Search code examples
iosswiftnsstringoption-type

Handle nil value in Swift for NSString


The following method is called a lot from Objective-C files (it's a mixed Obj-C and Swift project) and under certain circumstances I seem to get a nil value for an NSString that throws an exception. According to this post Swift implicitly converts an NSString to a force unwrapped String!. How can I handle a nil case

Should I use an if let statement? If so, what would the syntax be? I can't get it to work.

@objc func download(surl: NSString, completion : @escaping (NSData) -> Void ) {
        
        guard let url = URL(string: String(surl)) else {
            //print("Can not get url with " , surl )
            return }
        
        let sessionConfig = URLSessionConfiguration.default
        let session = URLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil)
        
       
        let task = session.dataTask(with: url) { data, response, error in
            if let data = data, error == nil {
                let nsdata = NSData(data: data)
                DispatchQueue.main.async {
                    completion(nsdata)
                }
            } else {
                
               // print("Failure: %@", error?.localizedDescription);
            }
        }
        task.resume()
    }

Solution

  • Why are you even using Objective-C types with Swift? You could have simply used String instead of NSString and Data instead of NSData.

    @objc func download(surl: String?, completion: ((Data?)->())?) {
        guard let str = surl, let url = URL(string: str) else {
            //print("Can not get url with " , surl )
            return
        }
    
        URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data else {
                print(error?.localizedDescription)
                completion?(nil)
                return
            }
            DispatchQueue.main.async {
                completion?(data)
            }
        }.resume()
    }
    

    Also, you can use URSession.shared object in case there is no specific networking requirement.