Отправить NSArray через AirDrop

У меня есть NSMutableArray self.certificates

Этот массив состоит из сохраненных строк и основных данных. Я хочу отправить это через AirDrop. Я проверил serialization и пытаюсь отправить его со следующим

- (void)send{

NSData *jsonData2 = [NSJSONSerialization dataWithJSONObject:self.certificates options:NSJSONWritingPrettyPrinted error:nil];

NSString *jsonString = [[NSString alloc] initWithData:jsonData2 encoding:NSUTF8StringEncoding];
NSLog(@"Electrical Certificates List:\n%@", jsonString);


UIActivityViewController *activityCtr = [[UIActivityViewController alloc] initWithActivityItems:@[jsonString]
                                                                          applicationActivities:nil];

NSMutableArray *excludedActivities = [self iOSActivities].mutableCopy;
[excludedActivities addObject:UIActivityTypeAddToReadingList];
[excludedActivities addObject:UIActivityTypePostToFlickr];
[excludedActivities addObject:UIActivityTypePostToTencentWeibo];
[excludedActivities addObject:UIActivityTypePostToVimeo];
[activityCtr setExcludedActivityTypes:excludedActivities];

[self presentViewController:activityCtr
                   animated:YES
                 completion:nil];
}

Это дает мне следующую ошибку
'NSInvalidArgumentException', reason: 'Invalid type in JSON write (Certificate)'

Я преобразовал данные в строку, поэтому не уверен, что мне здесь не хватает

Я исследовал NSInvalidArgumentException, причина: "Неверный тип в записи JSON (__NSDate)" и Как отправить NSArray в веб-службу


person JSA986    schedule 31.03.2014    source источник


Ответы (1)


Исключение генерируется JSONSerialization перед преобразованием массива в данные.

Чтобы поделиться пользовательским типом данных, вам нужно реализовать NSCoding и UIActivityItemSource в объекте вашей модели:

@interface CertificateGroup : NSObject <NSCoding, UIActivityItemSource>

@property(copy, nonatomic) NSArray *certificates;

@end

@implementation CertificateGroup

- (void)encodeWithCoder:(NSCoder *)aCoder {
    // Save all your custom properties
    [aCoder encodeObject:self.certificates forKey:@"certificates"]l
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super init];
    if (self) {
        // Read back properties
        self.certificates = [aDecoder decodeObjectForKey:@"certificates"];
    }
    return self;
}

- (id)activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController
{
    //Let the activity view controller know NSData is being sent by passing this placeholder.
    return [NSData data];
}

- (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType
{
    //Serialize this object for sending. NSCoding protocol must be implemented for the serialization to occur.
    return [NSKeyedArchiver archivedDataWithRootObject:self];
}

- (NSString *)activityViewController:(UIActivityViewController *)activityViewController dataTypeIdentifierForActivityType:(NSString *)activityType {
    return @"com.mycompany.myapp.certificates";
}

@end

Затем, когда вы создаете свой контроллер представления активности:

CertificatesGroup *group = [CertificatesGroup new];
group.certificates = self.certificates;
UIActivityViewController *activityCtr = [[UIActivityViewController alloc] initWithActivityItems:@[group]
                                                                          applicationActivities:nil];
...

Вы делегат приложения должны реализовать -application:openURL:sourceApplication:annotation: и декодировать входящие сертификаты.

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
     NSData *groupData = [NSData dataWithContentsOfURL:url];
     CertificatesGroup *group = [NSKeyedUnarchiver unarchiveObjectWithData:groupData];
     NSLog(@"%@", group.certificates);
     return YES;
}

Для получения дополнительной информации см. AirDropSample, особенно APLProfile.h/.m, APLProfileViewController.h/.m и AppDelegate.m.

person Austin    schedule 31.03.2014
comment
Спасибо за ответ, это дает мне нулевую строку для archivedString - person JSA986; 01.04.2014
comment
Ах, это, вероятно, недопустимая строка. Возможно, вы сможете передать объект NSData непосредственно в контроллер представления активности. Однако я предполагаю, что вы хотите иметь возможность открывать эти данные в своем приложении на принимающем устройстве, а затем декодировать их? - person Austin; 01.04.2014
comment
Да, массив NSMutable заполняет табличное представление, я хочу отправить его на другое устройство и получить его декодирование. Просто способ вручную синхронизировать устройства, пробовал iCloud, но, похоже, вообще не работает! - person JSA986; 01.04.2014
comment
Являются ли ваши сертификаты пользовательскими объектами или предоставляются фреймворком? - person Austin; 01.04.2014
comment
Это пользовательские объекты - person JSA986; 01.04.2014
comment
Обновил мой ответ. Вероятно, вам следует прочитать весь пример AirDropSample — он очень поможет понять, как работает AirDrop. - person Austin; 01.04.2014
comment
Большое вам спасибо за такой подробный ответ - плюс 1, я получил пример кода раздачи и изучил его. Еще один вопрос self.certificates = [aDecoder objectForKey:@"certificates"]; дает мне no visibel@ interface error NSCoder declares the object - person JSA986; 01.04.2014
comment
Извините, должно быть decodeObjectForKey:. Обновил мой ответ. - person Austin; 01.04.2014
comment
Ах, спасибо за это, и должен ли я возвращать себя в этом методе? или НСдата? Предположительно, это NSData в предоставленном вами методе делегата? - person JSA986; 01.04.2014
comment
Какой метод делегирования? - person Austin; 01.04.2014
comment
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { что мне здесь возвращать? Я перенастраиваю себя в - (id)initWithCoder:(NSCoder *)aDecoder { Верно? - person JSA986; 02.04.2014
comment
Вы должны вернуть BOOL, указывающий, был ли запрос успешно обработан в методе делегата приложения, и self в методе инициализации. - person Austin; 02.04.2014