Game Center-отправка и получение данных

изменить: Я сделал чистый, новый проект, но все еще не могу заставить его работать. Пожалуйста, скачайте его, есть немного кода, чтобы посмотреть и, вероятно, легко для профессионала или любого удаленного опыта, чтобы увидеть, что я делаю неправильно. Просто пытаюсь отправить это целое число.

http://www.2shared.com/file/fPOCLlg5/gkTest.html

Привет

Я пытаюсь реализовать Game Center multiplayer в своей игре iphone и не могу понять образцы, которые я имею под рукой в документах Apple и от третьих лиц относительно отправки и получения данных.

может кто-нибудь объяснить образцы кода в официальных документах Apple здесь, пожалуйста: http://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/GameKit_Guide/MatchesandVoice/MatchesandVoice.html#//apple_ref/doc/uid/TP40008304-CH10-SW4

или помогите мне выяснить этот пример кода, который мне был предоставлен. Его сборный класс, сделано для обработки всех задач game center и образец из него для отправки и получения данных будет следующим:

- (void) sendPosition
{
    NSError *error;
    PositionPacket msg;
    msg.messageKind = PositionMessage;
    msg.x = currentPosition.x;
    msg.y = currentPosition.y;
    NSData *packet = [NSData dataWithBytes:&msg length:sizeof(PositionPacket)];
    [match sendDataToAllPlayers: packet withDataMode: GKMatchSendDataUnreliable error:&error];
    if (error != nil)
    {
        // handle the error
    }
}

и прием:

- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID
{
    Packet *p = (Packet*)[data bytes];
    if (p.messageKind == PositionMessage)
        // handle a position message.
}

мой большой вопрос об этой форме кода официальные документы:

где PositionPacket/Packet откуда? И предполагая, когда вы хотите отправлять / получать данные, вы называете их так:

[self sendPosition];

или

[self match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID];

что я могу ввести как матч, данные и playerID?

Е. Г. Я int с именем "score", но нет ли специального ключа, который мне нужно использовать?

1 ответов


в этом примере PositionPacket-это просто структура. Следующая строка помещает эту структуру в NSData, которая является просто объектом "Byte bucket".

NSData *packet = [NSData dataWithBytes: &msg length: sizeof(PositionPacket)];

поэтому, если вы просто хотите отправить оценку int, у вас может быть метод sendScore, который выглядел так:

- (void) sendScore
{
    NSError *error;
    int myScore = self.score;
    NSData *packet = [NSData dataWithBytes:&myScore length:sizeof(myScore)];
    [match sendDataToAllPlayers: packet withDataMode: GKMatchSendDataUnreliable error: &error];
    if (error != nil)
    {
        // handle the error
    }
}

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

msg.messageKind = PositionMessage;

В общем, вы можете отправить все, что хотите инкапсулировать в объект NSData, так как это просто байтовое ведро. Вы можете отправлять примитивные типы, такие как ints, или структуры, как в Примере, или даже NSObjects (если они реализуют NSCoding). Вы должны прочитать о NSKeyedArchiver, NSCoding и NSData для получения дополнительной информации о отправке и получении NSObjects таким образом. Вот справочный документ Apple на Archving.

как для получая, вы не вызываете метод,он вызывает вас набором. Это то, что называется "методом делегирования" (на языке какао) или "методом обратного вызова"."Вы можете думать об этом как о "телефонном звонке", который ваше приложение может принимать асинхронно. Путем реализации метода с подписью:

- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID;

...вы говорите: "Я могу принять такой телефонный звонок."Поэтому, когда GameKit получает данные от вашего имени от другого игрока, он увидит, что вы хотите получить обратные вызовы этого вид и затем вызовет этот метод - тогда это зависит от вас, чтобы обновить внутреннее состояние приложения на основе того, что получено.

чтобы продолжить этот пример, если вы отправили простое сообщение "ничего, кроме целого числа", описанное выше, вы можете реализовать этот метод следующим образом:

- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID
{
    int* receivedScorePtr = (int*)[data bytes];
    int receivedScore = *receivedScorePtr;
    [self updateScore: received forPlayer: playerID];
}

это, конечно, при условии, что у вас есть метод updateScore:forPlayer: который обновит таблицу баллов.

вы можете найти более общие обсуждение / объяснение того, как делегаты и методы делегатов работают в этой записи блога:http://mohrt.blogspot.com/2010/01/cocoa-and-delegates.html

добавлено: используя код, опубликованный asker, я сделал несколько изменений и создал версию, которая "работает" для этого случая использования голых костей. рабочая версия тестового приложения для отправки одного целого числа через GameCenter Я не делаю никаких заявлений о качестве кода или его пригодности для, ну, все, что угодно. Я не писал 99,9% этого - пожалуйста, не принимайте мою публикацию здесь как одобрение чего-либо, что появляется в нем.

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