2017-12-29 4 views
1

Ich sende ein verschlüsseltes Archiv als Anhang an eine E-Mail mit MFMailComposeController. Meine App, die den E-Mail-Anhang liest, erhält das verschlüsselte Archiv, aber das Auslagern gibt keine Werte. Details wie folgt:NSKeyedUnarchiver führt nach Übertragung über MFMailComposeController zu Nullwerten

Der Sende View-Controller:

- (IBAction)saveAndSend:(id)sender { 

    // Email Subject 
    NSString *emailTitle = @"Test Email"; 
    // Email Content 
    NSString *messageBody = @"TimeChime Trace Data"; 
    // To address 
    NSArray *toRecipents = [NSArray arrayWithObject:@"[email protected]"]; 

    if (![MFMailComposeViewController canSendMail]) { 
     NSLog(@"Mail services are not available."); 
     return; 
    } 
    MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init]; 
    mc.mailComposeDelegate = self; 
    [mc setSubject:emailTitle]; 
    [mc setMessageBody:messageBody isHTML:NO]; 
    [mc setToRecipients:toRecipents]; 
    // attach NSData to message. Note: file name extension will be used by the mail client to launch 
    // the handler with this extension in its info.plist. 

    NSData *data = [[NSData alloc]init]; 
    data = [NSKeyedArchiver archivedDataWithRootObject:self.items]; 

    [mc addAttachmentData:data mimeType:@"application/CustomUTIHandler" fileName:@"traceData.nrc"]; 

    // Present mail view controller on screen 
    [self presentViewController:mc animated:YES completion:NULL]; 

} 

Das Array vor dem Senden (Array von NRCEventItem) archiviert werden:

Printing description of self->_items: 
<__NSArrayM 0x1c045e390>(
Event Date/time: 2017-12-29 00:08:17 +0000, Event Sender: <AppDelegate: 0x1c40523c0>, Event Description: appl did become active, 
Event Date/time: 2017-12-29 00:15:32 +0000, Event Sender: <HourlyChimeTableViewController: 0x10282fa00>, Event Description: triggerNotification, 
Event Date/time: 2017-12-29 00:30:32 +0000, Event Sender: <HourlyChimeTableViewController: 0x10282fa00>, Event Description: triggerNotification, 
Event Date/time: 2017-12-29 00:45:32 +0000, Event Sender: <HourlyChimeTableViewController: 0x10282fa00>, Event Description: triggerNotification, 
Event Date/time: 2018-01-05 00:00:32 +0000, Event Sender: <HourlyChimeTableViewController: 0x10282fa00>, Event Description: triggerNotification, 
Event Date/time: 2018-01-05 00:15:32 +0000, Event Sender: <HourlyChimeTableViewController: 0x10282fa00>, Event Description: triggerNotification, 
Event Date/time: 2018-01-05 00:30:32 +0000, Event Sender: <HourlyChimeTableViewController: 0x10282fa00>, Event Description: triggerNotification, 
Event Date/time: 2018-01-05 00:45:32 +0000, Event Sender: <HourlyChimeTableViewController: 0x10282fa00>, Event Description: triggerNotification 
) 

Die EventItem Klasse entspricht NSCoding:

// 
// NRCEventItem.h 
// Hourly Chime2 
// 
// Created by Nelson Capes on 12/12/17. 
// Copyright © 2017 Nelson Capes. All rights reserved. 
// 

#import <Foundation/Foundation.h> 

@interface NRCEventItem : NSObject <NSCoding> 
@property (nonatomic) NSDate *eventDateTime; 
@property (nonatomic) NSString *eventSender; 
@property (nonatomic) NSString *eventDescription; 
@end 

Die info.plist der empfangenden App:

enter image description here

Der Code für die empfangende Anwendung, die den Email-Anhang erhält und unarchives die Daten:

- (void) receiveNotificationFromAppDelegate:(NSNotification *) notification { 
NSLog(@"userInfo trace %@",notification.userInfo[KTraceKey]); 

self.items = (NSMutableArray*)[NSKeyedUnarchiver unarchiveObjectWithData:notification.userInfo[KTraceKey]]; 
[self.tableView reloadData]; 

} 

Die Daten nach unarchivierten wobei: erkannte der NSKeyedUnarchiver Offensichtlich

Printing description of path: 
/private/var/mobile/Containers/Data/Application/CCDA0B96-8DD6-496E-B0A0-08B3C072E76A/Documents/Inbox/traceData-40.nrc 
Printing description of items: 
<__NSArrayM 0x1c4240720>(
Event Date/time: (null), Event Sender: (null), Event Description: (null), 
Event Date/time: (null), Event Sender: (null), Event Description: (null), 
Event Date/time: (null), Event Sender: (null), Event Description: (null), 
Event Date/time: (null), Event Sender: (null), Event Description: (null), 
Event Date/time: (null), Event Sender: (null), Event Description: (null), 
Event Date/time: (null), Event Sender: (null), Event Description: (null), 
Event Date/time: (null), Event Sender: (null), Event Description: (null), 
Event Date/time: (null), Event Sender: (null), Event Description: (null) 
) 

die Daten als ein Array, und dass die Elemente in dem Array NRCEventItem sind. Die Eigenschaften in jedem Element des Arrays sind jetzt jedoch null. Ich habe auch den Archivierungsschritt getestet, indem ich das Archiv sofort entpackt habe und die Eigenschaften des Arrays wie zuvor archiviert wurden.

Fazit: irgendwie werden die Daten bei der Übertragung mit dem MFMailComposeViewController geändert.

Wenn jemand Licht darauf werfen kann, würde ich es wirklich schätzen.

+0

Können Sie die Kosten einbeziehen, die das NSCoding-Protokoll implementieren?Hast du versucht, eine Rundreise in der gleichen App zu machen? Und funktioniert das? Sieht die NSData am anderen Ende anders aus? –

Antwort

0

Ich habe das Problem gefunden (und es ist nicht mit MFMailComposeViewController). Meine benutzerdefinierte Klasse NRCEventItem hatte die NSCoding-Protokolle nicht implementiert, sodass das änderbare Array, in dem sie enthalten waren, ordnungsgemäß archiviert und nicht archiviert wurde, die Elemente jedoch nicht. Hier ist der korrekte Code für den Artikel:

// 
// NRCEventItem.m 
// Hourly Chime2 
// 
// Created by Nelson Capes on 12/12/17. 
// Copyright © 2017 Nelson Capes. All rights reserved. 
// 

#import "NRCEventItem.h" 
#import "constants.h" 
@implementation NRCEventItem 
-(void)encodeWithCoder:(NSCoder *)aCoder{ 

    [aCoder encodeObject:_eventSender forKey:kEventLoggerSender]; 
    [aCoder encodeObject:_eventDateTime forKey:KEventLoggerDateTime]; 
    [aCoder encodeObject:_eventDescription forKey:KEventLoggerEventDescription]; 

} 
-(instancetype) initWithCoder:(NSCoder *)aDecoder{ 
    self = [super init]; 
    if (self){ 

     self.eventSender = [aDecoder decodeObjectForKey:kEventLoggerSender]; 
     self.eventDateTime = [aDecoder decodeObjectForKey:KEventLoggerDateTime]; 
     self.eventDescription = [aDecoder decodeObjectForKey:KEventLoggerEventDescription]; 

    } 
    return self; 
} 
-(NSString *)description{ 
    return [NSString stringWithFormat:@"Event Date/time: %@, Event Sender: %@, Event Description: %@", self.eventDateTime, self.eventSender, self.eventDescription]; 
} 
@end 

Ich habe auch den Code für Archiv und Archivieren geändert. Hier ist der Code, das funktioniert:

NSMutableData *data = [[NSMutableData alloc]init]; 
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data]; 
[archiver encodeObject:self.items forKey:@"items"]; 
[archiver finishEncoding]; 

NSMutableData *data = [[NSMutableData alloc]init]; 
data = notification.userInfo[KTraceKey]; 
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data]; 
self.items = [unarchiver decodeObjectForKey:@"items"]; 
[unarchiver finishDecoding]; 

Ich fand, dass es ein Vorteil der Verwendung von NSKeyedArchiver und NSKeyedUnarchiver mit encodeObject und decodeObject statt archivedDataWithRootObject: die Entpacker lassen Sie wissen, wenn es keine Daten im Archiv ist, wenn Sie rief nicht an finishEncoding. Mit der Archivierung und dem Archivieren des Stammobjekts erhalten Sie diese Benachrichtigung nicht.

Ich würde vorschlagen, dass die Verwendung von MFMailComposeViewController eine gute Möglichkeit ist, Daten zwischen Apps zu übertragen, die auf separaten Geräten laufen. Der Schlüssel ist die Implementierung der info.plist, die in meinem OP angezeigt wird.

Danke an Dave für ein mögliches Problem mit der Kodierung!

Verwandte Themen