1

When tying out network requests from a Swift playground, I can't see the network call in Charles Proxy. However, it works when I do network requests from an iOS simulator by following the steps in the answer here.

Would be nice to make it work for Xcode Playgrounds for faster iteration. Does anyone know what needs to be done to make it work there?

Guy Daher
  • 5,526
  • 5
  • 42
  • 67

3 Answers3

2

Swift 5 version of fruitcoder's answer:


public class NetworkEnabler: NSObject, URLSessionDelegate {
    public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
    }
}

Then to initialize the URLSession:

let session = URLSession(configuration: .default, delegate: NetworkEnabler(), delegateQueue: nil)
stas95
  • 58
  • 7
  • Is there something we can do to view decrypted contents? For instance, we had to trust a Charles Proxy certificate on the real device when using that. – BFeher Feb 05 '20 at 22:50
  • @BFeher Did you try `Enable SSL Proxy` in Charles for those requests? – stas95 Feb 10 '20 at 09:09
1

Unlike the simulator, Playgrounds don't have their own network configuration. If you need a proxy on a Playground then you need to proxy your Mac's network connection. That will affect every app on your Mac, which is potentially a lot of data. It should work but you might want to quit any other network-related apps that you can. If you don't need to use your browser while testing, for example, quit it until you're done.

Tom Harrington
  • 69,312
  • 10
  • 146
  • 170
1

I found a gist that describes a way to make it work with Playgrounds. It circumvents the need to alter the ATS settings. Create an object conforming to URLSessionDelegate with the following implementation:

public class NetworkEnabler: NSObject, NSURLSessionDelegate {
    public func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
        completionHandler(.UseCredential, NSURLCredential(trust: challenge.protectionSpace.serverTrust!))
    }
}

and create a session with an instance as its delegate: URLSession(configuration: .default, delegate: enabler, delegateQueue: nil). Using that session for requests will allow you to use Charles.

fruitcoder
  • 1,073
  • 8
  • 24