Подтвердить что ты не робот

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

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

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

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

Есть ли другой способ программно проверить, включен ли Bluetooth? Является ли это чем-то, что я должен использовать для достижения достижимости? Или это просто ошибка, которую 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.

4b9b3361

Ответ 1

Теперь в 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. В противном случае, если он обнаружит периферию, он вызовет соответствующий метод делегирования, но если в этой реализации нет ничего, вам не нужно об этом беспокоиться.

Ответ 2

Я согласен с Мартином Гордоном, но обходным решением может быть использование достижимость Apple.

Ответ 3

Интересный момент, вы пробовали тестировать его с помощью Bluetooth OFF и WiFi ON? Недавно я узнал, что хотя моя программа вызывала это сообщение "Bluetooth Unavailable", на самом деле он не использовал Bluetooth AT ALL, а подключался через мою сеть WiFi. Я не знаю, как заставить GKSession подключиться к Bluetooth без использования объекта Apple PeerPicker, но объект PeerPicker позволяет людям создавать свои собственные интерфейсы. То, что, по-видимому, не разрешает, это типы подключения, отличные от Peer, поэтому, если вы хотите, чтобы клиентская/серверная система не помогала.

-Ash

Ответ 4

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

Ответ 5

Во-вторых, понятие использования достижимости Apple. В качестве бонуса он указан в качестве одного из инструкций по представлению Apple App Store.

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

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

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

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

Ответ 6

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