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?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With