Как правильно настроить GKSession (Bluetooth) на iOS 6.1
У меня проблема с тем, чтобы заставить GKSession работать. Ниже мой код, который выполняется при нажатии определенной кнопки.
GKSession *session;
if (connectButtonHasBeenPressed == false) {
NSLog(@"connectToBluetoothDevice has been called");
connectButtonHasBeenPressed = true;
GKSession *session = [[GKSession alloc] initWithSessionID:@"Unicorn" displayName:nil sessionMode:GKSessionModePeer];
[session setDataReceiveHandler:self withContext:nil];
[session setDelegate:self];
[session setAvailable:YES];
NSLog(@"Session ID: %@", [session sessionID]);
NSLog(@"Currently Available Peers: %i", [[session peersWithConnectionState:GKPeerStateAvailable] count]);
if ([session isAvailable]) {
NSLog(@"The Session Is Available");
}
[connectToDeviceButton setTitle:@"Searching..." forState:UIControlStateNormal];
}
else {
NSLog(@"Currently Available Peers: %i", [[session peersWithConnectionState:GKPeerStateAvailable] count]);
}
После первого нажатия кнопки все работает нормально. И каждый раз, когда я нажимаю кнопку после этого, она печатает "В настоящее время доступно пиров: 0". Это было бы ожидаемым результатом, если бы у меня не было двух устройств, сидящих рядом друг с другом, запустив программу с нажатой кнопкой. У меня также есть все методы GKSessionDelegate, реализованные в этом классе, которые все записывают сообщение на консоль. Ни один из этих методов никогда не запускается. Все это указывает на то, что устройства не могут найти друг друга.
Тем не менее, я запустил пример программы GKRocket, которая использует GKSession для соединения двух устройств, и она отлично работает между этими двумя устройствами. Я сравнил код GKRocket с кодом моей программы, и я не нашел никаких отличий, которые, как мне кажется, могли бы повлиять на GKSession.
Какие-либо предложения?
1 ответ
Кажется, у вас есть два экземпляра GKSession. Один снаружи, а другой внутри if
заявление.
Это означает, что если connectButtonHasBeenPressed
является false
он создаст свою собственную версию GKSession, которую он хранит. но если это true
затем session
будет равно nil
,
Также я бы порекомендовал использовать nil
в качестве идентификатора сеанса, поскольку он устанавливается для вас с помощью идентификатора пакета. Хотя это может быть личным предпочтением.
Попробуйте использовать что-то вроде этого:
if (session == nil)
{
NSLog(@"connectToBluetoothDevice has been called");
session = [[GKSession alloc] initWithSessionID:nil displayName:nil sessionMode:GKSessionModePeer];
[session setDataReceiveHandler:self withContext:nil];
[session setDelegate:self];
[session setAvailable:YES];
NSLog(@"Session ID: %@", [session sessionID]);
if ([session isAvailable])
{
NSLog(@"The Session Is Available");
}
[connectToDeviceButton setTitle:@"Searching..." forState:UIControlStateNormal];
connectButtonHasBeenPressed = true;
}
NSLog(@"Currently Available Peers: %i", [[session peersWithConnectionState:GKPeerStateAvailable] count]);
Вам не нужно иметь connectButtonHasBeenPressed
переменная, так как вы можете просто проверить, равен ли GKSession nil, что всегда должно быть, если нет соединения. Когда ваша сессия заканчивается, вы всегда должны отменить все действия сессии и установить session = nil;
,
session
переменная действительно должна быть объявлена в вашем.h файле, чтобы вы могли использовать ее во всем классе. Чтобы GKSession *session;
больше не нужен.
Примечание: просто записка от вашего connectToBluetoothDevice has been called
журнал. По моему опыту, GKSession будет использовать WiFi или Bluetooth, в зависимости от того, что доступно. Настолько, что вы можете иметь 3 устройства, 1 с включенным только Bluetooth, 1 с включенным только WiFi и последнее с обоими, и все они будут подключаться и разговаривать друг с другом абсолютно нормально.
Надеюсь это поможет.
Редактировать: удалены ненужные connectButtonHasBeenPressed
переменная из примера кода и добавил больше объяснений.