【问题标题】:Is it possible to get user approximate location without permission in iOS?是否可以在未经 iOS 许可的情况下获取用户大致位置?
【发布时间】:2020-04-08 16:33:33
【问题描述】:

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

【问题讨论】:

  • 我已经更新了我的答案,这可能会对你有所帮助。

标签: ios objective-c swift location


【解决方案1】:

来自苹果的文档

重要提示:除了硬件不可用外,用户还有 拒绝应用程序访问位置服务的选项 数据。在应用程序的初始使用期间,核心位置 框架提示用户确认使用位置服务 是可以接受的。如果用户拒绝该请求,则 CLLocationManager 对象在未来向其委托报告适当的错误 要求。您还可以检查应用程序的显式授权 使用 authorizationStatus 方法的状态。

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


你有什么其他的方法来猜测用户是哪个国家的 位于?

您可以通过使用 ip 地址获取此信息。


Swift 4 - Get device's IP Address:

在您的桥接头中添加#include<ifaddrs.h>

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

class func getIPAddress() -> String? {
        var address: String?
        var ifaddr: UnsafeMutablePointer<ifaddrs>? = nil
        if getifaddrs(&ifaddr) == 0 {
            var ptr = ifaddr
            while ptr != nil {
                defer { ptr = ptr?.pointee.ifa_next }

                let interface = ptr?.pointee
                let addrFamily = interface?.ifa_addr.pointee.sa_family
                if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) {

                    if let name: String = String(cString: (interface?.ifa_name)!), name == "en0" {
                        var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
                        getnameinfo(interface?.ifa_addr, socklen_t((interface?.ifa_addr.pointee.sa_len)!), &hostname, socklen_t(hostname.count), nil, socklen_t(0), NI_NUMERICHOST)
                        address = String(cString: hostname)
                    }
                }
            }
            freeifaddrs(ifaddr)
        }
        return address
}

Get country using ip address

您可以先尝试 http://ip-api.com/json,它会返回一个 JSON,如 on their API page 所述。

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

func getIpLocation(completion: @escaping(NSDictionary?, Error?) -> Void)
{
    let url     = URL(string: "http://ip-api.com/json")!
    var request = URLRequest(url: url)
    request.httpMethod = "GET"

    URLSession.shared.dataTask(with: request as URLRequest, completionHandler:
    { (data, response, error) in
        DispatchQueue.main.async
        {
            if let content = data
            {
                do
                {
                    if let object = try JSONSerialization.jsonObject(with: content, options: .allowFragments) as? NSDictionary
                    {
                        completion(object, error)
                    }
                    else
                    {
                        // TODO: Create custom error.
                        completion(nil, nil)
                    }
                }
                catch
                {
                    // TODO: Create custom error.
                    completion(nil, nil)
                }
            }
            else
            {
                completion(nil, error)
            }
        }
    }).resume()
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多