brainray brainray - 6 months ago 79
Swift Question

Alamofire.request vs. manager.request - manager not working

EDIT: the question was not about what -999 means, but why do I not get an error with the first code fragment, but with the second?
Apart of using the Alamofire.Manager in the second code snippet (that should work identical to the Alamofire.request in the first code snippet), everything is identical.
Is this a bug, or do I miss something?

I have a function that works with Alamofire.request...

func getMenuFromIsoShortDate(menuDate: String) {
let user = Constants.DummyCredentials.UserName
let password = Constants.DummyCredentials.PassWord

var urlString = ""
let dateForWebservice: NSDate? = NSDate.dateFromIsoString(menuDate)

if let dateForWebservice = dateForWebservice {
urlString = Constants.WebservicePath.DailyMenu + NSDate.dateToIsoSlash(dateForWebservice)
println("urlString: \(urlString)")
}
let credential = NSURLCredential(user: user, password: password, persistence: .ForSession)

Alamofire.request(.GET, urlString)
.authenticate(usingCredential: credential)
.response {
(request, response, data, error) in

if let response = response {
var statusCode = response.statusCode
println("-->statusCode: \(statusCode)")
}

if (error == nil) {
var serializationError: NSError?
let jsonData: AnyObject? = NSJSONSerialization.JSONObjectWithData(data! as! NSData, options: NSJSONReadingOptions.AllowFragments, error: &serializationError)

var parser: Parser = Parser()
let menu: Menu = parser.parseMenuJSON(jsonData)

var dataAccess: DataAccess = DataAccess.sharedInstance
dataAccess.addMenu(menu)
} else {
println("Webservice error: \(error)")
}
}
}


but when I run the code with manager.request - it runs, but gives me a -999 error. Here the altered code:

func getMenuFromIsoShortDate(menuDate: String) {
let user = Constants.DummyCredentials.UserName
let password = Constants.DummyCredentials.PassWord

var urlString = ""
let dateForWebservice: NSDate? = NSDate.dateFromIsoString(menuDate)

if let dateForWebservice = dateForWebservice {
urlString = Constants.WebservicePath.DailyMenu + NSDate.dateToIsoSlash(dateForWebservice)
println("urlString: \(urlString)")
}
let credential = NSURLCredential(user: user, password: password, persistence: .ForSession)

let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
manager = Alamofire.Manager(configuration: configuration)

manager.request(.GET, urlString)
.authenticate(usingCredential: credential)
.response {
(request, response, data, error) in

if let response = response {
var statusCode = response.statusCode
println("-->statusCode: \(statusCode)")
}

if (error == nil) {
var serializationError: NSError?
let jsonData: AnyObject? = NSJSONSerialization.JSONObjectWithData(data! as! NSData, options: NSJSONReadingOptions.AllowFragments, error: &serializationError)

var parser: Parser = Parser()
let menu: Menu = parser.parseMenuJSON(jsonData)

var dataAccess: DataAccess = DataAccess.sharedInstance
dataAccess.addMenu(menu)
} else {
println("Webservice error: \(error)")
}
}
}


And here the error message:

Webservice error: Optional(Error Domain=NSURLErrorDomain Code=-999 "Abgebrochen" UserInfo=0x7f8f11c3f210 {NSErrorFailingURLKey=http://test.myserver.de:18507/app/services/mampf/get-menu/2015/05/08, NSLocalizedDescription=Abgebrochen, NSErrorFailingURLStringKey=http://test.myserver.de:18507/app/services/mampf/get-menu/2015/05/08})


What's wrong with this?

Answer

I can see two possible problems.

Problem 1 - Manager gets deallocated

The first obvious one is whether you are keeping your custom manager instance in memory. You need to hold onto the manager in a property to ensure it doesn't get deallocated in the middle of the request.

Problem 2 - Missing default HTTP headers

The only difference between Alamofire.request and your manager.request is that your manager is missing the default headers that the Alamofire shared manager attaches by default.

public static let sharedInstance: Manager = {
    let configuration: NSURLSessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
    configuration.HTTPAdditionalHeaders = Manager.defaultHTTPHeaders

    return Manager(configuration: configuration)
}()

I would add the following line to your manager initialization and see if that makes the behavior consistent.

let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
configuration.HTTPAdditionalHeaders = Alamofire.Manager.defaultHTTPHeaders
manager = Alamofire.Manager(configuration: configuration)

Hopefully that helps you get to the bottom of your issue. It's not apparent to me why the lack of the default headers would cause the issue you are seeing, but without access to your project, it's difficult to dig any further.