Gamekit и iPhone

У меня есть приложение, настроенное для отправки настраиваемого уровня в виде массива другому человеку во время соединения p2p. Принимающее устройство сохраняет массив в файл для дальнейшего использования. Я настроил в своем приложении gamekit, он без проблем будет искать и подключаться к другому устройству. Хотя проблема возникает, когда я отправляю данные на устройство, принимающее устройство получит данные (и сохранит настраиваемый уровень, как и должно), но сразу же выйдет из строя послесловие.

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

-(void) sendDataToPeers:(NSData *) data
{
    if (currentSession) 
    {
        //send the data
        [self.currentSession sendDataToAllPeers:data withDataMode:GKSendDataReliable error:nil];   

        //Alerting the user that the custom level has been sent.
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Sent!" message:@"Your custom level has been sent." delegate:self cancelButtonTitle:@"Close" otherButtonTitles:nil];
        [alert show];
        [alert release];
    }
}

-(void) btnSend
{
    //Data that will be sent
    NSMutableData *theData = [NSMutableData data];

    //Archiver
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:theData];

    //Desired level to send
    int theLevel =[[CTManager sharedInstance]getLevel];

    //Path to the custom levels
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory=[paths objectAtIndex:0];
    NSString *customLevelsSen = [documentsDirectory stringByAppendingPathComponent: [NSString stringWithFormat:@"customLevels"]];

    //Custom levels array
    NSArray *theLevels = [[NSArray alloc] initWithContentsOfFile: customLevelsSen];

    //Gets the desired level array from array of custom levels
    NSArray *myArray = [[NSArray alloc]initWithArray:[theLevels objectAtIndex:theLevel-51]];

    //prepare data
    [archiver encodeObject:myArray forKey:@"level"];
    [archiver finishEncoding];

    //send the data
    [self sendDataToPeers:theData];

    //cleanup
    [archiver release];
    [theLevels release];
    [myArray release];

}

-(void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession:(GKSession *)session context:(void *)context 
{   
    //Archiver
    NSKeyedUnarchiver *archiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];

    //Gets the custom level in form of an array from data.
    NSArray *level = [archiver decodeObjectForKey:@"level"];
    [archiver finishDecoding];
    [archiver release];

    //Path to the array of custom levels
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory=[paths objectAtIndex:0];
    NSString *customLevelsRec = [documentsDirectory stringByAppendingPathComponent: [NSString stringWithFormat:@"customLevels"]];

    //Gets the array of custom levels
    NSMutableArray *customLevelArray = [[NSMutableArray alloc] initWithContentsOfFile:customLevelsRec];

    //Adds a new array to the array of custom levels
    [customLevelArray addObject:level];

    //Saves the array.
    [customLevelArray writeToFile:customLevelsRec atomically:YES];

    //cleanup
    [customLevelArray release];

    //Message saying a custom level has been recieved
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Received!" message:@"A custom level has been saved." delegate:self cancelButtonTitle:@"Close" otherButtonTitles:nil];
    [alert show];
    [alert release];

}

Тестировать это было непросто, так как в настоящее время у меня нет двух собственных устройств, поэтому я отправляю бета-версию своему другу, который проводит их тесты (у него есть ipod и iphone). Любая помощь с этим приветствуется ...

Если я не могу найти проблему, я, скорее всего, отправлю ему весь проект xcode и через совместное использование экрана поработаю с проектом на его компьютере, чтобы эффективно построить и протестировать приложение. И я смогу использовать режим отладки.


person avizzini    schedule 15.02.2010    source источник


Ответы (3)


Не знаю, находили ли вы когда-нибудь ответ на этот вопрос или нет, надеюсь, что нашли. Но если вы этого не сделали, я настоятельно рекомендую вам попробовать новые функции нового SDK. Вместо того, чтобы проходить весь процесс кодирования / декодирования, они упростили его, заставив вас сделать следующее (в своей методологии отправки):

data = [NSKeyedArchiver archivedDataWithRootObject:anObject];

где anObject может быть практически любым объектом, массивом, словарем, чем угодно ...

В вашей методологии приема:

NSObject *object = [NSKeyedUnarchiver unarchiveObjectWithData:data];

где объект также может быть практически любым объектом.

Что касается сбоя, с которым вы столкнулись, проверили ли вы, в какой строке происходит сбой? Вы уверены, что это происходит в опубликованном вами коде? Или это происходит где-то еще?

person EmphaticArmPump    schedule 12.04.2011

Я не вижу ничего плохого в вашем методе receiveData.

Вы проверили, существует ли папка, в которой вы пытаетесь сохранить данные (customLevels)?

Мне удалось подключиться через приложение, использующее GameKit, устройство и симулятор iPhone. Это действительно удобно для отладки.
Я не проверял, через Bluetooth или Wi-Fi.

person Guillaume    schedule 15.02.2010
comment
Этот файл создается при установке приложения. Файл сохраняется на принимающем устройстве, но после этого происходит сбой. Как только вы перезапустите приложение, файл будет там. Немного назад я взял основные части метода отправки и получения и поместил их в одну функцию (для целей тестирования), которая будет вызываться каждый раз, когда я нажимаю кнопку отправки. Таким образом, я мог проверить свою логику только на одном устройстве, метод тестирования успешно работал, просто дублируя уровень. Он заархивировал данные, затем разархивировал данные и поместил их в файл customLevels на том же устройстве. - person avizzini; 15.02.2010
comment
Мне удалось подключиться через приложение, использующее GameKit, устройство и симулятор iPhone. Это действительно ручная отладка. Я не проверял, было ли это через Bluetooth или Wi-Fi. Я слышал, что вы можете сделать это с помощью Wi-Fi, но если это был Bluetooth, вы можете объяснить, как вы это сделали? - person avizzini; 15.02.2010
comment
Я наконец проверил, и не смог заставить его работать через Bluetooth. Простите за ложную надежду. При использовании Wi-Fi работает очень хорошо. (Я подключаюсь к sessionMode: GKSessionModePeer) - person Guillaume; 18.02.2010
comment
Когда вы сохраняете массив в файл, каково возвращаемое значение ‹code› - writeToFile: атомарно: ‹/code›? Делегатом вашего UIAlertView является self. Вы реализовали методы делегирования протокола UIAlertViewDelegate? - person Guillaume; 18.02.2010

person    schedule
comment
Спасибо за участие! Обычно мы считаем хорошим ответом тот, который объясняет, как и почему работает код. Пожалуйста, отредактируйте свой пост, чтобы он стал еще лучше. - person Mick MacCallum; 22.09.2012