data cosmos
data cosmos

Reputation: 313

Is swift 3 not compatible with NSURL classes on iOS 9?

I am migrating my Swift 2.2 code building and working fine on xcode 7 / ios 8 and ios 9. As of the answer to this question Swift 3 is compatible with iOS 8 and newer. And I am also aware that I won't be able to use newer APIs.

In my app I am creating some https requests, downloading some files etc.

My assumption is that I should also be able to use the classes NSURL, URLSessionDownloadDelegate, NSMutableURLRequest, etc. all available from iOS (8.0 and later).

But either I (obiously) run into a crash running my migrated code on iOS 8.1 because I use the URL class (available from iOS 10) or the compiler complains 'NSURL' is not implicitly convertible to 'URL' (see also this question).

Therefore I am not able to use the URL class, if I want to be compatible with iOS 9.

Here is some code to make things clearer:

Swift 2:

class ServerCom: NSObject, NSURLSessionDownloadDelegate {
   private var fileURL: NSURL = NSURL()
    [...]       
           guard let urlString: NSURL =
        NSURL(string: params,
            relativeToURL: NSURL(string: dcParam.baseURL) )  else {
                let failed = "Could not generate URL from: \(dcParam.baseURL)\(params)"
                throw fetchAppXmlError.FAILED_URL_GENERATION(failed)
    }
    [...]
    let request = NSMutableURLRequest(URL: urlString)
    request.timeoutInterval = 10
    request.HTTPMethod = "GET"

}

Swift 3

class ServerCom: NSObject, URLSessionDownloadDelegate {

 fileprivate var localFileURL: NSURL = NSURL()

 [...]

         guard let urlString: NSURL =
            NSURL(string: params,
                relativeTo: NSURL(string: dcParam.baseURL) )  else {
                    let failed = "Could not generate URL from: \(dcParam.baseURL)\(params)"
                    throw fetchAppXmlError.failed_URL_GENERATION(failed)
        }

 let request = NSMutableURLRequest(url: urlString)
 request.timeoutInterval = 10
 request.httpMethod = "GET"
 [...]

}

In the swift 3 code I get the following errors:

  1. At the line with: let request = ...: 'NSURL' is not implicitly convertible to 'URL'; did you mean to use 'as' to explicitly convert?
  2. At the line with let urlString = ...: Cannot convert value of type 'NSURL?' to expected argument type 'URL?'

I can't use localFileURL with type URL because this would be iOS 10 only. I also can't use URLRequest instead of NSMutableURLRequest because it is also only available from iOS (10.0 and later). It seems that I always use somehow URLs of type URL rather than the "old" NSURL.

So my question is: Is there any way to use NSURL et. al. with swift 3 and iOS 9?

Or in more general, is there a way to do background downloads with swift 3 that will work on iOS 9 and iOS 10?

Does this inconsistency come from the bridging of NSURLComponents to URLComponents?

Upvotes: 1

Views: 4577

Answers (1)

data cosmos
data cosmos

Reputation: 313

Thanks to OOPer i can answer my own question:

the code works fine with the URL class but only when you set the Deplyoment Target to the same iOS Version as your simulator!

XCode 8 updated my iOS 9 SDK to version 10 and so I only had the choice to use the simulator on either iOS 10 or iOS 8.1. However the Deployment Target was set to iOS 9 (I was pretty sure that it was before the upgrade set to iOS 8.1).

So I run into the runtime error with an iOS 8.1 simulator and Deployment Target set to iOS 9.

But it does work with iOS 8.1 simulator and Deployment Target set to iOS 8.1!

Here is the Swift 3 Code working also with iOS 8.1:

class ServerCom: NSObject, URLSessionDownloadDelegate {

fileprivate var localFileURL: URL = URL(string: "dummy")!

 [...]

         guard let urlString: URL =
            URL(string: params,
                relativeTo: URL(string: dcParam.baseURL) )  else {
                    let failed = "Could not generate URL from: \(dcParam.baseURL)\(params)"
                    throw fetchAppXmlError.failed_URL_GENERATION(failed)
        }

        var request = URLRequest(url: urlString)
        request.timeoutInterval = 10
        request.httpMethod = "GET"
 [...]

}

Thank you!

Upvotes: 0

Related Questions