2013-12-14 105 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:@「Your email Subject」forKey:@「subject」]沒有記錄,所以我認爲它會被Apple拒絕。我想這就是爲什麼蘋果已經添加了這個API,他們希望你改用它。 - (NSString *)activityViewController:(UIActivityViewController *)activityViewController subjectForActivityType:(NSString *)activityType; 此外,這仍然不能解決具有自定義名稱的附件的問題。 – RawMean

32

對於那些在一個解決方案仍然磕磕絆絆運作良好,有定製UIActivityViewController一個更優雅的解決方案。爲解決原始問題,附件未顯示的原因是因爲它應該是一個單獨的UIActivityItemProvider對象。

因此,解決方案是創建兩個UIActivityItemProvider子類,一個包裝'emailBody'和'emailSubject',另一個包裝附件。使用UIActivityItemProvider作爲附件的好處是,您有機會延遲處理附件直到需要爲止,而不是在呈現UIActivityViewController之前這樣做。

落實AttachmentProvider類,以提供像這樣的附件:

@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與這兩個項目在你的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 Drive的操作,保存到Dropbox等。如果我在第二個提供商中添加了正文/主題數據,則不會顯示這些操作。如果電子郵件是唯一的問題,這很好,但應該謹慎。 – Craig

相關問題