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

3 ответа

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

data = [NSKeyedArchiver archivedDataWithRootObject:anObject];

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

В вашей методологии получения:

NSObject *object = [NSKeyedUnarchiver unarchiveObjectWithData:data];

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

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

NSData* data = [@"TEXT" dataUsingEncoding:NSUTF8StringEncoding];

NSError *error = nil;
    [self.session sendData:data toPeers:peerID withDataMode:GKSendDataReliable error:&error];



(void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession:(GKSession *)session context:(void *)context {

   NSString* message = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];//@"TEXT"

   NSString* nameOfTheTransmitter = [session displayNameForPeer:peer];// name who sent

}

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

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

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

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