2

我正在使用ReachabilityApple 的课程来确定数据或 wifi 是否可用。但是,一位用户(使用美国 iPhone)正在另一个国家/地区测试该应用程序,他在尝试访问 MapKit 时看到以下错误。

安慰

在我对这个错误的研究中,我发现那PBRequesterProtocolBuffer

2012-10-15 21:16:00.921 WrightsCS App[24239:907] PBRequester 失败,错误域=kCFErrorDomainCFNetwork 代码=-1018“国际漫游当前已关闭。” UserInfo=0x1e5587d0 {NSErrorFailingURLKey=https://gsp13-cn.ls.apple.com/shift, NSErrorFailingURLStringKey=https://gsp13-cn.ls.apple.com/shift, NSLocalizedDescription=国际漫游目前已关闭。}

例子

-(BOOL)hasDataConnection
{
    Reachability *networkReachability = [Reachability reachabilityForInternetConnection];
    NetworkStatus networkStatus = [networkReachability currentReachabilityStatus];

    if ( networkStatus == NotReachable )
    {
        return NO;
    }
    else
    {
        if ( ! [Reachability reachabilityWithHostName:@"www.google.com"] )
            return NO;

        return YES;
    }
}

问题

我们如何检测用户是否正在漫游,或者至少确保如果用户正在漫游,我们不会遇到此错误?

4

4 回答 4

2

好的 - 这不是答案,但可能会为您指明正确的方向。首先,我找不到似乎可以让您执行此操作的Objective C 类(例如NSURLRequestClass)。

我认为您需要直接访问 CFNetwork 框架(CFNetwork 框架参考),因为查看 CFNetworkError 代码有这些诱人的条目(与您的错误消息相匹配):

kCFURLErrorNotConnectedToInternet  = -1009,
kCFURLErrorInternationalRoamingOff = -1018,
kCFURLErrorDataNotAllowed          = -1020,

不幸的是,我不知道 CFNetwork 框架,尽管查看了 Apple 文档,但我并不知道哪个 CFNetwork 框架 API 使用这些值。但我相信总会有办法的。

我的两个“想法”(我松散地使用这个词):

  1. 使用CFHost(并获取回调以查询错误代码)
  2. 使用CFNetDiagnosticCopyNetworkStatusPassively(并解析返回的字符串)。

如果那里有专家,我很想看到真正的答案。

于 2012-10-17T03:29:27.063 回答
1

您可以使用http://ipinfo.io (我自己的服务)之类的第三方服务,根据设备的IP地址查找偶数运营商代码的当前国家/地区。然后,您可以将其与CTCarrier详细信息进行比较,以确定设备是否正在漫游。这是标准的 ipinfo.io API 响应:

$ curl ipinfo.io/24.32.148.1 
{
    "ip": "24.32.148.1",
    "hostname": "doc-24-32-148-1.pecos.tx.cebridge.net",
    "city": "Pecos",
    "region": "Texas",
    "country": "US",
    "loc": "31.3086,-103.5892",
    "org": "AS7018 AT&T Services, Inc.",
    "postal": "79772"
}

可以使用自定义包,其中还包括移动 IP 的 mnc/mcc 详细信息。有关详细信息,请参阅http://ipinfo.io/developers

于 2014-08-10T03:25:49.653 回答
1

Apple 实际上建议您在可以避免的情况下不要使用 Reachability,而只需拨打电话并检查结果即可。在通话之前,您可以将allowsCellularAccess 设置为NO,以避免昂贵的3G 连接。

显然你会得到错误。在可以使用 3G 但不允许使用 3G 且没有 WiFi 的特殊情况下,您会得到 kCFURLErrorDataNotAllowed。然后,您可能会询问用户是否允许您进行 3G 连接。

否则,如果没有 Internet 连接,您将得到 kCFURLErrorNotConnectedToInternet,并且在有 3G 连接但不允许数据漫游的特殊情况下(如美国电话在另一个国家/地区),您会得到 kCFURLErrorInternationalRoamingOff。还有 kCFURLErrorCallIsActive ,您可以在通话时使用无法使用 3G 的电话。

于 2015-05-14T16:45:50.723 回答
-2

我这样做是为了检查漫游(这不是 100% 完整的证明,但是..):

1.当用户第一次加载应用程序时,将运营商网络保存到用户默认值中:

CTTelephonyNetworkInfo *netinfo = [[CTTelephonyNetworkInfo alloc] init];
CTCarrier *carrier = [netinfo subscriberCellularProvider];
NSString *name = [[carrier carrierName] copy];
NSLog(@"Carrier Name: %@", name);

NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
self.homeNetwork = [standardUserDefaults objectForKey:SNAP_homeNetwork];
if(self.homeNetwork == nil || self.homeNetwork.length == 0){
    self.homeNetwork = [[Globals sharedInstance] getCarrier];
    [standardUserDefaults setObject:self.homeNetwork forKey:SNAP_homeNetwork];
    [standardUserDefaults synchronize];
}
  1. 每次您需要检查当前运营商与您在第一次启动应用程序时保存的运营商,如果名称不同,则用户正在漫游。
于 2013-08-20T20:17:55.170 回答