问题
I have an NSMutableArray
self.certificates
This array is made up of saved strings and core data. I want to send this through AirDrop. I have checked out serialization
and and im trying to send it with the folowing
- (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];
}
This gives me the following error'NSInvalidArgumentException', reason: 'Invalid type in JSON write (Certificate)'
I have converted to data to a string so not sure what im missing here
Ive researched NSInvalidArgumentException, reason: 'Invalid type in JSON write (__NSDate)' and How to send NSArray to web service
回答1:
The exception is thrown by JSONSerialization
, before the array is converted to data.
To share a custom data type, you'll want to implement NSCoding
and UIActivityItemSource
on your model object:
@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
Then, when you create your activity view controller:
CertificatesGroup *group = [CertificatesGroup new];
group.certificates = self.certificates;
UIActivityViewController *activityCtr = [[UIActivityViewController alloc] initWithActivityItems:@[group]
applicationActivities:nil];
...
You're app delegate should implement -application:openURL:sourceApplication:annotation:
and decode the incoming certificates.
- (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;
}
For more info, see Apple's AirDropSample project, especially APLProfile.h
/.m
, APLProfileViewController.h
/.m
and AppDelegate.m
.
来源:https://stackoverflow.com/questions/22769911/send-nsarray-via-airdrop