Передача любого типа данных между устройствами с многоранговым подключением

Я пытаюсь внедрить структуру многопользовательского подключения в свое приложение.

Я успешно сделал это. Я хочу, чтобы пользователь мог выбрать что-то вроде изображения из фотопленки и передать его на другое подключенное устройство. Я делаю это с другими вещами, а не только с UIImage (например, NSString, NSObject...)

В идеале я хочу иметь возможность использовать его и получать одним из двух методов:

- (void)session:(MCSession *)session didReceiveStream:(NSInputStream *)stream withName:(NSString *)streamName fromPeer:(MCPeerID *)peerID;

OR

- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID {

Однако мне нужен стандартизированный способ (для любого типа объекта) передать его на другое устройство с использованием многорангового соединения.

Моей единственной мыслью было преобразовать каждый объект в NSData, а затем передать его, однако это не работает на принимающей стороне. Мой тест:

NSData *myData = [NSKeyedArchiver archivedDataWithRootObject:self.myImage];
NSLog(@"%@", myData);

Тогда я понятия не имею, как преобразовать его обратно. Это как-то связано с NSCoding?? Любые идеи будут высоко оценены! :) Спасибо!!


person falky    schedule 25.10.2013    source источник


Ответы (2)


Похоже, у вас есть правильная идея, вам просто нужно использовать NSKeyedUnarchiver при получении данных.

- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID {

    id myObject = [NSKeyedUnarchiver unarchiveObjectWithData:data];
}

Оттуда вы можете определить, какой объект вы на самом деле получили:

if ([myObject isKindOfClass:[SomeClass class]]){

   //Handle
}

Это будет работать для любого класса, если он соответствует протоколу NSCoding. Взгляните на: Кодирование и декодирование объектов

person ChrisH    schedule 25.10.2013

Я бы предложил реализовать протокол для передачи объектов NSData между устройствами. Имейте стандартизированный пакет, который вы отправляете между устройствами. Такие как

type | length | data....

Тип и длина должны быть целыми числами, чтобы, когда они переходят на другую сторону, вы точно знали, насколько они велики. Затем длина скажет вам, какова длина вашего фактического пакета.

Простой пример

// method received "(id) data" which can be UIImage, NSString, NSDictionary, NSArray

// 1 -> Image
// 2 -> JSON
uint32_t type;

if ([data isKindOfClass:[UIImage class]]) {
   data = UIImageJPEGRepresentation((UIImage *)data, 1.0);
   type = 0;
} else {
   data = [data JSONData];
   type = 1;
}

uint32_t length = [data length];

NSMutableData *packet = [NSMutableData dataWithCapacity:length + (INT_32_LENGTH * 2)];
[packet appendBytes:&type length:INT_32_LENGTH];
[packet appendBytes:&length length:INT_32_LENGTH];
[packet appendData:data];

Затем на другом конце вы просто читаете длину пакета, проверяете тип и конвертируете обратно в правильный тип объекта. Для изображений отправляйте как двоичный пакет, а для чего-либо еще отправляйте как JSON.

Надеюсь, это поможет.

person sbarow    schedule 25.10.2013