Alamofire 'fatal error: unexpectedly found nil while unwrapping an Optional value' - ios

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

Related

Migration Alamofire 4 to 5 build issue

I am doing migration after 2 years a lots things have been changed, now flagging a lots of error while building. Most are related to Alamofire 5. Now there are many error keeps coming fixing one by one.
Error: // ERROR: Cannot specialize non-generic type
public static func ObjMappingSerializer<T: Mappable>(_ keyPath: String?) -> DataResponseSerializer<T> { 'DataResponseSerializer'
return DataResponseSerializer { request, response, data, error in
//LogResponse(response, data: data, error: error)
Logger._reqresLogger.logResponse(response, data: data, error: error)
guard error == nil else {
return .failure(parseErrorResponse(data: data, response: response, errorType: error!))
}
guard let _ = data else {
return .failure(errorForNilData())
}
let JSONToMap = deserializeJSON(request: request, response: response, data: data, error: error, keyPath: keyPath)
if let json = JSONToMap as? [String:Any], let parsedObject = Mapper<T>().map(JSON:json) {
return .success(parsedObject)
}
let errorCode = response?.statusCode ?? NSURLErrorCannotParseResponse
return .failure(APIError(code: errorCode, errorUserInfo: nil))
}
}
Fixed by autosuggestion however next error comes
Error: Trailing closure passed to parameter of type 'DataPreprocessor' that does not accept a closure
public static func ObjMappingSerializer(_ keyPath: String?) -> DataResponseSerializer {
return DataResponseSerializer { request, response, data, error in
//LogResponse(response, data: data, error: error)
Logger._reqresLogger.logResponse(response, data: data, error: error)
guard error == nil else {
return .failure(parseErrorResponse(data: data, response: response, errorType: error!))
}
guard let _ = data else {
return .failure(errorForNilData())
}
let JSONToMap = deserializeJSON(request: request, response: response, data: data, error: error, keyPath: keyPath)
if let json = JSONToMap as? [String:Any], let parsedObject = Mapper<T>().map(JSON:json) {
return .success(parsedObject)
}
let errorCode = response?.statusCode ?? NSURLErrorCannotParseResponse
return .failure(APIError(code: errorCode, errorUserInfo: nil))
}
}
Now in Alamofire many methods have been removed in Alamofire 5. How can I fix these errors?
You can no longer initialize a DataResponseSerializer with a closure. I suggest you reevaluate your parsing needs and rebuild around responseDecodable. If you need, you can create your own serializer by adopting ResponseSerializer. Your logic would be the same, just copied into the parse method.

Parse Cloud with Swift PFIdResultBlock Error

PFCloud.callFunctionInBackground("hello", withParameters: ["test":"tester"]) {
(response: AnyObject?, error: NSError?) -> Void in
if error == nil {
let responseString = response as? String
print(responseString)
} else {
print(error!.description)
}
}
I am getting the error:
Cannot convert value of type '(AnyObject?, NSError?) -> Void' to
expected argument type 'PFIdResultBlock?' (aka
'Optional<(Optional, Optional) -> ()>')
Even if I add as! PFIdResultBlock, the error will not go away.
How can I go about fixing this?
I definitely appreciate your help on this one!!
There is no need to specify the variable types while implementing the closure (Block in Objective-C) unlike Objective-C. You just need to change your code to the following:
PFCloud.callFunction(inBackground: "",
withParameters: ["": ""]) { (response, error) in
if error == nil {
let responseString = response as? String
print(responseString)
} else {
print(error?.localizedDescription)
}
}

Swift3 closure crash

Crashing while creating an instance of URLSessionTask with the completion handlers
func sessionTaskPostRequest (_ urlRequest : URLRequest , responseHandler: #escaping ResponseHandler) -> URLSessionTask {
// 5
let sesstionTask : URLSessionTask = networkSession.dataTask(with: urlRequest, completionHandler: { (data : Data? , urlResponse : URLResponse? , error : NSError? ) in
var json: NSDictionary!
do {
json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions()) as? NSDictionary
} catch {
print(error)
}
// Did the JSONObjectWithData constructor return an error? If so, log the error to the console
if(error != nil) {
responseHandler (false , nil , error , nil)
}
else {
// The JSONObjectWithData constructor didn't return an error. But, we should still
// check and make sure that json has a value using optional binding.
if let parseJSON = json {
let errorJSON = parseJSON ["Err"] as! String
if !errorJSON.isEmpty {
responseHandler (false , nil , nil , errorJSON)
}else {
responseHandler (true , parseJSON , nil , nil)
}
print("Succes: \(parseJSON)")
}
else {
// Woa, okay the json object was nil, something went worng. Maybe the server isn't running?
let jsonStr = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
responseHandler (false , nil , error , "Error could not parse JSON")
print("Error could not parse JSON: \(jsonStr)")
}
}
} as! (Data?, URLResponse?, Error?) -> Void)
return sesstionTask
}
And created a type alias for response handler that returns the response JSON Object . Type alias as follows
typealias ResponseHandler = (_ successFlag :Bool , _ data : NSDictionary? , _ errorObject : NSError? , _ errorString : String?) -> Void
Seems like Response handler is getting the Error Object as NSError which will get crashed if Error object is nil and failed to cast it to NSError
Error = nil
and when you receive it as NSError Typecasting fails because of nil object , but the same thing is handled wisely if you don't do any typecasting

Alamofire unexpectedly found nil while unwrapping an Optional value

I use this Alamofire code to download images for URL
func getImage(imageUrlString: String, completionHandler: (responseObject: UIImage?, error: NSError?) -> ()) {
makeGetImageCall(imageUrlString, completionHandler: completionHandler)
}
func makeGetImageCall(imageUrlString: String, completionHandler: (responseObject: UIImage?, error: NSError?) -> ()) {
//Perform request
print("Trying to get: " + imageUrlString)
Alamofire.request(.GET, imageUrlString, headers: ["Authorization": NSUserDefaults.standardUserDefaults().stringForKey("BasicAuthenticationString")!])
.responseImage { request, response, result in
print(request)
print(response)
print(result)
completionHandler(responseObject: result.value, error: nil)
}
}
This is my class that uses the method:
public class NewsListEntry: NSObject {
public var thumbnail: String = ""
public var thumbnailImage: UIImage = UIImage()
public var thumbnailDownloaded: Bool = false
public func downloadThumbnail() {
print(self.title)
GetImageHandeler().getImage(self.thumbnail, completionHandler: { (responseObject, error) in
})
}
}
Then i get a:
fatal error: unexpectedly found nil while unwrapping an Optional value
What have i done wrong?
This is the errors im getting:
What have i done wrong?
Two things. First, you are using the force-unwrap operator somewhere, possibly here:
NSUserDefaults.standardUserDefaults().stringForKey("BasicAuthenticationString")!
This means you're guaranteeing that the return value isn't nil, but in this case, it was. Since you broke your promise, the app crashes.
Second, PLEASE DO NOT STORE AUTHORIZATION STRINGS IN NSUSERDEFAULTS. iOS has a highly secure keychain for a reason. NSUserDefaults provides no encryption. Please use the keychain. There are wrapper libraries like Locksmith and SSKeychain which can help you.
You are unwrapping the result without checking if it's valid or not. Add the following code:
Alamofire.request(.GET, imageUrlString, headers: ["Authorization": NSUserDefaults.standardUserDefaults().stringForKey("BasicAuthenticationString")!])
.responseImage { request, response, result in
print(request)
print(response)
print(result)
switch result {
case .Success(let value):
completionHandler(responseObject: value, error: nil)
case .Failure(_, let error):
completionHandler(responseObject: nil, error: error)
}
}
If using Swift 2, you'll need to change the error parameter of the completionHandler block from NSError? to ErrorType.

Alamofire Completion Handler returning response + data

I have a function that includes a responseObject in it's completion handler. At the moment this returns the json body when I call it, along with any errors.
Some parts of the API I am using however, don't return any data in the response body, they just return a response (200, 404, etc...)
I was thinking about appending the response inside the empty json object that is getting returned, then realised that would be silly and it would probably be better if I returned the NSHTTPURLResponse as well, but everything I have found just explains how to return the responseObject along with the error...
This is the function that returns the completion handler:
func makePostRequest(url : String, params : AnyObject, completionHandler: (responseObject: NSHTTPURLResponse, JSON?, error: NSError?) -> ()) -> Request? {
println("params = \(params)")
return Alamofire.request(.POST, url, parameters: params as? [String : AnyObject], encoding: .JSON)
.responseJSON { (request, response, data, error) in completionHandler(
//This is wrong
response: response as? NSHTTPURLResponse,
responseObject:
{
println("Request is \(request)")
println("Response is \(response)")
println("Data is \(data)")
println("Error is \(error)")
//Append the response to this JSON object?
//
var json:JSON = [:]
if let anError = error
{
println(error)
}
else if let data: AnyObject = data
{
json = JSON(data)
}
//probably better to return the two...
//
return (response, json)
}(),
error: error
)
}
}
And this is how its used:
networking.makePostRequest(documentUrl, params: docParams) { response, json, error in
println("response is: \(response)")
println("document json: \(json)")
println("document error: \(error)")
}
I've added in the 'response' bits to all the bits of code, i'm sure this is possible? just not sure how to achieve it..
For anyone stuck trying to figure out how to return stuff this way, I solved it like this:
func makePostRequest(url : String, params : AnyObject, completionHandler: (httpResponse: NSHTTPURLResponse, responseObject:JSON?, error: NSError?) -> ()) -> Request? {
println("params = \(params)")
return Alamofire.request(.POST, url, parameters: params as? [String : AnyObject], encoding: .JSON)
.responseJSON { (request, response, data, error) in completionHandler(
//This is wrong
httpResponse: response!,
responseObject:
{
println("Request is \(request)")
println("Response is \(response)")
println("Data is \(data)")
println("Error is \(error)")
//Append the response to this JSON object?
//
var json:JSON = [:]
if let anError = error
{
println(error)
}
else if let data: AnyObject = data
{
json = JSON(data)
}
return json
}(),
error: error
)
}
}
and then calling it like this:
networking.makePostRequest(workDocumentUrl, params: params) { response, json, error in
if response.statusCode == 200{
//do something
}
println("json: \(json)")
println("error: \(error)")
}

Resources