I'm not sure where the nil value is here. I also tried explicitly allocating the error var and still had the issue. The code is taken almost directly from Twitter documentation.
let statusesShowEndpoint = "https://api.twitter.com/1.1/users/profile_banner.json?"
let params = ["screen_name":"twitter"]
var clientError :NSError?
let request = Twitter.sharedInstance().APIClient.URLRequestWithMethod(
"GET", URL: statusesShowEndpoint, parameters: params,
error: &clientError)
if request != nil {
Twitter.sharedInstance().APIClient.sendTwitterRequest(request) {
(response, data, connectionError) -> Void in
if (connectionError == nil) {
var jsonError : NSError?
let json : AnyObject? =
NSJSONSerialization.JSONObjectWithData(data,
options: nil,
error: &jsonError)
}
else {
println("Error: \(connectionError)")
}
}
}
else {
println("Error: \(clientError)")
}
I get this error on the request:
fatal error: unexpectedly found nil while unwrapping an Optional value
I haven't spent much time with the twitter api, but the http endpoint you are trying to access requires that you have the qAuth authority have you done this? as the http link is coming back "bad authentication data" when i try to access it
Related
I'm trying to make some connections with an API and I need to return an error message if the username is unknown. Though, while I try to print my variable in my post request, I see the message but if I print my variable after my request but in my function, I have an error: fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb).
Here is a sample of my code. I use SwiftHTTP for my requests:
var errSign: String?
func signUp(email:String, pwd:String) {
let params: Dictionary<String,AnyObject> = ["password": pwd, "email": email]
task.POST(signUpUrl, parameters: params, completionHandler: {(response: HTTPResponse) -> Void in
if let err = response.error {
println("error: \(err.localizedDescription)")
}
if let json = response.responseObject as? Dictionary<String, AnyObject> {
var data = JSON(json)
if data["error"] != false {
self.errSign = String(stringInterpolationSegment: data["error"])
println(self.errSign!)
}
}
})
// ERROR println(self.errSign!)
}
You've declared errSign as optional, so you should probably check to see that there's something in there before attempting to print anything out:
self.errSign = String(stringInterpolationSegment: data["error"])
if let actualErrSign = self.errSign
{
println(\(actualErrSign))
} else {
println("no (obvious) error was returned")
}
the ! keyword is to unwrap an optional variable to access to its value. This is only possible when your optional variable contains a value. In case you try to unwrap an optional variable that does not hold actually a value, your application will crash and it receive that fatal error.
The solution is in the answer of #Michael Dautermann
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let url = NSURL(string: "https://api.forecast.io/forecast/MYKEYHERE/")
let session = NSURLSession.sharedSession()
let task: NSURLSessionDownloadTask = session.downloadTaskWithURL(url!, completionHandler: { (location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in
if error == nil {
let data = NSData(contentsOfURL: location)
let json: NSDictionary = NSJSONSerialization.JSONObjectWithData(data!, options: nil, error: nil) as! NSDictionary!
println(json)
}
})
task.resume()
}
This is code for a download task to a weather API. Just wondering why I am getting the error:
Thread 6: EXC_BAD_INSTRUCTION(code=EXC_1386_INVOP, subcode=0x0).
Thanks a lot.
You're getting this error because the response is not JSON (or the JSON is not a dictionary). So, when parsing the JSON, use optional binding to gracefully handle nil or non-dictionary errors, perhaps examining the body of response if it fails, e.g.:
let task = session.downloadTaskWithURL(url!) { location, response, error in
if error == nil {
let data = NSData(contentsOfURL: location)
var error: NSError?
if let json = NSJSONSerialization.JSONObjectWithData(data!, options: nil, error: &error) as? NSDictionary {
println("json = \(json)")
} else {
println("error = \(error)")
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
println("not json; responseString = \(responseString)")
println(response)
}
}
}
task.resume()
Also, note, when using JSONObjectWithData, you not only want to gracefully check for an error, but you generally want to use the error parameter, too, as noted above.
BTW, make sure you include the latitude and longitude in the URL as described in the forecast.io API documentation, or else you'll get a non-JSON error response. Even if you fix the URL to avoid this error, you should still implement some graceful handling of errors, like above, or else your app might crash whenever there are any server issues.
I'm new to Swift been reading but have no clue what this means. On the line of code below, I have "Expected expression in list of expressions" after parameters[String]. AS well at the same point it is looking for "Expected ',' separator. I believe these are related.
AppDelegate.submitLacunaRequest(module: "empire", method: "login", parameters[String]:["myuserid", "mypassword", "mykey"]) {
responseObject, error in
// some network error or programming error
if error != nil {
println("error = \(error)")
println("responseObject = \(responseObject)")
return
}
// network request ok, now see if login was successful
if let responseDictionary = responseObject as? NSDictionary {
if let errorDictionary = responseDictionary["error"] as? NSDictionary {
println("error logging in (bad userid/password?): \(errorDictionary)")
} else if let resultDictionary = responseDictionary["result"] as? NSDictionary {
println("successfully logged in, refer to resultDictionary for details: \(resultDictionary)")
} else {
println("we should never get here")
println("responseObject = \(responseObject)")
}
}
}
Here is the related code from AppDelegate
public func submitLacunaRequest (#module: String, method: String, parameters: AnyObject, completion: (responseObject: AnyObject!, error: NSError!) -> (Void)) -> NSURLSessionTask? {
let session = NSURLSession.sharedSession()
let url = NSURL(string: "https://us1.lacunaexpanse.com")?.URLByAppendingPathComponent(module)
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
request.setValue("application/json-rpc", forHTTPHeaderField: "Content-Type")
let requestDictionary = [
"jsonrpc" : "2.0",
"id" : 1,
"method" : "login",
"params" : ["myuserid", "mypassword", "mykey"]
]
var error: NSError?
let requestBody = NSJSONSerialization.dataWithJSONObject(requestDictionary, options: nil, error: &error)
if requestBody == nil {
completion(responseObject: nil, error: error)
return nil
}
request.HTTPBody = requestBody
let task = session.dataTaskWithRequest(request) {
data, response, error in
// handle fundamental network errors (e.g. no connectivity)
if error != nil {
completion(responseObject: data, error: error)
return
}
// parse the JSON response
var parseError: NSError?
let responseObject = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &parseError) as? NSDictionary
if responseObject == nil {
// because it's not JSON, let's convert it to a string when we report completion (likely HTML or text)
let responseString = NSString(data: data, encoding: NSUTF8StringEncoding) as String
completion(responseObject: responseString, error: parseError)
return
}
completion(responseObject: responseObject, error: nil)
}
task.resume()
return task
}
You are using external parameter name for a parameter when calling the function, but the external parameter is not defined in your function declaration. Simply use it this way.
submitLacunaRequest(module: "empire", "login", ["myuserid", "mypassword", "mykey"]) {
You're calling the function incorrectly. You don't need the [String] in the parameters param...
AppDelegate.submitLacunaRequest(module: "empire", method: "login", parameters: ["myuserid", "mypassword", "mykey"]) {
...
}
I called my function parameter protocol.
If I was to try using this property as usual, I would notice it to be written in pink being a keyword and I would rename it.
Instead, I used this property in a string like this and I didn't get any clues from the compiler:
func configure(_ protocol: Protocol, host:String, port:String) {
urlString = "\(protocol)://\(host):\(port)"
}
I spend good 5 minutes confused out of my mind by this error, but then I figured it out. The problem was in the name of the parameter.
I didn't want to rename the parameter, so I ended up writing it like this:
urlString = "\(`protocol`)://\(host):\(port)"
When I am trying to server request in my swift code block, some errors occured after server response JSON like the code below;
Alamofire.request(.POST, Utility.WebServiceAddress+"/ApproveOrder", parameters: parameters)
.responseJSON
{(request, response, JSON, error) in
if let jsonResult: NSDictionary = JSON as? NSDictionary
{
if let wsResult = jsonResult[WSConstants.WSRESULT] as? NSDictionary
{
let resultCode = wsResult.valueForKey(WSConstants.RESULT_CODE) as Int
if(resultCode == Utility.WS_RESULT_SUCCESS)
{
self.PrepareMainItemsInBagToSetUpLocalNotifications()
Utility.ActivityIndicatorStopAnimating(self.activityIndicator, indicatorLabel: self.lblIndicatorMessage, viewController: self)
Utility.ReleaseBagAndPopToInitialViewController(self)
}
else
{
PromptDialogs.getPromptDialogWebServiceError(self.activityIndicator, lblIndicatorMessage: self.lblIndicatorMessage, viewController: self, message: "Sipariş tablebiniz gönderilirken hata oluştu. Lütfen tekrar deneyiniz!")
}
}
}
else
{
PromptDialogs.getPromptDialogWebServiceError(self.activityIndicator, lblIndicatorMessage: self.lblIndicatorMessage, viewController: self, message: "Sunucudan yanıt alınamadı. Lütfen internet bağlantınızı kontrol edip yeniden deneyiniz!")
}
} // gives 'fatal error: unexpectedly found nil while unwrapping an Optional value' at this line, as refering Alamofire code below ->
public func responseJSON(options: NSJSONReadingOptions = .AllowFragments, completionHandler: (NSURLRequest, NSHTTPURLResponse?, AnyObject?, NSError?) -> Void) -> Self {
return response(serializer: Request.JSONResponseSerializer(options: options), completionHandler: { (request, response, JSON, error) in
completionHandler(request, response, JSON, error)
})
}
I used this request way for some other UIViewControllers. But I did not understand that why am I getting this error only here? If it is necessary for you, I can share the more detailed code block.
Could you help me ?
Best regards
I am using the following function to upload a image to a given url.
I built this function based on the answers given to these to questions:
NSURLConnection Using iOS Swift and How to send UIImage in JSON format, by filling a NSDictionary
func uploadFileToUrl(url:NSURL){
var request = NSMutableURLRequest(URL:url)
request.HTTPMethod = "POST"
request.HTTPBody = NSData.dataWithData(UIImagePNGRepresentation(image))
var response: AutoreleasingUnsafeMutablePointer<NSURLResponse?>=nil
var error: AutoreleasingUnsafeMutablePointer<NSErrorPointer?> = nil
var dataVal: NSData = NSURLConnection.sendSynchronousRequest(request, returningResponse: response, error:nil)!
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataVal, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
if (error != nil) {
println("Request didn't go through")
}
println("Synchronous\(jsonResult)")
}
However when I run my app I always get an "fatal error: unexpectedly found nil while unwrapping an Optional value" on the following line:
var dataVal: NSData = NSURLConnection.sendSynchronousRequest(request, returningResponse: response, error:nil)!
What am I doing wrong? Thanks
First off, you aren't passing your error pointer when you make the request, so you will never know if that failed.
Secondly, as already mentioned, you are force unwrapping your dataVal variable without checking the value. So if your request did error and you don't handle it, you end up with the error you showed.
See the code below for a working example.
func uploadFileToUrl(url:NSURL){
var request = NSMutableURLRequest(URL:url)
request.HTTPMethod = "POST"
request.HTTPBody = NSData.dataWithData(UIImagePNGRepresentation(image))
var response: AutoreleasingUnsafeMutablePointer<NSURLResponse?>=nil
var HTTPError: NSError? = nil
var JSONError: NSError? = nil
var dataVal: NSData? = NSURLConnection.sendSynchronousRequest(request, returningResponse: response, error: &HTTPError)
if ((dataVal != nil) && (HTTPError == nil)) {
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataVal!, options: NSJSONReadingOptions.MutableContainers, error: &JSONError) as NSDictionary
if (JSONError != nil) {
println("Bad JSON")
} else {
println("Synchronous\(jsonResult)")
}
} else if (HTTPError != nil) {
println("Request failed")
} else {
println("No Data returned")
}
}
If there's a problem, NSURLConnection.sendSynchronousRequest returns nil. You do have a problem, and it is returning nil. You are then force-unwrapping that nil with your exclamation mark. Hence the crash.
Instead, type dataVal as an NSData? which is what you are getting back (and remove the exclamation mark). Now you won't crash. Now in the next line look to see whether dataVal is nil. If it is, you know you've got a problem, and now you can read the error to see what the problem was.
If it isn't, now you can unwrap it and hand it off to NSJSONSerialization for interpretation.