3
votes

I am trying to make a service call to get user details however i get this error :

Thread 10: Fatal error: Unexpectedly found nil while unwrapping an Optional value

From this code :

    let urlString = "http://myURL.com/getInfo/getAccountTransactions/{accountPublicKey}"
    print(urlString)
    let requestUrl = URL(string:urlString)
    let requestURL = URLRequest(url:requestUrl!)

When i wrap the code in a guard let the code doesn't get executed because it finds nil, i am not sure why because the URL string can never be nill since its initialized with a default value on the same code.

This the code in a guard let :

    let urlString = "http://myURL.com/getInfo/getAccountTransactions/{accountPublicKey}"
    guard let requestUrl = URL(string:urlString) else { return }
    let requestURL = URLRequest(url:requestUrl)

This the entire service call code :

class TransactionServiceCall : NSObject, URLSessionDelegate{

let viewResponse = ThrowResponse()

func fetchTransactions(requestObject: Transaction, completion: @escaping (Dictionary<String,Any>?) -> Void) {
    let urlString = "http://myURL.com/getInfo/getAccountTransactions/{accountPublicKey}"

    guard let requestUrl = URL(string:urlString) else { return }
    let requestURL = URLRequest(url:requestUrl)

    let searchParams = Transaction.init(publicKey: requestObject.publicKey)
    var request = requestURL
    request.httpMethod = "POST"
    request.httpBody = try?  searchParams.jsonData()
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    let session = URLSession.shared

    let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in
        do {
            let httpResponse = response as! HTTPURLResponse
            let statusCode = httpResponse.statusCode

            if 200 ... 299 ~= statusCode {
                if let json = try JSONSerialization.jsonObject(with: data!) as? Dictionary<String,Any> {
                    self.viewResponse.dismissLoader()
                    print(json)
                    completion(json)
                }
            }else{
                self.viewResponse.dismissLoader()
                self.viewResponse.showFailureAlert(title: "Failure", message: "")
                completion(nil)
            }
        } catch {
            DispatchQueue.main.async {
                self.viewResponse.dismissLoader()
                self.viewResponse.showFailureAlert(title: "Failure", message: "")
                completion(nil)
            }
        }
    })

    task.resume()

  }

}

It is important to note that the url has curly brackets in it e.g

http://myURL.com/getInfo/getAccountTransactions/{accountPublicKey}

1
If the URL cannot be created then urlString has the wrong format.vadian
What happens if you try URLComponents(string: urlString)?.url instead of URL(string:)? URLComponents uses a newer RFC to create URLs, and without knowing what your URL is ("http://myURL.com/getInfo" works on my machine), it's not inconceivable that that could alter the behavior.Charles Srstka
URLComponents doesnt work also, another thing to note is that the url has curly brackets like this : myURL.com/getInfo/getAccountTransactions{accountPublicKey}Erent
in postman the url works fine and the curly brackets are part of the urlErent
Hey this code working wellGowtham Sooryaraj

1 Answers

5
votes

You need to escape special characters in the url string using addingPercentEncoding(withAllowedCharacters:) and an appropriate CharacterSet so that a valid URL object may be created from it.
In your case, the CharacterSet should be .urlQueryAllowed

Like so:

//The unescaped string
let unescaped = "http://myURL.com/getInfo/getAccountTransactions/{accountPublicKey}"

//The escaped string
let escaped = unescaped.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)

//...