just incompatibility or real error in swift code - swift

hello i am working with swift 6.2 ( the performance of my pc doesn't support ++)
i have copied from open classroom this program in my file but there are many errors
i just want to know if it is just problem of swift compatibility or there are really errors in the code
//****************
import UIKit
class QuestionManager {
private let url = URL(string: "https://opentdb.com/api.php?amount=10&type=boolean")!
// exemple of message error: use of unresolved identifier 'URL'
static let shared = QuestionManager()
private init() {}
// FIX IT : replace static with class ...
// AND LOT OF MESSAGE ERROR LIKE THIS...
func get(completionHandler: #escaping ([Question]) -> ()) {
let task = URLSession.shared.dataTask(with: self.url) { (data, response, error) in
guard error == nil else {
completionHandler([Question]())
return
}
DispatchQueue.main.async {
completionHandler(self.parse(data: data))
}
}
task.resume()
}
private func parse(data: Data?) -> [Question] {
guard let data = data,
let serializedJson = try? JSONSerialization.jsonObject(with: data, options: []),
let parsedJson = serializedJson as? [String: Any],
let results = parsedJson["results"] as? [[String: Any]] else {
return [Question]()
}
return getQuestionsFrom(parsedDatas: results)
}
private func getQuestionsFrom(parsedDatas: [[String: Any]]) -> [Question]{
var retrievedQuestions = [Question]()
for parsedData in parsedDatas {
retrievedQuestions.append(getQuestionFrom(parsedData: parsedData))
}
return retrievedQuestions
}
private func getQuestionFrom(parsedData: [String: Any]) -> Question {
if let title = parsedData["question"] as? String,
let answer = parsedData["correct_answer"] as? String {
return Question(title: String(htmlEncodedString: title)!, isCorrect: (answer == "True"))
}
return Question()
}
}
extension String {
init?(htmlEncodedString: String) {
guard let data = htmlEncodedString.data(using: .utf8) else {
return nil
}
let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [
NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html,
NSAttributedString.DocumentReadingOptionKey.characterEncoding: String.Encoding.utf8.rawValue
]
guard let attributedString = try? NSAttributedString(data: data, options: options, documentAttributes: nil) else {
return nil
}
self.init(attributedString.string)
}
}

Related

Cannot convert value of type '(key: String, value: Any)' to expected argument type '[String : Any]

I'm trying to get JSON but it shows an occurred issue
Line starting with if let deliveryObject
How to get rid of the problem?
code:
struct Tracking {
let receiver: String
let placeOfMail: String
let indexOfMail: Double
init(json:[String:Any]) throws {
guard let receiver = json["name"] as? String else {
throw SerializationError.missing("Receiver data has been missed")
}
guard let placeOfMail = json ["address"] as? String else {
throw SerializationError.missing("Place of delivery has been missed")
}
guard let indexOfMail = json ["postindex"] as? Double else {
throw SerializationError.missing("Index of postmail has been missed")
}
self.receiver = receiver
self.placeOfMail = placeOfMail
self.indexOfMail = indexOfMail
}
static let basePath = "https://track.kazpost.kz/api/v2/"
static func deliveryData (withTrackid trackid:String, completion: #escaping ([Tracking]) -> ()){
let url = basePath + trackid
let request = URLRequest(url: URL(string: url)!)
let task = URLSession.shared.dataTask(with: request) { (data: Data?, response : URLResponse?, error: Error?) in
var deliveryArray: [Tracking] = []
if let data = data {
do {
if let json = try JSONSerialization.jsonObject(with: data, options:[]) as? [String:Any] {
if let deliveryInformation = json ["delivery"] as? [String:Any] {
if let deliveryPlace = deliveryInformation ["address"] as? [String:Any] {
for dataPoint in deliveryPlace {
if let dataPointValue = dataPoint.value as? [String: AnyObject],
let deliveryObject = try Tracking(json: dataPointValue) {
deliveryArray.append(deliveryObject)
}
}
}
}
}
}catch {
print(error.localizedDescription)
}
completion(deliveryArray)
}
}
task.resume()
}
}

Parsing get_video_info (YouTube information data) in swift

To get a direct link to YouTube video I made request to get the get_video_info file, in this file that link, but I have to parse it, I find the solution to parse it by PHP but I want to parse it directly from my App
I get the data from my code like this:
let youtubeContentID = "sZz7tiToK1U"
if let infoURL = URL(string:"https://www.youtube.com/get_video_info?video_id=\(youtubeContentID)") {
let request = URLRequest(url: infoURL)
let session = URLSession(configuration: .default)
let task = session.dataTask(with: request, completionHandler: { (data, response, error) -> Void in
if let error = error {
print(error)
} else if let data = data, let result = NSString(data: data, encoding: String.Encoding.utf8.rawValue) {
print(result)
}
})
task.resume()
}
}
I got data with many Ascii symbols like this:
c=WEB&vss_host=s.youtube.com&innertube_api_version=v1&xhr_apiary_host=youtubei.youtube.com&apiary_host_firstparty=&status=ok&t=1&enabled_engage_types=3%2C6%2C4%2C5%2C17%2C1&ssl=1&adaptive_fmts=type%3Dvideo%252Fwebm%253B%2Bcodecs%253D%2522vp9%2522%26eotf%3Dbt709%26projection_type%3D1%26lmt%3D1550114115045036%26bitrate%3D16962786%26size%3D3840x2160%26index%3D221-1771%26quality_label%3D2160p%26xtags%3D%26url%3Dhttps%253A%252F%252Fr2---sn-nuj-wxqek.googlevideo.com%252Fvideoplayback%253Fexpire%253D1551500605%2526usequic%253Dno%2526gir%253Dyes%2526mime%253Dvideo%25252Fwebm%2526requiressl%253Dyes%2526keepalive%253Dyes%2526fvip%253D2%2526clen%253D547103152%2526source%253Dyoutube%2526aitags%253D133%25252C134%25252C135%25252C136%25252C137%25252C160%25252C242%25252C243%25252C244%25252C247%25252C248%25252C271%25252C278%25252C313%25252C394%25252C395%25252C396%25252C397%2526signature%253D9C28A5C103FA95701CD3655795DDB7F2C0954828.55534AC9C7BEE5D644C3A34C2CD4A4EEC9E2FD38%2526lmt%253D1550114115045036%2526ip%253D129.208.30.232%2526key%253Dyt6%2526c%253DWEB%2526ei%253D3bB5XKeFFNWd1wbBpqjgAg%2526txp%253D5531432%2526id%253Do-AIOVogCB8KFe32o_VgxSx-LqaEjNBZxiZ1jl81VTXZhF%2526sparams%253Daitags%25252Cclen%25252Cdur%25252Cei%25252Cgir%25252Cid%25252Cinitcwndbps%25252Cip%25252Cipbits%25252Citag%25252Ckeepalive%25252Clmt%25252Cmime%25252Cmm%25252Cmn%25252Cms%25252Cmv%25252Cpl%25252Crequiressl%25252Csource%25252Cusequic%25252Cexpire%2526initcwndbps%253D296250%2526itag%253D313%2526ms%253Dau%25252Crdu%2526mt%253D1551478917%2526mv%253Dm%2526dur%253D428.933%2526pl%253D19%2526ipbits%253D0%2526mm%253D31%25252C29%2526mn%253Dsn-nuj-wxqek%25252Csn-hgn7yn7l%26clen%3D547103152%26init%3D0-220%26itag%3D313%26primaries%3Dbt709%26fps%3D30%2Ctype%3Dvideo%252Fwebm%253B%2Bcodecs%253D%2522vp9%2522%26eotf%3Dbt709%26projection_type%3D1%26lmt%3D1550113771564979%26bitrate%3D6318874%26size%3D2560x1440%26index%3D220-1763%26quality_label%3D1440p%26xtags%3D%26url%3Dhttps%253A%252F%252Fr2---sn-nuj-wxqek.googlevideo.com%252Fvideoplayback%253Fexpire%253D1551500605%2526usequic%253Dno%2526gir%253Dyes%2526mime%253Dvideo%25252Fwebm%2526requiressl%253Dyes%2526keepalive%253Dyes%2526fvip%253D2%2526clen%253D155020170%2526source%253Dyoutube%2526aitags%253D133%25252C134%25252C135%25252C136%25252C137%25252C160%25252C242%25252C243%25252C244%25252C247%25252C248%25252C271%25252C278%25252C313%25252C394%25252C395%25252C396%25252C397%2526signature%253D4D7BF761EE4A6DFD048DE3D48550FCE80E61B7D0.D625BCC9645471ABA478F79C197B2208F354E15F%2526lmt%253D1550113771564979%2526ip%253D129.208.30.232%2526key%253Dyt6%2526c%253DWEB%2526ei%253D3bB5XKeFFNWd1wbBpqjgAg%2526txp%253D5531432%2526id%253Do-AIOVogCB8KFe32o_VgxSx- .... ext
I find code can deal with this YouTube request, it created on 2015 so it can't run on the new Swift, so I edited it to work on Swift 4, just copy this code in side a new Swift file then call function h264videosWithYoutubeID(youtubeID: your TouTube ID) and you will get the correct url:
import UIKit
public extension NSURL {
func dictionaryForQueryString() -> [String: AnyObject]? {
if let query = self.query {
return query.dictionaryFromQueryStringComponents()
}
let result = absoluteString?.components(separatedBy: "?")
if result!.count > 1 {
return result!.last?.dictionaryFromQueryStringComponents()
}
return nil
}
}
public extension NSString {
func stringByDecodingURLFormat() -> String {
let result = self.replacingOccurrences(of: "+", with: " ")
return result.removingPercentEncoding!
}
func dictionaryFromQueryStringComponents() -> [String: AnyObject] {
var parameters = [String: AnyObject]()
for keyValue in components(separatedBy: "&") {
let keyValueArray = keyValue.components(separatedBy: "=")
if keyValueArray.count < 2 {
continue
}
let key = keyValueArray[0].stringByDecodingURLFormat()
let value = keyValueArray[1].stringByDecodingURLFormat()
parameters[key] = value as AnyObject
}
return parameters
}
}
public class YoutubeUrlReciver: NSObject {
static let infoURL = "http://www.youtube.com/get_video_info?video_id="
static var userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.79 Safari/537.4"
public static func youtubeIDFromYoutubeURL(youtubeURL: NSURL) -> String? {
if let
youtubeHost = youtubeURL.host,
let youtubePathComponents = youtubeURL.pathComponents {
let youtubeAbsoluteString = youtubeURL.absoluteString
if youtubeHost == "youtu.be" as String? {
return youtubePathComponents[1]
} else if youtubeAbsoluteString?.range(of: "www.youtube.com/embed") != nil {
return youtubePathComponents[2]
} else if youtubeHost == "youtube.googleapis.com" ||
youtubeURL.pathComponents!.first == "www.youtube.com" as String? {
return youtubePathComponents[2]
} else if let
queryString = youtubeURL.dictionaryForQueryString(),
let searchParam = queryString["v"] as? String {
return searchParam
}
}
return nil
}
public static func h264videosWithYoutubeID(youtubeID: String) -> [String: AnyObject]? {
let urlString = String(format: "%#%#", infoURL, youtubeID) as String
let url = NSURL(string: urlString)!
let request = NSMutableURLRequest(url: url as URL)
request.timeoutInterval = 5.0
request.setValue(userAgent, forHTTPHeaderField: "User-Agent")
request.httpMethod = "GET"
var responseString = NSString()
let session = URLSession(configuration: URLSessionConfiguration.default)
let group = DispatchGroup()
group.enter()
session.dataTask(with: request as URLRequest, completionHandler: { (data, response, _) -> Void in
if let data = data as NSData? {
responseString = NSString(data: data as Data, encoding: String.Encoding.utf8.rawValue)!
}
group.leave()
}).resume()
group.wait()
let parts = responseString.dictionaryFromQueryStringComponents()
if parts.count > 0 {
var videoTitle: String = ""
var streamImage: String = ""
if let title = parts["title"] as? String {
videoTitle = title
}
if let image = parts["iurl"] as? String {
streamImage = image
}
if let fmtStreamMap = parts["url_encoded_fmt_stream_map"] as? String {
// Live Stream
if let _: AnyObject = parts["live_playback"]{
if let hlsvp = parts["hlsvp"] as? String {
return [
"url": "\(hlsvp)" as AnyObject,
"title": "\(videoTitle)" as AnyObject,
"image": "\(streamImage)" as AnyObject,
"isStream": true as AnyObject
]
}
} else {
let fmtStreamMapArray = fmtStreamMap.components(separatedBy: ",")
for videoEncodedString in fmtStreamMapArray {
var videoComponents = videoEncodedString.dictionaryFromQueryStringComponents()
videoComponents["title"] = videoTitle as AnyObject
videoComponents["isStream"] = false as AnyObject
return videoComponents as [String: AnyObject]
}
}
}
}
return nil
}
public static func h264videosWithYoutubeURL(youtubeURL: NSURL,completion: ((
_ videoInfo: [String: AnyObject]?, _ error: NSError?) -> Void)?) {
DispatchQueue.global().async {
if let youtubeID = self.youtubeIDFromYoutubeURL(youtubeURL: youtubeURL), let videoInformation = self.h264videosWithYoutubeID(youtubeID: youtubeID) {
DispatchQueue.main.async {
completion?(videoInformation, nil)
}
}else{
DispatchQueue.main.async {
completion?(nil, NSError(domain: "com.player.youtube.backgroundqueue", code: 1001, userInfo: ["error": "Invalid YouTube URL"]))
}
}
}
}
}

Converting Swift ios Networking to use Alamofire

I got a source code from a github page written in swift and implementing GoogleMaps. I now want to refactor the codes to use Alamofire and SwiftyJSON so that I can improve the code but I got confused because through my learning of swift I used Alamofire and swiftyJSON for every networking process so I am confused currently. the code below
typealias PlacesCompletion = ([GooglePlace]) -> Void
typealias PhotoCompletion = (UIImage?) -> Void
class GoogleDataProvider {
private var photoCache: [String: UIImage] = [:]
private var placesTask: URLSessionDataTask?
private var session: URLSession {
return URLSession.shared
}
let appDelegate = UIApplication.shared.delegate as! AppDelegate
func fetchPlacesNearCoordinate(_ coordinate: CLLocationCoordinate2D, radius: Double, types:[String], completion: #escaping PlacesCompletion) -> Void {
var urlString = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=\(coordinate.latitude),\(coordinate.longitude)&radius=\(radius)&rankby=prominence&sensor=true&key=\(appDelegate.APP_ID)"
let typesString = types.count > 0 ? types.joined(separator: "|") : "food"
urlString += "&types=\(typesString)"
urlString = urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) ?? urlString
guard let url = URL(string: urlString) else {
completion([])
return
}
if let task = placesTask, task.taskIdentifier > 0 && task.state == .running {
task.cancel()
}
DispatchQueue.main.async {
UIApplication.shared.isNetworkActivityIndicatorVisible = true
}
placesTask = session.dataTask(with: url) { data, response, error in
var placesArray: [GooglePlace] = []
defer {
DispatchQueue.main.async {
UIApplication.shared.isNetworkActivityIndicatorVisible = false
completion(placesArray)
}
}
guard let data = data,
let json = try? JSON(data: data, options: .mutableContainers),
let results = json["results"].arrayObject as? [[String: Any]] else {
return
}
results.forEach {
let place = GooglePlace(dictionary: $0, acceptedTypes: types)
placesArray.append(place)
if let reference = place.photoReference {
self.fetchPhotoFromReference(reference) { image in
place.photo = image
}
}
}
}
placesTask?.resume()
}
func fetchPhotoFromReference(_ reference: String, completion: #escaping PhotoCompletion) -> Void {
if let photo = photoCache[reference] {
completion(photo)
} else {
let urlString = "https://maps.googleapis.com/maps/api/place/photo?maxwidth=200&photoreference=\(reference)&key=\(appDelegate.APP_ID)"
guard let url = URL(string: urlString) else {
completion(nil)
return
}
DispatchQueue.main.async {
UIApplication.shared.isNetworkActivityIndicatorVisible = true
}
session.downloadTask(with: url) { url, response, error in
var downloadedPhoto: UIImage? = nil
defer {
DispatchQueue.main.async {
UIApplication.shared.isNetworkActivityIndicatorVisible = false
completion(downloadedPhoto)
}
}
guard let url = url else {
return
}
guard let imageData = try? Data(contentsOf: url) else {
return
}
downloadedPhoto = UIImage(data: imageData)
self.photoCache[reference] = downloadedPhoto
}
.resume()
}
}
}
any help to refactor the codes to use Alamofire and swiftyJSON would be appreciated.
Both Alamofire and SwiftyJSON have pretty decent instructions, and there are plenty of examples online to look for. However, this would be a decent starting point - you need to replace your session.dataTask and session.downloadTask with Alamofire methods. For example, instead of:
session.downloadTask(with: url) { url, response, error in
var downloadedPhoto: UIImage? = nil
defer {
DispatchQueue.main.async {
UIApplication.shared.isNetworkActivityIndicatorVisible = false
completion(downloadedPhoto)
}
}
guard let url = url else {
return
}
guard let imageData = try? Data(contentsOf: url) else {
return
}
downloadedPhoto = UIImage(data: imageData)
self.photoCache[reference] = downloadedPhoto
}
.resume()
use this skeleton and implement your models and logic:
Alamofire
.request(url)
.responseJSON { dataResponse in
switch dataResponse.result {
case .success:
guard let json = JSON(dataResponse.data) else {
return
}
// Continue parsing
case .failure(let error):
// Handle error
print("\(error)")
}
}

Why isn't my Weather Underground data not printing in Swift 3?

I'm having an issue printing data from Weather Underground. My code works with other data sources, just not Weather Underground. I have even tried replacing the URL with actual data (i.e. https://api.wunderground.com/api/APIKEY/forecast/geolookup/forecast/q/94129.json"), but it doesn't print.
Any suggestions on what it could be?
import Foundation
import UIKit
class APIManager {
func weatherJSON(zip: String, completion: #escaping ([Weather]) -> Void) {
let baseUrlString = "https://api.wunderground.com/api/APIKEY/forecast/geolookup/forecast/q/\(zip).json"
guard let url = URL(string: baseUrlString) else { return }
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
guard error == nil, let data = data else { return }
do {
guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [[String: Any]] else { return }
// MARK: Print JSON
print(json)
var weatherList = [Weather]()
for item in json {
if let weather = Weather.create(from: item) {
weatherList.append(weather)
}
}
completion(weatherList)
} catch {
print("Uh oh. You have an error with \(zip)!")
}
}
task.resume()
}
}
EDIT: SOLVED
I have used the code posted below and am now seeing errors.
I'd suggest changing this to report errors:
enum WeatherError Error {
case badURL
case invalidJSON
}
func weatherJSON(zip: String, completion: #escaping ([Weather]?, Error?) -> Void) {
let baseUrlString = "https://api.wunderground.com/api/APIKEY/forecast/geolookup/forecast/q/\(zip).json"
guard let url = URL(string: baseUrlString) else {
completion(nil, WeatherError.badURL)
return
}
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
guard error == nil, let data = data else {
completion(nil, error)
return
}
do {
guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [[String: Any]] else {
completion(nil, WeatherError.invalidJSON)
return
}
// MARK: Print JSON
print(json)
var weatherList = [Weather]()
for item in json {
if let weather = Weather.create(from: item) {
weatherList.append(weather)
}
}
completion(weatherList, nil)
} catch let parseError {
print("Uh oh. You have an error with \(zip)!")
if let responseString = String(data: data, encoding: .utf8) {
print("responseString = \(responseString)")
}
completion(nil, parseError)
}
}
task.resume()
}
Then, when you call it, you can see what the error was
weatherJSON(zip: something) { weatherReports, error in
guard let weatherReports = weatherReports, error == nil else {
print(error)
return
}
// use weatherReports here
}
This won't solve your problem, but it will help you diagnose what the issue is.

Nested dataTaskWithRequest in Swift tvOS

I'm a C# developer convert to Swift tvOs and just starting to learn. I've made some progress, but not sure how to handle nested calls to json. The sources are from different providers so I can't just combine the query.
How do I wait for the inner request to complete so the TVSeries has the poster_path? Is there a better way to add the show to the collection and then process the poster path loading in another thread so it doesn't delay the UI Experience?
func downloadTVData() {
let url_BTV = NSURL(string: BTV_URL_BASE)!
let request_BTV = NSURLRequest(URL: url_BTV)
let session_BTV = NSURLSession.sharedSession()
//get series data
let task_BTR = session_BTV.dataTaskWithRequest(request_BTV) { (data_BTV, response_BTV, error_BTV) -> Void in
if error_BTV != nil {
print (error_BTV?.description)
} else {
do {
let dict_BTV = try NSJSONSerialization.JSONObjectWithData(data_BTV!, options: .AllowFragments) as? Dictionary<String, AnyObject>
if let results_BTV = dict_BTV!["results"] as? [Dictionary<String, AnyObject>]{
for obj_BTV in results_BTV {
let tvshow = TVSeries(tvDict: obj_BTV)
//for each tv series try to load a poster_path from secondary provider
if let str = obj_BTV["title"] as? String!{
let escapedString = str?.stringByAddingPercentEncodingWithAllowedCharacters(.URLQueryAllowedCharacterSet())!
if let url = NSURL(string: self.SEARCH_URL_BASE + escapedString!) {
let request = NSURLRequest(URL: url)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) { (data, response, error) -> Void in
if error != nil {
print (error?.description)
} else {
do {
let dict = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments) as? Dictionary<String, AnyObject>
if let results = dict!["results"] as? [Dictionary<String, AnyObject>] {
//iterate through the poster array
for obj in results {
if let path = obj["poster_path"] as? String {
tvshow.posterPath = path
break
}
}
}
} catch let error as NSError {
print(error.description)
}
}
}
task.resume()
}
}
self.tvSeries.append(tvshow)
}
dispatch_async(dispatch_get_main_queue()){
self.collectionView.reloadData()
}
}
} catch let error as NSError {
print(error.description)
}
}
}
task_BTR.resume()
}
Thanks for your help!
I would recommend breaking things apart into multiple methods, with callbacks to sequence the operations, and utilizing Swift's built-in throws error handling mechanism. Here's an example, not perfect, but might help as a starting point:
class TVSeries
{
let title: String
var posterPath: String?
enum Error: ErrorType {
case MalformedJSON
}
init(tvDict: [String: AnyObject]) throws
{
guard let title = tvDict["title"] as? String else {
throw Error.MalformedJSON
}
self.title = title
}
static func loadAllSeries(completionHandler: [TVSeries]? -> Void)
{
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: BTV_URL_BASE)!) { data, response, error in
guard let data = data else {
print(error)
completionHandler(nil)
return
}
do {
completionHandler(try fromJSONData(data))
}
catch let error {
print(error)
}
}.resume()
}
static func fromJSONData(jsonData: NSData) throws -> [TVSeries]
{
guard let dict = try NSJSONSerialization.JSONObjectWithData(jsonData, options: .AllowFragments) as? [String: AnyObject] else {
throw Error.MalformedJSON
}
guard let results = dict["results"] as? [[String: AnyObject]] else {
throw Error.MalformedJSON
}
return try results.map {
return try TVSeries(tvDict: $0)
}
}
func loadPosterPath(completionHandler: () -> Void)
{
guard let searchPath = title.stringByAddingPercentEncodingWithAllowedCharacters(.URLQueryAllowedCharacterSet()) else {
completionHandler()
return
}
let url = NSURL(string: SEARCH_URL_BASE)!.URLByAppendingPathComponent(searchPath)
NSURLSession.sharedSession().dataTaskWithURL(url) { [weak self] data, response, error in
defer { completionHandler() }
guard let strongSelf = self else { return }
guard let data = data else {
print(error)
return
}
do {
strongSelf.posterPath = try TVSeries.posterPathFromJSONData(data)
}
catch let error {
print(error)
}
}.resume()
}
static func posterPathFromJSONData(jsonData: NSData) throws -> String?
{
guard let dict = try NSJSONSerialization.JSONObjectWithData(jsonData, options: .AllowFragments) as? [String: AnyObject] else {
throw Error.MalformedJSON
}
guard let results = dict["results"] as? [[String: AnyObject]] else {
throw Error.MalformedJSON
}
for result in results {
if let path = result["poster_path"] as? String {
return path
}
}
return nil
}
}
It might also be worth your time to look into something like RxSwift or Alamofire, which help you with these kinds of data-conversion / sequencing operations.