2017-12-29 6 views
1

MFMailComposeController를 사용하여 전자 메일에 첨부 파일로 키 저장을 보냅니다. 전자 메일 첨부 파일을 읽는 내 응용 프로그램은 키 보관 파일을 가져 오지만 저장을 해제하면 값이됩니다. 상세는 다음과 같이 :MFMailComposeController를 통해 전송 한 후 NSKeyedUnarchiver 결과가 nil 값이됩니다.

송신 뷰 컨트롤러 :

배열은 (NRCEventItem 배열)을 전송하기 전에 보관되는
- (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]; 

} 

:

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 
) 

EventItem 클래스 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 

수신 앱의 정보 목록 :

enter image description here

데이터를 전자 메일 첨부 파일을 가져 와서 전개함으로써 수신 응용 프로그램의 코드 :

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

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

} 

데이터 아카이브 해제 된 후에 : 분명히

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) 
) 

을의 NSKeyedUnarchiver가 인식 데이터를 배열로 간주하고 배열의 요소는 NRCEventItem입니다. 그러나 배열의 각 요소에있는 속성은 nil입니다. 또한 아카이브를 즉시 아카이브 해제하여 아카이브 단계를 테스트했으며 배열의 특성은 아카이브되기 전과 같습니다.

결론 : 어떻게 든 데이터는 MFMailComposeViewController를 사용하여 전송 중에 변경됩니다.

누구든지이 문제에 관해 밝힐 수 있다면 정말 고맙겠습니다.

+0

NSCoding 프로토콜을 구현하는 비용을 포함 할 수 있습니까?같은 앱에서 왕복 여행을 해봤습니까? 그게 효과가 있니? NSData는 다른 끝에서 다르게 보입니까? –

답변

0

문제점을 발견했습니다 (MFMailComposeViewController와 함께 표시되지 않음). 내 사용자 지정 클래스 인 NRCEventItem에는 NSCoding 프로토콜이 구현되어 있지 않으므로이를 포함하는 변경 가능한 배열이 제대로 보관되고 보관되지는 못했지만 항목은 그렇지 않았습니다. 해당 항목의 올바른 코드는 다음과 같습니다.

// 
// 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 

또한 보관 및 보관 취소 코드가 변경되었습니다.

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]; 

내가 오히려 archivedDataWithRootObject보다는 encodeObject 및 decodeObject와 NSKeyedArchiver와 NSKeyedUnarchiver를 사용하는 이점이 있음을 발견 : 여기에 작동하는 코드 인 unarchiver은 아카이브에 데이터가없는 경우 알려 드릴 것입니다 당신이 경우 finishEncoding으로 전화하지 않았습니다. 루트 객체 보관 및 보관 취소로이 알림을받지 못합니다.

MFMailComposeViewController를 사용하면 별도의 장치에서 실행되는 앱간에 데이터를 전송할 수있는 좋은 방법이라고 생각합니다. 열쇠는 내 OP에 표시되는 info.plist를 구현하는 것입니다.

Dave에게 인코딩 문제를 제안 해 주셔서 감사합니다!

관련 문제