6
votes

Apple introduced fancy new error handling in Swift 2

https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html#//apple_ref/doc/uid/TP40014216-CH7-ID10

I'm working with project that uses AFNetoworking v2.x where AFHTTPRequestSerializer has 2 selectors:

- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
                             URLString:(NSString *)URLString
                            parameters:(id)parameters DEPRECATED_ATTRIBUTE;

- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
                             URLString:(NSString *)URLString
                            parameters:(id)parameters
                                 error:(NSError * __autoreleasing *)error;

First is deprecated but second is converted automatically to first signature by Swift 2 compiler. Old fashioned method now doesn't allowed:

var error: NSError?
let request = self!.operationManager.requestSerializer.requestWithMethod(method, URLString: url?.absoluteString, parameters: params, error: error)

gives me a compile time error:

Cannot convert value of type 'NSError?' to expected argument type '()'

But brand new notation reduces selector with error processing to deprecated variant without it.

do {
    let request = try
    self!.operationManager.requestSerializer.requestWithMethod(method, URLString: url?.absoluteString, parameters: params)
} catch let error as NSError {
    // ...
}

What is best practice in Swift 2 to solve this problem? Is there any way to specify certain selector in this situation?

UPD: More precise link on Swift 2 feature that become a reason of my problem. https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/AdoptingCocoaDesignPatterns.html#//apple_ref/doc/uid/TP40014216-CH7-ID10

2
Well, I know what I would do; I'd write a trampoline method in Objective-C. (And I'd file a bug report with the AFNetworking people.) - matt
Yes it looks like a better choice in case Swift 2 have no tools to solve this itself. But I wonder Swift architects predicted such problems and they had some proper way in minds to overcome this type of problems. - lazarev
Are you sure the deprecated variant is called? Maybe Xcode just mixes up deprecation warnings? - Sulthan

2 Answers

0
votes

Seems this works properly in Xcode 7.1 (I recall having this issue in 7.0) just change your method to use an error pointer i.e &error

var error: NSError?
let request = self!.operationManager.requestSerializer.requestWithMethod(method, URLString: url?.absoluteString, parameters: params, error: &error)
-1
votes

Swift 2 prefers to provide Try Catch block to necessary methods only. Thus if your method have cases where you might need error handling then only provide this block.

do {    
   try managedObjectContext.save() 
} catch {

   // Replace this implementation with code to handle the error appropriately.

   // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.

   let NSError = error as NSError

   NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
   abort()
}