Home > other >  How to verify that a website is reachable with Swift?
How to verify that a website is reachable with Swift?

Time:02-14

My app shall access a php file on a hosted website in order to get data from a backend SQL database. This works fine but I want to be prepared or all kind of possible errors. In case there is no internet connection or the host cannot be reached, an error is thrown - fine. But if the url address is modified to an address which does not exist on the host, no error is thrown. But I want to cover this condition as well. What is the best way in Swift to do this?

Here is my code:

    @available(iOS 15.0, *)
   func checkCustomerExistsInBackend(emailAddress: String) async throws -> String 
   {
    
    let url = URL(string: "https://myHost.de/mySite/checkCustomerexists.php")!
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    
    let dataString = "EmailAddress=\(emailAddress)"
    var returnValue = ""
    do {
        let dataD = dataString.data(using: .utf8)
        let (data, _) = try await URLSession.shared.upload(for: request, from: dataD!, delegate: nil)
        let answer = try JSONDecoder().decode(BackendMessage.self, from: data)
        returnValue = answer.Message
    }
    catch {
        let myError: NSError = error as NSError
        switch myError.localizedDescription {
        case "The Internet connection appears to be offline.":
            throw BackendError.noInternet
        case "A server with the specified hostname could not be found.":
            throw BackendError.serverNotFound
        default:
            throw error
        }
    }
    return returnValue
}

The url above with "https://myHost.de/mySite/checkCustomerexists.php" is not the true address of course. But when I replace "myHost.de" with the true host address, no error is thrown even though a site "mySite" does not exist.

I spent several hours searching for the answer in SO but could not find anything that works for my constellation.

Any hint would be appreciated!

CodePudding user response:

Larme's comment answered this question. In case it is helpful for anybody stepping over the same subject, here the modified code of my example with the solution based on Larme's advice:

   @available(iOS 15.0, *)
func checkCustomerExistsInBackend(emailAddress: String) async throws -> String {
    
    let url = URL(string: "https://myHost.de/mySite/checkCustomerexists.php")!
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    
    let dataString = "EmailAddress=\(emailAddress)"
    var returnValue = ""
    do {
        let dataD = dataString.data(using: .utf8)
        let (data, response) = try await URLSession.shared.upload(for: request, from: dataD!, delegate: nil)
       
        let httpURLResponse = response as? HTTPURLResponse
        let statusCode = httpURLResponse?.statusCode
        if statusCode != 404 {
            let answer = try JSONDecoder().decode(BackendMessage.self, from: data)
            returnValue = answer.Message
        }
        else {
            throw BackendError.invalidURL
        }
    }
    catch {
        let myError: NSError = error as NSError
        print(myError.localizedDescription)
        switch myError.localizedDescription {
        case "The Internet connection appears to be offline.":
            throw BackendError.noInternet
        case "A server with the specified hostname could not be found.":
            throw BackendError.serverNotFound
        default:
            throw error
        }
    }
    return returnValue
}
  • Related