可达性和国际漫游

时间:2012-10-17 01:25:33

标签: ios cocoa-touch protocol-buffers mapkit pbrequester

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

控制台

在我对此错误的研究中,我发现 PBRequester ProtocolBuffer

  

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 =国际漫游目前已关闭。} < / p>

实施例

-(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 个答案:

答案 0 :(得分:2)

好的 - 这不是一个答案,但可能会指出你正确的方向。首先,我找不到似乎允许你这样做的Objective C类(例如NSURLRequest Class)。

我认为您需要直接转到CFNetwork Framework (CFNetwork Framework Reference),因为查看CFNetworkError代码会有这些诱人的条目(与您的错误消息相符):

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

不幸的是,我不知道CFNetwork Framework,尽管查看了Apple文档,但我并不清楚哪些CFNetwork Framework API使用这些值。但我确信会有办法。

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

  1. 使用CFHost(并获取回调以查询错误代码)
  2. 使用CFNetDiagnosticCopyNetworkStatusPassively(并解析返回的字符串)。
  3. 如果那里有专家,我很乐意看到真正的答案。

答案 1 :(得分: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

答案 2 :(得分:0)

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

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

否则,如果没有互联网连接,你会得到kCFURLErrorNotConnectedToInternet,并且在特殊情况下会有3G连接但不允许数据漫游(如美国其他国家的电话),你会得到kCFURLErrorInternationalRoamingOff。还有kCFURLErrorCallIsActive,你可以在通话时使用3G。

答案 3 :(得分:-1)

我这样做是为了检查漫游(这不是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. 每次你需要检查currentCarrier和你在第一次启动应用程序时保存的那个,如果名称不同,那么用户就是在漫游。