Swift Alamofire Unexpectedly found nil - Facebook API - facebook

I'm running the same exact function for Instagram and Youtube API with Alamofire and SwiftyJSON; however, with Facebook's API I get fatal error: unexpectedly found nil while unwrapping an Optional value.
var posts : [JSON] = []
func loadFBFeed() {
let url = "https://graph.facebook.com/mpstnews/posts/?access_token=\(apiKey)&date_format=U&fields=comments.limit(0).summary(1),likes.limit(0).summary(1),from,picture,message,story,name,link,created_time,full_picture&limit=5"
Alamofire.request(.GET, url).responseJSON { (request, response, json) -> Void in
switch json {
case .Success(let data):
let jsonObj = JSON(data)
if let postInfo = jsonObj["data"].arrayValue as [JSON]? {
self.posts = postInfo
self.tableView.reloadData()
}
case .Failure(_, let error):
print("Request failed with error: \(error)")
}
}
}

URL was using characters that Alamofire does not like, had to add a line to resolve...
var urlString = "https://graph.facebook.com/mpstnews/posts/?access_token=\(apiKey)&date_format=U&fields=comments.limit(0).summary(1),likes.limit(0).summary(1),from,picture,message,story,name,link,created_time,full_picture&limit=5"
urlString = urlString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!

This generally happens when your URL is not valid. Most likely one of the values you are inserting into the URL is bad causing the URLStringConvertible logic to crash.

Related

cannot read data from Json hosted on GitHub

when try to read data from a json on my GitHub space, I get an error
nw_protocol_get_quic_image_block_invoke dlopen libquic failed
Invalid response from the server. Please try again.
am I using wrong url or there is an issue in the way I'm parsing data?
my repo url
https://github.com/stark226/stark226.github.io.git
where there is a simple json file at this url
https://github.com/stark226/stark226.github.io/blob/3b2bebb4a3d85524732c7e7ec302b24f8d3e66ae/testjson.json
in my viewDidload
getDataFromJsonOnGithub(completed: { [weak self] result in
guard let self = self else {return}
switch result {
case .success(let expected):
print(expected)
case .failure(let error):
print(error.rawValue)
}
})
my struct
struct RemoteData: Codable, Hashable {
var tokenDuration: Int
}
my func
func getDataFromJsonOnGithub(completed: #escaping (Result<RemoteData, ListOfErrors>) -> Void) {
let endpoint = "https://github.com/stark226/stark226.github.io/stark226/testjson.json"
guard let url = URL(string: endpoint) else {
completed(.failure(.invalidUsername))
return
}
let task = URLSession.shared.dataTask(with: url) { data, response, error in
if let _ = error {
completed(.failure(.unableToComplete))
return
}
guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
completed(.failure(.invalidResponse))
return
}
guard let data = data else {
completed(.failure(.invalidData))
return
}
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let expectedRrsult = try decoder.decode(RemoteData.self, from: data)
completed(.success(expectedRrsult))
} catch {
completed(.failure(.invalidData))
}
}
task.resume()
}
enum ListOfErrors: String, Error {
case invalidUsername = "This username created an invalid request. Please try again."
case unableToComplete = "Unable to complete your request. Please check your internet connection"
case invalidResponse = "Invalid response from the server. Please try again."
case invalidData = "The data received from the server was invalid. Please try again."
case unableToFavorite = "There was an error favoriting this user. Please try again."
case alreadyInFavorites = "You've already favorited this user. You must REALLY like them!"
}
You have to access the raw file. The URL you are accessing renders an HTML page. Try the following url (click on "Raw" button in GitHub):
https://raw.githubusercontent.com/stark226/stark226.github.io/3b2bebb4a3d85524732c7e7ec302b24f8d3e66ae/testjson.json

Not able to iterate through SPTPlaylistList items

I am trying to access all the playlists of a Spotify user
let request2: URLRequest = try! SPTPlaylistList.createRequestForGettingPlaylists(forUser: self.username, withAccessToken: accessToken)
print(request2)
SPTRequest.sharedHandler().perform(request2) { (error, response, data) in
if error == nil {
print(response)
let playlists = try! SPTPlaylistList(from: data, with: response)
}else{
print(error)
}
}
And I can see the playlists if I print 'playlists'
some([<SPTPartialPlaylist: 0x10aa854d0>: john mayer [2 tracks] (spotify:user:virajdeshpande88:playlist:3BLBrqb3CURu5KFPqdYqd1), <SPTPartialPlaylist: 0x10aa922a0>: beatles [2 tracks] (spotify:user:virajdeshpande88:playlist:2t6z8KEhZGzY7Tqvy8QoW4)])
But I can't access the playlists individually or iterate through playlists.items. If I do the following:
print (playlists.items[0])
I get 'Unexpectedly found nil while unwrapping an Optional value'.
Update: I tried using playlistsForUser:withAccessToken:callback: and I am able to access all the user's playlists now. But it only seems to work if the following block of code is inside the if {} block of the piece of code I posted above. If this block is placed just by itself, I get the nil value error again.
SPTPlaylistList.playlists(forUser: self.username, withAccessToken: accessToken, callback: {(error, playlist_list) in
if error == nil {
let list = playlist_list as! SPTPlaylistList
print(list.items[0])
print(list.items[1])
let playlist = list.items[0] as! SPTPartialPlaylist
print(playlist.name)
}else{
print("latest error")
}
})
You should avoid using force unwrap !.
if let request2: URLRequest = try? SPTPlaylistList.createRequestForGettingPlaylists(forUser: self.username, withAccessToken: accessToken){
print(request2)
SPTRequest.sharedHandler().perform(request2) { (error, response, data) in
if error == nil {
print(response)
if let playlists = try? SPTPlaylistList(from: data, with: response) {
playlists.forEach{ playlist in
print(playlist)
// do thing with your each playlist
}
}
}else{
print(error)
}
}
}

do - try - catch code doesnt try or catch. just do's

thanks for any help upfront.
url session works perfect with connection, it prints the error as nil. but without it it prints the .localizedDescription just fine and shows me the right error, but then continues to do the do{ try } and crashes with this error in the try line:
Thread 6: Fatal error: Unexpectedly found nil while unwrapping an
Optional value
now I am not even sure if this has anything to do with the errorhandling. thanks for any help with understanding whats going on or just solving the problem!
func getData(completion: (() -> ())?) {
let urlString = URL(string: "https://api.coinmarketcap.com/v1/ticker/")
URLSession.shared.dataTask(with: urlString!, completionHandler: { (data, response , error) in
print("before entering do-try-catch", error?.localizedDescription)
do {
//create Dictionary
print("downloading content")
self.coinData = try JSONSerialization.jsonObject(with: data!) as! [[String:Any]]
//set connection status
self.connection = true
//update tableView
DispatchQueue.main.async {
completion?()
}
} catch {
print("catch", error.localizedDescription)
//set connection status
self.connection = false
//update tableView
DispatchQueue.main.async {
completion?()
}
}
}).resume()
}
Thread 6: Fatal error: Unexpectedly found nil while unwrapping an Optional value is a common problem for beginners.
You try to work with data that is not there.
So for example in your code you force to execute try JSONSerialization.jsonObject(with: data!)
When data is nil the code will crash.
The same at the beginning URLSession.shared.dataTask(with: urlString!, completionHandler: { (data, response, error) {}
When urlString is not a valid URL the code will be crash. (In this case the url seems to be valid).
For more information have a look here:
https://stackoverflow.com/a/24034551/4420355
Try the following snipped it should work
if let data = data {
self.coinData = try JSONSerialization.jsonObject(with: data) as? [[String:Any]]
//... work with coinData
}
Reason why it is crashing is because data is Optional and it should be nil or has some value. On line
self.coinData = try JSONSerialization.jsonObject(with: data!) as! [[String:Any]]
Compiler thinks:
Let's take a look and unwrap this Optianal variable. But it's nil, there is "nothing"! So what should I unwrap? Let's crash and throw Fatal Error message.
How to easily avoid this with Optional binding:
if let data = data {
....do something with data
} else {
...print error message
}
For more information take look at this brilliant answer.
https://stackoverflow.com/a/32170457/3046686

How to load a url in swift [duplicate]

I am following this post for getting JSON data and for some reason this function:
func getJSON(urlToRequest: String) -> NSData {
return NSData(contentsOfURL: NSURL(string: urlToRequest)!)!
}
returns nil as I get the error:
fatal error: unexpectedly found nil while unwrapping an Optional value
I have broken up the function:
func getJSON(urlToRequest: String) -> NSData {
let url : NSURL! = NSURL(string: urlToRequest)
let data : NSData! = NSData(contentsOfURL: url)
return data
}
And according to my debugger:
Printing description of url:
www.reddit.com/r/earthporn/.json
Printing description of data:
(NSData!) data = nil
Pasting in the URL to Chrome doesn't give a blank page. It gives a massive glob of JSON, so I am confused why data is nil?
You forgot to add the url scheme. NSURL needs the full address. You should also use if let to safely unwrap your optional data:
func getJSON(urlToRequest: String) -> NSData? {
if let url = NSURL(string: urlToRequest) {
if let data = NSData(contentsOfURL: url) {
return data
}
}
return nil
}
if let myData = getJSON("http://www.reddit.com/r/earthporn/.json") {
println("there is data") // "there is data in myData"
}

Snap to Roads in Swift

I am trying to implement a method that uses Googles snap to roads API however I have been unable to achieve any results.
I was able to successfully implement the directions API in to my Swift project using
https://maps.googleapis.com/maps/api/directions/json?origin=xyz
let request = NSURLRequest(URL: NSURL(string:directionURL)!)
let session = NSURLSession.sharedSession()
session.dataTaskWithRequest(request,
completionHandler: {(data: NSData!, response: NSURLResponse!, error: NSError!) in
if error == nil {
let object = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) as! NSDictionary
println(object)
let routes = object["routes"] as! [NSDictionary]
for route in routes {
println(route["summary"])
}
dispatch_async(dispatch_get_main_queue()) {
//update your UI here
}
}
else {
println("Direction API error")
}
}).resume()
however if the GPS coordinates are even slightly different I get an entirely different result.
What I am trying to do is plot a users path the same each time even if the start/end coordinates a slightly different.
The error I am getting is
fatal error: unexpectedly found nil while unwrapping an Optional value
Any suggestions?
Thanks
EDIT:
I am trying this but this is what is causing the error
func directionAPITest() {
let directionURL = "https://roads.googleapis.com/v1/snapToRoads?path=-35.27801,149.12958|-35.28032,149.12907|-35.28099,149.12929|-35.28144,149.12984|-35.28194,149.13003|-35.28282,149.12956|-35.28302,149.12881|-35.28473,149.12836&interpolate=true&key=xyz"
let request = NSURLRequest(URL: NSURL(string:directionURL)!)
let session = NSURLSession.sharedSession()
}
I was able to resolve this after finding this post NSURL found nil while unwraping an Optional value
Basically had to escape the string.