Register NSURLProtocol (URLProtocol) class for use with external app?

1k views Asked by At

I want to use a custom NSURLProtocol class to serve static data for testing and I have done this implementing the protocol in the application itself and registering it to the NSURLSessionConfiguration.protocolClasses. I want to move the protocol class to another app and register it for other applications to use. Is this possible?

Apple Documentation for registerClass: states:

Attempts to register a subclass of NSURLProtocol, making it visible to the URL loading system.

In the new app that I want to use as the protocol, I register the protocol but the external app doesn't call into it.

// Swift 3
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    URLProtocol.registerClass(MyCustomURLProtocolClass)
}

I want an external app to be able to use my protocol class with NSURLSession and call it with a url such as foo://externalApplication.com.

Thanks for the help!

1

There are 1 answers

0
dgatwood On BEST ANSWER

NSURLProtocol registration is inherently per-process. It is not possible to register a protocol in one process for use it in another, because that would be a security hole, allowing any app to trivially manipulate any other app's traffic.

Assuming this is just for testing purposes, and assuming you are in control of both apps, you might consider either A. writing your server code in an app extension or B. using openURL to establish a communication channel between the apps like this:

  • Make your server app an actual web server. (There are a number of third-party web server frameworks out there.)
  • Register a URL scheme for that server app so that the other app can launch it on demand.
  • In the other app, register a URL scheme so that the server app can return control to that app after being launched.
  • In the other app, use openURL to kick the server app and pass a custom URL that will open the other app.
  • In the server app, decode that URL and use openURL to switch back to the other app, appending a port number as part of the URL it sends to the other app.
  • In the other app, grab the port number out of the URL and start talking to the local web server. If this ever fails to respond, send another openURL request.

For details, and for more inter-application communication tips and techniques, I would suggest reading this article: http://www.goldmansachs.com/what-we-do/engineering/see-our-work/app-to-app-comm.html