使用 Xcode 在 Swift 中 Ping 本地主机

Pinging localhost in Swift w/ Xcode

最终我的 Swift 前端将 API 调用外部服务器,但在开发过程中,我想在我的计算机上进行本地测试。如何从 Xcode 访问我的本地主机服务器?在这一点上,我只是想确保联系——我还不需要实际检索任何东西。

到目前为止我有以下代码:

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

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

urlString 变量中,我尝试了我的实际 IP 地址。我还尝试了 localhost:4001/hello,其中 4001 是我的 node.js 服务器监听的端口,我定义了 /hello。我是否使用了错误的地址、错误的代码,或者无法从 Xcode 联系我的本地计算机?

如果您 print(error)catch 块中(这始终是一个好习惯 -- print("Failure!") 不会告诉您 为什么 catch 块被调用)你会注意到有一个错误告诉你:

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

虽然没有明确说明,但我认为这里的含义是 checkResourceIsReachable 用于文件系统 URLs -- 不是远程 http 请求。

相反,使用一个系统来验证 URL 是否可以访问远程资源。

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/")
            }
    }
}

如评论中所述,您需要确保在 Info.plist

中将 NSAllowsArbitraryLoads 设置为 YES