Blog

Swift & AFNetworking 2.2.4

Since writing this post we have had more discussions and received some feedback. After some more investigation we’ve now have more info on why Xcode crashes and found a better solution.

Checkout out the follow up post for all the details.

As you probably know Apple announced a new programming language called Swift. A language that is not built on C but can run along side with it and Objective-C.

A lot of people, including ustwo, have started porting their applications from Objective-C to Swift. Depending on your approach you might start fresh with a new Swift project or, like I’ve done, adding Swift code to your current Objective-C project as you go.

If you are using AFNetworking together with CocoaPods in your project you might, eventually, run into a problem where Xcode just keeps crashing when you launch your app.

The problem

What we often do in our projects is that we subclass the AFHTTPSessionManager to isolate all network configuration in one place.

Let’s say you are working on a project that is communicating with a backend that is responding with JSON. Then your subclass might look something like this:

class SessionManager: AFHTTPSessionManager { init(baseURL url: NSURL!) { super.init(baseURL: url) requestSerializer = AFJSONRequestSerializer(); responseSerializer = AFJSONResponseSerializer(); }}

That’s all fine. You run your app and what happens is that it will crash and Xcode will crash as well.

Xcode is in beta so I’m not really bothered with it crashing. However there’s little information about what is actually going on. By digging through the log files I found this error message:

SessionManager.swift: 11: 11: fatal error: use of unimplemented initializer 'init(baseURL:sessionConfiguration:)' for class 'MyProject.SessionManager'

You can find the log files in: ~/Library/Logs/DiagnosticReports/.

Look for a file that matches the format: appName_date_user.crash.

You will find the error message in the “Application Specific Information” section of the crash log.

How we solved it

I’m assuming that because there’s no default initializer in AFHTTPSessionManager Swift cannot treat the other ones as convenience initializers.

Meaning that you have to override the initializers that is called from within AFNetworking and simply call the super implementation, otherwise Swift cannot recognize the selector and will crash your app together with Xcode.

In our case it would look like this:

class SessionManager: AFHTTPSessionManager { init(baseURL url: NSURL!) { super.init(baseURL: url) setup() } init(baseURL url: NSURL!, sessionConfiguration configuration: NSURLSessionConfiguration!) { super.init(baseURL: url, sessionConfiguration: configuration) setup() } func setup() { requestSerializer = AFJSONRequestSerializer(); responseSerializer = AFJSONResponseSerializer(); }}

Build, run and you should be free from crashes!