iOS 是否可以在未经许可的情况下获取用户的大概位置?

Emr*_*ran 3 location objective-c ios swift

您建议如何在未经用户许可的情况下获取用户所在国家/地区?是否可以使用手机信号塔三角测量或 WiFi 定位来获得大概位置?您建议使用什么其他方法来猜测用户所在的国家/地区?

Eru*_*aru 7

来自苹果的文档

\n\n
\n

重要提示:除了硬件不可用之外,用户还可以选择拒绝应用程序访问位置服务数据。在应用程序首次使用期间,核心位置框架会提示用户确认使用位置服务是可接受的。如果用户拒绝该请求,则 CLLocationManager\n 对象会在以后的请求期间向其委托报告相应的错误。您还可以使用authorizationStatus 方法检查应用程序\xe2\x80\x99s 显式授权\n 状态。

\n
\n\n

因此,即使存在一些棘手的方法来避免许可,您也会在审核阶段被拒绝。

\n\n
\n\n
\n

您建议使用什么其他方法来猜测用户所在的国家/地区?

\n
\n\n

您可以使用 IP 地址获取此信息。

\n\n
\n\n

Swift 4 - 获取设备的 IP 地址:

\n\n

添加 #include<ifaddrs.h>您的桥接标头。

\n\n

这是获取IP地址所需的框架。

\n\n
class func getIPAddress() -> String? {\n        var address: String?\n        var ifaddr: UnsafeMutablePointer<ifaddrs>? = nil\n        if getifaddrs(&ifaddr) == 0 {\n            var ptr = ifaddr\n            while ptr != nil {\n                defer { ptr = ptr?.pointee.ifa_next }\n\n                let interface = ptr?.pointee\n                let addrFamily = interface?.ifa_addr.pointee.sa_family\n                if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) {\n\n                    if let name: String = String(cString: (interface?.ifa_name)!), name == "en0" {\n                        var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))\n                        getnameinfo(interface?.ifa_addr, socklen_t((interface?.ifa_addr.pointee.sa_len)!), &hostname, socklen_t(hostname.count), nil, socklen_t(0), NI_NUMERICHOST)\n                        address = String(cString: hostname)\n                    }\n                }\n            }\n            freeifaddrs(ifaddr)\n        }\n        return address\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

使用 IP 地址获取国家/地区

\n\n

您可以首先尝试http://ip-api.com/json,它会返回一个 JSON,如其API 页面上所述。

\n\n

然后,您可以将此 JSON 字符串转换为字典并访问数据。

\n\n
func getIpLocation(completion: @escaping(NSDictionary?, Error?) -> Void)\n{\n    let url     = URL(string: "http://ip-api.com/json")!\n    var request = URLRequest(url: url)\n    request.httpMethod = "GET"\n\n    URLSession.shared.dataTask(with: request as URLRequest, completionHandler:\n    { (data, response, error) in\n        DispatchQueue.main.async\n        {\n            if let content = data\n            {\n                do\n                {\n                    if let object = try JSONSerialization.jsonObject(with: content, options: .allowFragments) as? NSDictionary\n                    {\n                        completion(object, error)\n                    }\n                    else\n                    {\n                        // TODO: Create custom error.\n                        completion(nil, nil)\n                    }\n                }\n                catch\n                {\n                    // TODO: Create custom error.\n                    completion(nil, nil)\n                }\n            }\n            else\n            {\n                completion(nil, error)\n            }\n        }\n    }).resume()\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

此函数返回字典或错误(在解决 TODO 之后)。completion假设您将使用结果来更新 UI,则在主线程上调用该函数。如果没有,您可以删除DispatchQueue.main.async { }.

\n