2013-12-14 1 views
17

UIActivityItemProvider를 사용하여 전자 메일 첨부 파일을 통해 내 응용 프로그램 내에서 파일을 공유하려고합니다. 전자 메일의 제목 줄을 채우고 첨부 파일의 이름을 장치에 저장된 파일 이름과 다른 것으로 지정해야합니다.UIActivityItemProvider를 사용하여 UIActivityViewController가있는 첨부 파일이있는 전자 메일을 보내려면 어떻게합니까?

여기에 제가 사용하고있는 코드가 있습니다. 문제는 이메일에서 첨부 파일이 누락되었습니다.

@interface ItemProvider:UIActivityItemProvider 
@property (nonatomic, strong) NSURL *filepath; 
@property (nonatomic, strong) NSString *emailBody; 
@property (nonatomic, strong) NSString *emailSubject; 
@end 

@implementation ItemProvider 

- (id)initWithPlaceholderItem:(id)placeholderItem 
{ 
    //Initializes and returns a provider object with the specified placeholder data 
    return [super initWithPlaceholderItem:placeholderItem]; 
} 

- (id)item 
{ 
    //Generates and returns the actual data object 
    return [NSDictionary dictionary]; 
} 

// The following are two methods in the UIActivityItemSource Protocol 
// (UIActivityItemProvider conforms to this protocol) - both methods required 
#pragma mark UIActivityItemSource 

//- Returns the data object to be acted upon. (required) 
- (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType 
{ 


    if ([activityType isEqualToString:UIActivityTypeMail]) { 
     return @{@"body":self.emailBody, @"url":self.filepath}; 
    } 


    return @{@"body":self.emailBody, @"url":self.filepath}; 
} 

//- Returns the placeholder object for the data. (required) 
//- The class of this object must match the class of the object you return from the above method 
- (id)activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController 
{ 
    return @{@"body":self.emailBody, @"url":self.filepath}; 
} 

-(NSString *) activityViewController:(UIActivityViewController *)activityViewController subjectForActivityType:(NSString *)activityType { 
    return self.emailSubject; 
} 

@end 

그리고

는 내의 ViewController에서 나는이 작업을 수행 :

 ItemProvider *provider = [[ItemProvider alloc] initWithPlaceholderItem:@{@"body":emailBody, @"url":filePath}]; 
    provider.emailBody = emailBody; 
    provider.emailSubject = info.title; 
    provider.filepath = filePath; 
    NSArray *activityItems = @[provider]; 

    // Build a collection of custom activities (if you have any) 
// NSMutableArray *customActivities = [[NSMutableArray alloc] init]; 


    UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil]; 

    [self presentViewController:activityController animated:YES completion:nil]; 

답변

6

내가 ItemProvider없이 첨부 파일이있는 이메일을 보내고있다. 는 아직 이것에 대한 해결책에 비틀 거리는 사람들을 위해

NSMutableArray *selDocs = [[NSMutableArray alloc] init]; 
for (Document *theDoc in self.selectedDocs) { 
    NSURL *fileUrl = [NSURL fileURLWithPath:theDoc.filePath];  
    [selDocs addObject:fileUrl]; 
} 
NSArray *postItems = [NSArray arrayWithArray:selDocs]; 

UIActivityViewController *avc = [[UIActivityViewController alloc] initWithActivityItems:postItems applicationActivities:nil]; 
[avc setValue:@"Your email Subject" forKey:@"subject"]; 

avc.completionHandler = ^(NSString *activityType, BOOL completed){ 
    NSLog(@"Activity Type selected: %@", activityType); 
    if (completed) { 
     NSLog(@"Selected activity was performed."); 
    } else { 
     if (activityType == NULL) { 
      NSLog(@"User dismissed the view controller without making a selection."); 
     } else { 
      NSLog(@"Activity was not performed."); 
     } 
    } 
}; 

[self presentViewController:avc animated:YES completion:nil]; 
+1

감사합니다. 솔루션은 작동하지만 다음 요구 사항을 충족하지 않습니다. 질문을 명확하게하기 위해 업데이트했습니다. 1. 전자 메일의 제목 줄을 채워야합니다 (이것이 공급자 솔루션을 사용하는 이유 중 하나입니다). 2. 첨부 파일에 파일 이름과 다른 이름을 지정해야합니다. – RawMean

+3

왜 당신들은 당신이 원하거나 필요로하는 것을 정확히 묘사하는 것을 배우지 못합니까? 당신이 처음에 내가 이것을 필요로하고 대답을받은 후에 당신을 도우려는 사람들을위한 낭비되는 시간이 더 필요해 그리고 이것과 나는 ... 설정 주제를 추가했습니다 ... – thorb65

+0

요구 사항에 대해 충분히 구체적입니다. 사과드립니다. [avc setValue : @ "귀하의 이메일 제목"forKey : @ "제목"]은 문서화되어 있지 않으므로 Apple에 의해 거부 될 것입니다. 나는 이것이 애플이이 API를 추가 한 이유이며, 대신에 그것을 사용하기를 원한다고 생각한다. - (NSString *) activityViewController : (UIActivityViewController *) activityViewController subjectForActivityType : (NSString *) activityType; 또한 사용자 지정 이름이있는 첨부 파일의 문제는 해결되지 않습니다. – RawMean

32

:-) 잘 작동, UIActivityViewController을 사용자 지정하기위한 더 우아한 해결책이 있습니다. 원래 질문을 처리하기 위해 첨부 파일이 표시되지 않는 이유는 별도의 UIActivityItemProvider 개체로 간주되기 때문입니다.

그래서 해결책은 두 개의 UIActivityItemProvider 하위 클래스를 만들고 하나는 'emailBody'와 'emailSubject'를 래핑하고 다른 하나는 첨부 파일을 래핑하는 것입니다. 첨부 파일에 UIActivityItemProvider을 사용하면 얻을 수있는 이점은 첨부 파일 처리가 필요하기 전까지 처리하는 것이 아니라 UIActivityViewController을 제시하기 전에 첨부 파일 처리를 지연 할 수있는 기회가 있다는 것입니다.

@implementation AttachmentProvider : UIActivityItemProvider 

- (id)item { 
    if ([self.activityType isEqualToString:UIActivityTypeMail]) { 

     /* Replace with actual URL to a file. Alternatively 
     * you can also return a UIImage. 
     */ 

     return [NSData dataWithContentsOfURL:dataURL]; 
    } 
    return nil; 
} 

@end 

지금처럼 공급자에게 이메일 본문 및 대상 클래스를 EmailInfoProvider 클래스를 구현 :

@implementation EmailInfoProvider : UIActivityItemProvider 

- (id)item { 
    return @"Your email body goes here"; 
} 

- (NSString *)activityViewController:(UIActivityViewController *)activityViewController subjectForActivityType:(NSString *)activityType { 
    if ([activityType isEqualToString:UIActivityTypeMail]) { 
     return @"Your subject goes here"; 
    } 
    return nil; 
} 

@end 

당신은 다음 UIActivityViewController과를 만들 수 있습니다

지금과 같은 첨부 파일을 제공하기 위해 AttachmentProvider 클래스를 구현 당신의 viewController에있는이 두 항목은 다음과 같습니다 :

- (void)shareAction { 

    AttachmentProvider *attachment = [[AttachmentProvider alloc] init]; 
    EmailInfoProvider *emailContent = [[EmailInfoProvider alloc] init]; 

    // You can provider custom -(id)init methods to populate EmailInfoProvider 

    UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:@[attachment, emailContent] applicationActivities:nil]; 
    [self presentViewController:activityController animated:YES completion:nil]; 
} 
+0

두 개의 서브 클래스를 작성할 필요조차 없습니다. 같은 것을 넣을 수 있습니다. 'UIActivityItemProvider'는 어쨌든'UIActivityItemSource' 프로토콜을 구현합니다. – orkoden

+2

@orkoden 전자 메일 본문과 첨부 파일을 어떻게 단일 제공 업체에 결합합니까? – Andy

+1

이 접근법을 시도해 보면 활동 컨트롤러에서 사용할 수있는 활동이 제한된다는 것을 알았습니다. 활동 항목 배열에 하나의 파일 항목이있는 경우 iOS에서 iCloud 드라이브에 추가 할 작업, 보관 용으로 저장하는 작업 등을 제공합니다. 본문/주제 데이터가있는 두 번째 공급자를 추가하면 이러한 작업이 나타나지 않습니다. 전자 메일이 유일한 관심사라면 괜찮습니다.하지만 조심해야 할 사항입니다. – Craig