GKSession - что если у меня отключены Bluetooth и Wi-Fi?

Я работаю над приложением для iPhone, которое разрешит одноранговые соединения. Из того, что я понимаю, у меня есть выбор между использованием GKPeerPicker или GKSession. Мне не нравится идея использования PeerPicker, потому что я хочу показать пользовательский интерфейс, поэтому я решил использовать GKSession, и эй, BONUS в том, что он также работает через Wi-Fi, а Peer Picker - нет.

Итак, проблема в том... что если у пользователя отключены Bluetooth и Wi-Fi? В Peer Picker есть приглашение включить Bluetooth без выхода из приложения. В GKSession его нет... но, подождите секунду, кажется, что я даже не могу проверить, включен ли Bluetooth программно или нет!

Carpe Cocoa не требует никаких проблем, просто используйте делегат session:didFailWithError: метод. Но, как это объясняется в комментариях... это больше не работает! И по своему опыту я согласен.

Есть ли другой способ программно проверить, включен ли Bluetooth? Это то, что я должен использовать Reachability для? Или это просто ошибка, которую Apple еще не исправила?

Чтобы быть более конкретным, я создаю свою сессию так:

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, и я знаю, что он работает, потому что когда у меня включен bluetooth, методы делегата не вызывают проблем. Я реализовал их так:

#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);
}

Ни одна из инструкций журнала не распечатывается, и я устанавливаю точки останова в каждом методе, но ни одна из них не срабатывает, когда у пользователя отключены Bluetooth и Wi-Fi. Я надеялся, что что-то произойдет, чтобы вызвать сеанс:didFailWithError: так, чтобы я мог предложить пользователю включить Bluetooth или подключиться к сети Wi-Fi.

6 ответов

Теперь в 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];

Для этого необходимо импортировать инфраструктуру CoreBluetooth в iOS 5. Если Bluetooth отключен, в системе появится окно с предупреждением, в котором будет предложено включить Bluetooth. В противном случае, если он найдет периферийное устройство, он вызовет соответствующий метод делегата, но если в этой реализации ничего нет, вам не нужно об этом беспокоиться.

Я согласен с Мартином Гордоном, но обходной путь может заключаться в использовании доступности Apple.

Интересно, вы пробовали тестировать его с выключенным Bluetooth и включенным WiFi? Недавно я обнаружил, что, хотя моя программа назвала это сообщение "Bluetooth недоступен", на самом деле он не использовал Bluetooth ВСЕ, а подключался через мою сеть WiFi. Я не знаю способа заставить GKSession подключиться к Bluetooth без использования объекта Apple PeerPicker, но объект PeerPicker позволяет людям создавать свои собственные интерфейсы. Кажется, что он не позволяет использовать типы соединений, отличные от Peer, поэтому, если вы хотите, чтобы клиент-серверное расположение было не слишком полезным.

-Ash

Вы можете включить Blutooth программно, используя частный API Apple (я думаю, BluetoothManger.h), но будьте осторожны, это приведет к отклонению в Apple App Store.

Я поддерживаю идею использования доступности Apple. В качестве бонуса он указан в качестве одного из правил подачи заявок в Apple App Store.

Это не так сложно реализовать, так как большая часть необходимого кода уже написана для вас.

Slf предоставил ссылку на некоторый исходный код, используя класс Reachability, кроме того, вот ссылка на официальный пример достижимости Apple Dev.

Однако убедитесь, что вы проверяете возможность подключения асинхронно.

Я использую его в своем приложении, и хотя это не лучшее решение, по крайней мере, оно уведомляет пользователя о том, что ему / ей нужно настроить параметры соединения или что сети не существует.

Вы должны использовать то же самое sessionID,

Другие вопросы по тегам