1

I'm trying to change my Soap service to Swift2, but I get an error:

CFNetwork SSLHandshake failed (-9824)

I tryed to google it, but I still get same error, full error here:

2015-12-28 09:28:01.674 SoapSwift[501:7558] CFNetwork SSLHandshake failed (-9824) 2015-12-28 09:28:01.675 SoapSwift[501:7558] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824) error of Optional(Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={_kCFStreamErrorCodeKey=-9824, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, NSUnderlyingError=0x7feaf2634fb0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9824, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9824}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://ip:port/.../server.php, NSErrorFailingURLStringKey=https://ip:port/.../server.php, _kCFStreamErrorDomainKey=3})

My info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>

    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>https://ip:port/</key>
            <dict>
                <!--Include to allow subdomains-->
                <key>NSIncludesSubdomains</key>
                <true/>
                <!--Include to allow insecure HTTP requests-->
                <key>NSExceptionAllowsInsecureHTTPLoads</key>
                <true/>
                <!--Include to specify minimum TLS version-->
                <key>NSExceptionMinimumTLSVersion</key>
                <string>TLSv1.1</string>
            </dict>
        </dict>
    </dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>en</string>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>$(PRODUCT_NAME)</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>1</string>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>UILaunchStoryboardName</key>
    <string>LaunchScreen</string>
    <key>UIMainStoryboardFile</key>
    <string>Main</string>
    <key>UIRequiredDeviceCapabilities</key>
    <array>
        <string>armv7</string>
    </array>
    <key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>UISupportedInterfaceOrientations~ipad</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationPortraitUpsideDown</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
</dict>
</plist>

Soap code:

import UIKit

class ViewController: UIViewController, UITextFieldDelegate, NSXMLParserDelegate, NSURLSessionDataDelegate, NSURLSessionDelegate {

    var MutableData: NSMutableData = NSMutableData()
    var currentElementName: NSString = ""

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let soapMessage = "<?xml version='1.0' encoding='UTF-8'?>..."

//        let session = NSURLSession.sharedSession()


        let urlString = "https://ip:port/"

        let url = NSURL(string: urlString)
        let theRequest = NSMutableURLRequest(URL: url!)
        let msgLength = String(soapMessage.characters.count)

        theRequest.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
        theRequest.addValue(msgLength, forHTTPHeaderField: "Content-Length")
        theRequest.addValue("urn:ResponseAction", forHTTPHeaderField: "SOAPAction")
        theRequest.HTTPMethod = "POST"
        theRequest.HTTPBody = soapMessage.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
        let config = NSURLSessionConfiguration.defaultSessionConfiguration()
        let session = NSURLSession(configuration: config, delegate: self, delegateQueue: NSOperationQueue.mainQueue())
        let task = session.dataTaskWithRequest(theRequest)
        task.resume()
    }

    func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {

        print("Am in NSURLSessionDelegate didReceiveChallenge")

        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust && challenge.protectionSpace.host == "example.com" {
            NSLog("yep authorised")
            let credential = NSURLCredential(trust: challenge.protectionSpace.serverTrust!)
            challenge.sender!.useCredential(credential, forAuthenticationChallenge: challenge)
        } else {
            NSLog("nope")
            challenge.sender!.performDefaultHandlingForAuthenticationChallenge!(challenge)
        }

    }
    func URLSessionDidFinishEventsForBackgroundURLSession(session: NSURLSession) {
        print("Am in URLSessionDidFinishEventsForBackgroundURLSession")
        let xmlParser = NSXMLParser(data: MutableData)
        xmlParser.delegate = self
        xmlParser.parse()
        xmlParser.shouldResolveExternalEntities = true
    }
    func URLSession(session: NSURLSession, didBecomeInvalidWithError error: NSError?) {
        print("error of \(error)")
    }

    func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void) {
        print("Am in didReceiveResponse")
        MutableData.length = 0
    }


    func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
        print("Am in didReceiveData")
        MutableData.appendData(data)
    }

    func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
        print("error of \(error)")
    }

}
Peppo
  • 1,107
  • 1
  • 12
  • 19
Ben
  • 761
  • 1
  • 12
  • 35
  • The exception domain should be *a domain*, not a URL, so you just want *ip address* not *https://ip address/path* – Paulw11 Dec 28 '15 at 11:12
  • @Paulw11 So what have to change in the xml ? – Ben Dec 28 '15 at 12:20
  • Where you have `https://ip:port` try just `ip` in the key. You may also just have to disable ATS entirely. – Paulw11 Dec 28 '15 at 19:54
  • @Paulw11 I think I can't use ip : http://stackoverflow.com/questions/30903923/app-transport-security-and-ip-addresses-in-ios9 – Ben Dec 29 '15 at 08:03
  • I thought that might be the case. If there is no dns entry for your server then you just need to disable ATS entirely – Paulw11 Dec 29 '15 at 08:09

0 Answers0