11

我正在开发一个允许点对点连接的 iPhone 应用程序。据我了解,我可以选择使用 GKPeerPicker 或 GKSession。我不喜欢使用 PeerPicker 的想法,因为我想显示一个自定义界面,所以我决定使用 GKSession,嘿,好处是它也可以通过 Wi-Fi 工作,而 Peer Picker 不能。

好的,所以问题是……如果用户同时关闭了蓝牙和 Wi-Fi 怎么办?在 Peer Picker 中,会提示您在不离开应用程序的情况下打开蓝牙。GKSession 没有它......但是哇等一下,我什至无法检查蓝牙是否以编程方式打开!

Carpe Cocoa声称没有问题,只需使用Delegate的session:didFailWithError:方法即可。但是,正如评论中解释的那样……这似乎不再起作用了!根据我的经验,我同意。

有没有其他方法可以以编程方式检查蓝牙是否打开?这是我应该利用可达性的东西吗?还是只是苹果尚未修复的错误?

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

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 时,它们都不会被命中。我希望会发生一些事情来触发 session:didFailWithError: 以便我可以提示用户打开蓝牙或连接到 Wi-Fi 网络。

4

6 回答 6

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 框架。如果蓝牙关闭,系统会弹出一个警报视图,提供打开蓝牙的选择。否则,如果它找到外围设备,它将调用相应的委托方法,但如果该实现中没有任何内容,则无需担心。

于 2012-08-10T19:16:11.203 回答
1

我同意 Martin Gordon 的观点,但一种解决方法可能是使用Apple 的 reachability

于 2010-03-02T14:35:18.543 回答
1

有趣的是,您是否尝试过在关闭蓝牙和打开 WiFi 的情况下对其进行测试?我最近发现,虽然我的程序调用了这个“蓝牙不可用”消息,但实际上它根本没有使用蓝牙,而是通过我的 WiFi 网络连接。我不知道在不使用 Apple 的 PeerPicker 对象的情况下强制 GKSession 进入蓝牙连接的方法,但是 PeerPicker 对象确实允许人们制作自己的接口。它似乎不允许的是 Peer 以外的连接类型,所以如果你想要一个客户端/服务器安排,它不会有太大帮助。

-灰

于 2010-10-07T11:01:27.597 回答
0

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

于 2011-08-10T07:16:15.933 回答
0

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

由于已经为您编写了所需的大部分代码,因此实现起来并不难。

Slf ​​提供了使用 Reachability 类的一些源代码的链接,另外这里是Apple Dev 的官方可达性示例的链接。

但是,请确保您正在异步检查可连接性。

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

于 2011-09-21T18:44:42.683 回答
-1

您应该使用相同的sessionID.

于 2011-08-18T12:03:13.387 回答