2013-12-14 19 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.私は電子メールの件名を入力する必要があります(これが私がプロバイダソリューションに頼った理由の1つです)。 2.添付ファイルにファイル名と異なる名前を付ける必要があります。 – RawMean

+3

あなたは何をしたいのか、必要としているのかを正確に記述するのをなぜ学ばないのですか?あなたが最初に私がこれを必要とし、答えを受け取った後にあなたが助けたいと思っている人々のための無駄な時間ですが、私はもっとこれとこれとこれが必要です...私は設定対象を追加しました... – thorb65

+0

あなたは要件について十分に具体的です。謝罪します。 [電子メールの件名] forKey:@ "件名"]は文書化されていないため、Appleによって却下されると思います。私はそれがAppleがこのAPIを追加した理由だと思うし、代わりにあなたが使いたいと思う。 - (NSString *)activityViewController:(UIActivityViewController *)activityViewController subjectForActivityType:(NSString *)activityType; また、カスタム名の添付ファイルの問題は解決しません。 – RawMean

32

:-)うまく機能し、UIActivityViewControllerをカスタマイズするための、よりエレガントな解決策があります。元の質問に対処するために、添付ファイルが表示されない理由は、別のUIActivityItemProviderオブジェクトであるためです。

解決策は、2つのサブクラス「emailBody」と「emailSubject」をラップするサブクラスと、添付ファイルをラップするサブクラスの2つを作成することです。添付ファイルに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

2つのサブクラスを作成する必要はありません。あなたは同じものを置くことができます。 'UIActivityItemProvider'はとにかく' UIActivityItemSource'プロトコルを実装しています。 – orkoden

+2

@orkoden電子メールの本文と添付ファイルを単一のプロバイダでどのように組み合わせますか? – Andy

+1

このアプローチを試してみると、アクティビティコントローラで利用可能なアクティビティが制限されていることがわかりました。アクティビティアイテム配列に1つのファイルアイテムがある場合、iOSはiCloudドライブに追加するアクションを提供し、Dropboxなどに保存します。ボディ/サブジェクトデータを含む2番目のプロバイダを追加すると、これらのアクションは表示されません。メールが唯一の問題であればこれは問題ありませんが、それは慎重なものです。 – Craig

関連する問題