Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pinging localhost in Swift with Xcode

Eventually my Swift frontend will make API calls to an external server, but in the development process, I want to test things locally on my computer. How do I reach my localhost server from Xcode? At this point I'm just trying to ensure contact--I don't need to actually retrieve anything yet.

So far I have the following code:

let urlString = "MY_IP_ADDRESS"
let url = URL(string: urlString)!

do {
    try url.checkResourceIsReachable()
    print("Success!")
} catch {
    print("Failure!")
}

In the urlString variable, I tried my actual IP Address. I also tried localhost:4001/hello where 4001 was the port my node.js server was listening on and I defined /hello. Am I using the wrong address, the wrong code, or is there no way to contact my local machine from Xcode?

like image 235
John Sorensen Avatar asked May 13 '26 02:05

John Sorensen


1 Answers

If you print(error) in your catch block (which is always a good practice -- print("Failure!") doesn't tell you why the catch block was invoked) you'll notice that there's an error telling you:

The file couldn’t be opened because the specified URL type isn’t supported.

Although it isn't explicitly said, I think the implication here is that checkResourceIsReachable is for filesystem URLs -- not remote http requests.

Instead, use a system of verifying the URL is reachable meant for remote resources.

import SwiftUI
import Combine

class CheckURL : ObservableObject {
    enum URLResult : String {
        case unknown, unreachable, reachable
    }
    
    @Published var urlReachable : URLResult = .unknown
    private var cancellable : AnyCancellable?
    
    func verifyURL(urlPath: String) {
        guard let url = URL(string: urlPath) else {
            assertionFailure("Invalid URL")
            self.urlReachable = .unknown
            return
        }
        
        var request = URLRequest(url: url)
        request.httpMethod = "HEAD"
        
        cancellable = URLSession.shared.dataTaskPublisher(for: url).tryMap({ (_ , response: URLResponse) -> URLResult in
            if let response = response as? HTTPURLResponse, response.statusCode == 200 {
                return .reachable
            } else {
                return .unreachable
            }
        })
        .replaceError(with: .unreachable)
        .receive(on: RunLoop.main).sink { result in
            self.urlReachable = result
        }
    }
}

struct ContentView : View {
    @StateObject private var urlChecker = CheckURL()
    
    var body: some View {
        Text("Reachable? \(urlChecker.urlReachable.rawValue)")
            .onAppear {
                    urlChecker.verifyURL(urlPath: "http://localhost:4001/")
            }
    }
}

As mentioned in the comments, you'll want to make sure you have NSAllowsArbitraryLoads set to YES in your Info.plist

like image 139
jnpdx Avatar answered May 14 '26 17:05

jnpdx



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!