iOS应用程序在输入IP地址时崩溃

iOS app crash when fetcing the IP address

提问人:RP89 提问时间:8/1/2022 最后编辑:SulthanRP89 更新时间:8/1/2022 访问量:2423

问:

在我的申请中,我起诉获取 IP 地址。以下是获取 IP 的代码。

 func getUrlIPAddress(){
      let url = URL(string: "https://api.ipify.org")

     do {
        if let url = url {
            let ipAddress = try String(contentsOf: url)
            self.ipAddressSend = ipAddress
            UserDefaults.standard.set(ipAddress, forKey: "agent_ipaddress")
        }
     } catch let error {
        print(error)
     }
    }

但是在应用商店控制台中报告了一次崩溃。我无法重现崩溃。即使它处理得足够多,为什么会崩溃? 这是崩溃日志的详细信息。enter image description here

请帮我找到这次崩溃的原因。

iOS Swift 崩溃

评论

0赞 Reinier Melian 8/1/2022
这段代码对我有用,也许是竞争条件?
0赞 RP89 8/1/2022
即使我也无法重现这个问题。但是在应用商店控制台中经常报告此崩溃。

答:

2赞 workingdog support Ukraine 8/1/2022 #1

您的代码有效,但它给了我这个编译器警告:“https://api.ipify.org 的同步 URL 加载不应发生在此应用程序的主线程上,因为它可能会导致 UI 无响应。请切换到异步网络 API,例如 URLSession。

最好使用这种方法:

func getUrlIPAddress() {
    let url = URL(string: "https://api.ipify.org")
    do {
        if let url = url {
            Task{@MainActor in
                let (data, _) = try await URLSession.shared.data(from: url)
                let ipAddress = String(data: data, encoding: .utf8)!
                self.ipAddressSend = ipAddress
                UserDefaults.standard.set(ipAddress, forKey: "agent_ipaddress")
            }
        }
    } catch let error {
        print(error)
    }
}

编辑-1:对于ios 12,您可以尝试以下方法:

func getUrlIPAddress() {
    guard let url = URL(string: "https://api.ipify.org") else { return }
    URLSession.shared.dataTask(with: url) { data, _, error in
        guard let data = data else { return }
        let ipAddress = String(data: data, encoding: .utf8)!
        print("\n---> ipAddress: \(ipAddress)")
        self.ipAddressSend = ipAddress
        UserDefaults.standard.set(ipAddress, forKey: "agent_ipaddress")
    }.resume()
}

评论

1赞 RP89 8/1/2022
我的应用程序最低支持版本是iOS 12。所以我想我不能使用 Task 和 URLSession.shared.data(from: url)。
1赞 workingdog support Ukraine 8/1/2022
好的,但是还有其他类型的,例如:不涉及,async/await等...并且可能在 iOS 12 中可用。根据 dosc developer.apple.com/documentation/foundation/urlsession/... 它可用 ios 7+URLSessionURLSession.shared.dataTask(...)Task
0赞 RP89 8/1/2022
感谢您的快速回复。我会尝试的。但是为什么即使有尝试和捕捉,它也会崩溃
1赞 Sulthan 8/1/2022
@RP89 如果请求以超时结束(这是网络请求的常见情况),它可能会阻塞主线程太久,系统(或用户)会杀死应用程序,因为它将无响应(冻结)。
1赞 workingdog support Ukraine 8/1/2022
@Sulthan,好点子。我的示例代码不处理错误。但是,您应该正确/彻底地处理生产代码的错误。