GCKSession - 如果我关闭蓝牙和Wifi怎么办?

时间:2010-02-20 23:36:42

标签: iphone bluetooth wifi p2p gksession

我正在开发一款允许点对点连接的iPhone应用程序。据我所知,我可以选择使用GKPeerPicker还是GKSession。我不喜欢使用PeerPicker的想法,因为我想显示一个自定义界面,所以我决定使用GKSession,嘿,BONUS是它也适用于Wi-Fi,而Peer Picker则没有。 / p>

好的,问题是......如果用户同时关闭了蓝牙和Wi-Fi怎么办?在Peer Picker中,有一个提示在没有离开应用程序的情况下打开蓝牙。 GKSession没有它......但是等待一秒钟,似乎我甚至无法检查蓝牙是否打开了!

Carpe Cocoa claims no problem,只需使用代理的session:didFailWithError:方法即可。但是,正如它在评论中所解释的那样......似乎不再起作用了!根据我的经验,我同意。

是否有其他方法可以通过编程方式检查蓝牙是否已开启?这是我应该利用Reachability的东西吗?或者它只是苹果尚未修复的错误?

更具体地说,我正在创建我的会话:

GKSession *aSession = [[GKSession alloc] initWithSessionID:nil
                                                  displayName:user.displayName 
                                                  sessionMode:GKSessionModePeer];

self.gkSession = aSession;
[aSession release];

self.gkSession.delegate = self;
self.gkSession.available = YES;

[self.gkSession setDataReceiveHandler:self withContext:NULL];

该类实现了GKSessionDelegate,我知道它正在工作,因为当我打开蓝牙时,委托方法被称为没有问题。我已经实现了它们:

#pragma mark -
#pragma mark GKSessionDelegate methods

- (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state {
     if (GKPeerStateAvailable == state) {
          [session connectToPeer:peerID withTimeout:10];
     } else if (GKPeerStateConnected == state) {
          // gets user

          NSError *error = nil;
          [session sendData:user.connectionData
                      toPeers:[NSArray arrayWithObjects:peerID,nil]
                withDataMode:GKSendDataReliable error:&error];
          if (error)
               NSLog(@"%@",error);
     }
}



- (void)session:(GKSession *)session didReceiveConnectionRequestFromPeer:(NSString *)peerID {
     NSError *error = nil;
     [session acceptConnectionFromPeer:peerID error:&error];
     if (error)
          NSLog(@"%@",error);
}

- (void)session:(GKSession *)session connectionWithPeerFailed:(NSString *)peerID withError:(NSError *)error {
     NSLog(@"%@",error);
}

- (void)session:(GKSession *)session didFailWithError:(NSError *)error {
     NSLog(@"%@",error);
}

没有打印任何日志语句,我在每种方法中都设置了断点,但当用户同时关闭了蓝牙和Wi-Fi时,都没有触发。我希望触发会话会发生一些事情:didFailWithError:这样我就可以提示用户打开蓝牙或连接到Wi-Fi网络。

6 个答案:

答案 0 :(得分:2)

现在在iOS 5中,可以这样实现:

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:FALSE], CBCentralManagerScanOptionAllowDuplicatesKey, nil];
NSMutableArray * discoveredPeripherals = [NSMutableArray new];
CBCentralManager * manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
[manager scanForPeripheralsWithServices:discoveredPeripherals options:options];
[manager stopScan];

这要求您在iOS 5中导入CoreBluetooth框架。如果蓝牙关闭,系统将弹出警报视图,该视图将提供打开蓝牙的选择。否则,如果找到外围设备,它将调用相应的委托方法,但如果该实现中没有任何内容,则无需担心。

答案 1 :(得分:1)

我同意Martin Gordon,但解决方法可能是使用Apple's reachability

答案 2 :(得分:1)

有趣的是,您是否尝试过蓝牙关闭和WiFi开启测试?我最近发现虽然我的程序称这是“蓝牙不可用”的消息,但它实际上并没有使用蓝牙全部,而是通过我的WiFi网络连接。我不知道如何在不使用Apple的PeerPicker对象的情况下强制GKSession进入蓝牙连接,但PeerPicker对象允许人们制作自己的界面。它似乎不允许的是除Peer之外的连接类型,因此如果您想要一个客户端/服务器安排,它将不会有太多帮助。

-Ash

答案 3 :(得分:0)

您可以使用Apple的私有API(我认为BluetoothManger.h)以编程方式打开蓝牙,但要小心,它会导致Apple App Store推送被拒绝。

答案 4 :(得分:0)

我认为使用Apple的可达性这一概念。作为奖励,它被列为Apple App Store提交指南之一。

实现起来并不难,因为已经为你编写了所需的代码。

Slf使用Reachability类提供了一些源代码的链接,另外这里是Apple Dev's official reachability example的链接。

但是,请确保以异步方式检查可连接性。

我在我的应用程序中使用它,虽然它不是最佳解决方案,但它至少会通知用户他/她需要调整连接设置或者没有网络存在。

答案 5 :(得分:-1)

您应该使用相同的sessionID