2012-09-27 9 views
31

मैं विभिन्न साझाकरण विकल्पों के साथ उपयोगकर्ता को प्रदान करने के लिए आईओएस 6 में नई UIActivityViewController कक्षा का उपयोग कर रहा हूं। आप पाठ, लिंक और छवियों जैसे पैरामीटर की एक सरणी पारित कर सकते हैं और यह बाकी करता है।मैं आईओएस 6 में UIActivityViewController के लिए प्राप्तकर्ता कैसे सेट करूं?

मैं प्राप्तकर्ताओं को कैसे परिभाषित करूं? उदाहरण के लिए मेल या एसएमएस के माध्यम से साझा करना प्राप्तकर्ताओं को स्वीकार करने में सक्षम होना चाहिए, लेकिन मैं यह नहीं समझ सकता कि इस व्यवहार को कैसे शुरू किया जाए।

मैं MFMessageComposeViewController और UIActivityViewController अलग से उपयोग करना नहीं चाहता क्योंकि यह केवल शेयर नियंत्रक के उद्देश्य को हरा देता है।

कोई सुझाव?

UIActivityViewController Class Reference

संपादित करें: यह अब एप्पल प्रस्तुत किया गया है और बाद में एक नकली बग रिपोर्ट के साथ विलय कर दिया। योजना (या एसएमएस: पाठ संदेशों के लिए)

Bug report on OpenRadar

उत्तर

3

यहां सभी क्रेडिट इमानुएल जाते हैं, क्योंकि वह अधिकांश कोड के साथ आया था।

हालांकि मैंने सोचा कि मैं अपने कोड का एक संशोधित संस्करण पोस्ट करूंगा जो प्राप्तकर्ता को सेट करने में मदद करता है।

मैं सुझाव के लिए MFMailComposeViewController पर एक श्रेणी का इस्तेमाल किया

#import "MFMailComposeViewController+Recipient.h" 
#import <objc/message.h> 

@implementation MFMailComposeViewController (Recipient) 

+ (void)load { 
    MethodSwizzle(self, @selector(setMessageBody:isHTML:), @selector(setMessageBodySwizzled:isHTML:)); 
} 



static void MethodSwizzle(Class c, SEL origSEL, SEL overrideSEL) 
{ 
    Method origMethod = class_getInstanceMethod(c, origSEL); 
    Method overrideMethod = class_getInstanceMethod(c, overrideSEL); 

    if (class_addMethod(c, origSEL, method_getImplementation(overrideMethod), method_getTypeEncoding(overrideMethod))) { 
     class_replaceMethod(c, overrideSEL, method_getImplementation(origMethod), method_getTypeEncoding(origMethod)); 
    } else { 
     method_exchangeImplementations(origMethod, overrideMethod); 
    } 
} 

- (void)setMessageBodySwizzled:(NSString*)body isHTML:(BOOL)isHTML 
{ 
    if (isHTML == YES) { 
     NSRange range = [body rangeOfString:@"<torecipients>.*</torecipients>" options:NSRegularExpressionSearch|NSCaseInsensitiveSearch]; 
     if (range.location != NSNotFound) { 
      NSScanner *scanner = [NSScanner scannerWithString:body]; 
      [scanner setScanLocation:range.location+14]; 
      NSString *recipientsString = [NSString string]; 
      if ([scanner scanUpToString:@"</torecipients>" intoString:&recipientsString] == YES) { 
       NSArray * recipients = [recipientsString componentsSeparatedByString:@";"]; 
       [self setToRecipients:recipients]; 
      } 
      body = [body stringByReplacingCharactersInRange:range withString:@""]; 
     } 
    } 
    [self setMessageBodySwizzled:body isHTML:isHTML]; 
} 

@end 
+4

बहुत भयानक कामकाज – Andy

+0

क्या आप पूरा उदाहरण साझा कर सकते हैं? – Rajeev

+0

क्या यह किसी के लिए काम किया है? यदि ऐसा है तो आप पूर्ण कोड साझा कर सकते हैं? – mKane

1

आप ऐसे प्राप्तकर्ताओं mailto के साथ एक NSUrl वस्तु का उपयोग कर शामिल करने के लिए सक्षम होना चाहिए।

UIActivity वर्ग संदर्भ से:

UIActivityTypeMail वस्तु पदों एक नया ईमेल संदेश के साथ उपलब्ध कराई गई सामग्री। इस सेवा का उपयोग करते समय, आप एनएसएसटींग और यूआईएममेज ऑब्जेक्ट्स और एनएसआरएल ऑब्जेक्ट्स स्थानीय फाइलों को गतिविधि आइटम के डेटा के रूप में इंगित कर सकते हैं। आप NSURL ऑब्जेक्ट्स भी निर्दिष्ट कर सकते हैं जिनकी सामग्री मेलto योजना का उपयोग करें।

इसलिए, कुछ इस तरह काम करना चाहिए:

NSString *text = @"My mail text"; 
NSURL *recipients = [NSURL URLWithString:@"mailto:[email protected]"]; 

NSArray *activityItems = @[text, recipients]; 

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

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

धन्यवाद। मैंने इसे आज़मा दिया है और मेलto यूआरएल की सामग्री ईमेल के शरीर में बस जुड़ जाती है। तो ऐसा लगता है कि दस्तावेज़ीकरण के बावजूद समाधान नहीं है। – MattCheetham

+0

हम्म जो अजीब है। क्या आप गतिविधि से टेक्स्ट को हटाने का प्रयास कर सकते हैं, और केवल mailURL के साथ NSURL को पारित कर सकते हैं? – henning77

+0

आप शरीर को शामिल करने के लिए मेलतो का विस्तार कर सकते हैं, उदा। mailto: [email protected] के साथ? [email protected]&subject=This%20is%20the%20subject&body=This%20is%20the%20body – henning77

8

यह प्रदर्शित करता है कि वर्तमान में mailto: ईमेल विषय स्थापित करने और शरीर काम नहीं कर रहा के लिए समाधान, यह किसी भी मामले में नहीं होगा पर्याप्त अगर आप ईमेल निकाय को HTML रखने के लिए सेट करना चाहते हैं और अभी भी UIActivityViewController के माध्यम से ऐप्पल के सिस्टम ईमेल आइकन का उपयोग करना चाहते हैं।

वही था जो हम करना चाहते थे: सिस्टम आइकन का उपयोग करें, लेकिन ईमेल में एक HTML body और एक कस्टम विषय है।

हमारा समाधान एक हैक का था, लेकिन यह कम से कम इस पल के लिए अच्छा काम करता है। इसमें MFMailComposeViewController का उपयोग करना शामिल है, लेकिन यह आपको अभी भी UIActivityViewController के साथ सिस्टम मेल आइकन का उपयोग करने देता है।

चरण 1:

@interface ActivityItemSource : NSObject <UIActivityItemSource> 
    @property (nonatomic, strong) id object; 
    - (id) initWithObject:(id) objectToUse; 
    @end 

    @implementation ActivityItemSource 

    - (id) initWithObject:(id) objectToUse 
    { 
     self = [super init]; 
     if (self) { 
      self.object = objectToUse; 
     } 
     return self; 
    } 


    - (id)activityViewController:(UIActivityViewController *)activityViewController     itemForActivityType:(NSString *)activityType 
    { 
    return self.object; 
    } 

    - (id)activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController 
    { 

     return self.object; 
    } 

चरण 2:: एक आवरण वर्ग तो जैसे UIActivityItemSource के अनुरूप बनाएं उपवर्ग UIActivityViewController और एक MFMailComposeViewControllerDelegate में यह इतना की तरह करते हैं:

@interface ActivityViewController : UIActivityViewController   <MFMailComposeViewControllerDelegate> 

    @property (nonatomic, strong) id object; 

    - (id) initWithObject:(id) objectToUse; 
    @end 


    @implementation ActivityViewController 

    - (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error 
    { 

     switch (result) 
     { 
      case MFMailComposeResultSent: 
      case MFMailComposeResultSaved: 
       //successfully composed an email 
       break; 
      case MFMailComposeResultCancelled: 
       break; 
      case MFMailComposeResultFailed: 
       break; 
     } 

    //dismiss the compose view and then the action view 
     [self dismissViewControllerAnimated:YES completion:^() { 
      [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];   
     }]; 

    } 

    - (id) initWithObject:(id) objectToUse 
    { 

     self = [super initWithActivityItems:[NSArray arrayWithObjects:[[ActivityItemSource alloc] initWithObject:objectToUse], nil] applicationActivities:nil]; 

     if (self) { 
      self.excludedActivityTypes = [NSArray arrayWithObjects: UIActivityTypePostToWeibo, UIActivityTypePrint, UIActivityTypeCopyToPasteboard, UIActivityTypeAssignToContact, UIActivityTypeSaveToCameraRoll, nil]; 

      self.object = objectToUse; 
     } 
     return self; 
    } 

नोट: जब आप super initWithActivityItems पर कॉल कर रहे हैं आप उस ऑब्जेक्ट को लपेट रहे हैं जिसे आप अपनी कस्टम गतिविधि में साझा करेंगे ITemSource

चरण 3: जब उपयोगकर्ता मेल आइकन पर टैप करता है तो सिस्टम के बजाय अपना स्वयं का MFMailComposeViewController लॉन्च करें। mailComposeControllerWithObject विधि आप MFMailComposeViewController वर्ग का एक उदाहरण का दृष्टांत और इसे सेट अप जो भी डेटा आप चाहते हैं को शामिल करने के लिए

- (id)activityViewController:(UIActivityViewController *)activityViewController     itemForActivityType:(NSString *)activityType 
    { 
     if([activityType isEqualToString:UIActivityTypeMail]) { 
       //TODO: fix; this is a hack; but we have to wait till apple fixes the   inability to set subject and html body of email when using UIActivityViewController 
       [self setEmailContent:activityViewController]; 
       return nil; 
      } 
     return self.object; 
    } 


    - (void) setEmailContent:(UIActivityViewController *)activityViewController 
    { 

     MFMailComposeViewController *mailController = [ShareViewController mailComposeControllerWithObject: self.object withDelegate: activityViewController]; 

     [activityViewController presentViewController:mailController animated:YES completion:nil]; 

    } 

:

आप ActivityItemSource कक्षा में activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType विधि में ऐसा होगा। ध्यान दें कि आप लिखें दृश्य के प्रतिनिधि के रूप में activityViewController सेट करेंगे।

कारण यह काम करता है कि जब एक रचना मोडल प्रदर्शित होता है, तो यह अन्य मॉडलों को प्रदर्शित होने से रोकता है, यानी आप अपना स्वयं का रचना दृश्य प्रदर्शित करते हैं जो प्रणाली को दिखने से दृश्य बनाते हैं। निश्चित रूप से एक हैक, लेकिन यह काम पूरा हो जाता है।

उम्मीद है कि इससे मदद मिलती है।

+1

हटा दिया गया है क्या आप मुझे बता सकते हैं कि ' MFMailComposeViewController * mailController = [ShareViewController mailComposeControllerWithObject: self.object withDelegate: ActivityViewController]; 'काम करता है? जब मैं 'MFMailComposeViewController * mailController = [[MFMailComposeViewController alloc] init] का प्रयास करता हूं; mailController.delegate = ActivityViewController; 'मुझे को पर प्रस्तुत करने का प्रयास मिलता है जो की देरी प्रस्तुति के लिए प्रतीक्षा कर रहा है' त्रुटि – zeroos

+0

हाय शून्य, हमने इस दृष्टिकोण को छोड़ दिया है थोड़ी देर पहले, इसलिए यह संभव है कि इस दौरान ऐप्पल ने इस छेड़छाड़ को बंद कर दिया हो। आप किस आईओएस संस्करण के लिए निर्माण कर रहे हैं? आप पहले ओएस के साथ सिम्युलेटर के निर्माण की कोशिश कर सकते हैं, उदा। 5.1, यह देखने के लिए कि क्या यह ओएस से संबंधित है। – ilyashev

+0

यदि आपको करना है, तो आप मेलकॉमव्यू व्यू को एक अलग दृश्य नियंत्रक से प्रदर्शित करने का प्रयास भी कर सकते हैं। संभवतः, जो अभी भी मानक मेल को प्रदर्शित करने से रोकना चाहिए। – ilyashev

10

मैं बस (मेरे मामले में ईमेल के विषय सेट) इस समस्या का समाधान के साथ आते हैं: isHTML: MFMailComposeViewController वर्ग की विधि, बस उस अवरोधन के रूप में आंतरिक रूप से UIActivityViewController कुछ बिंदु पर setMessageBody कॉल करेंगे कॉल और अंदर सेट करने के लिए कॉल करें Sububject: विधि। धन्यवाद "विधि swizzling" कलाओं, ऐसा लगता है जैसे:

#import <objc/message.h> 

static void MethodSwizzle(Class c, SEL origSEL, SEL overrideSEL) 
{ 
    Method origMethod = class_getInstanceMethod(c, origSEL); 
    Method overrideMethod = class_getInstanceMethod(c, overrideSEL); 

    if (class_addMethod(c, origSEL, method_getImplementation(overrideMethod), method_getTypeEncoding(overrideMethod))) { 
     class_replaceMethod(c, overrideSEL, method_getImplementation(origMethod), method_getTypeEncoding(origMethod)); 
    } else { 
     method_exchangeImplementations(origMethod, overrideMethod); 
    } 
} 

@implementation MFMailComposeViewController (force_subject) 

- (void)setMessageBodySwizzled:(NSString*)body isHTML:(BOOL)isHTML 
{ 
    if (isHTML == YES) { 
     NSRange range = [body rangeOfString:@"<title>.*</title>" options:NSRegularExpressionSearch|NSCaseInsensitiveSearch]; 
     if (range.location != NSNotFound) { 
      NSScanner *scanner = [NSScanner scannerWithString:body]; 
      [scanner setScanLocation:range.location+7]; 
      NSString *subject = [NSString string]; 
      if ([scanner scanUpToString:@"</title>" intoString:&subject] == YES) { 
       [self setSubject:subject]; 
      } 
     } 
    } 
    [self setMessageBodySwizzled:body isHTML:isHTML]; 
} 

@end 

कॉल में निम्न कोड पंक्ति UIActivityViewController उपयोग करने से पहले: कि UIActivityTypeMail के लिए UIActivityItemProvider एक कस्टम

MethodSwizzle([MFMailComposeViewController class], @selector(setMessageBody:isHTML:), @selector(setMessageBodySwizzled:isHTML:)); 

फिर UIActivityViewController के पास एक HTML रिटर्न जैसे NSString:

<html><head> 
<title>Subject of the mail</title> 
</head><body> 
Body of the <b>mail</b> 
</body></html> 

ईमेल के विषय (वह हिस्सा के लिए सादा पाठ का उपयोग करें, कोई HTML शीर्षक से निकाला जाता है एचटीएमएल इकाइयों या टैग)।

उस विधि का उपयोग करके, मैं आपको प्राप्तकर्ता को मेल के लिए सेट करने के लिए एक शानदार तरीका बताता हूं।

24

ईमेल iOS6 पर UIActivityViewController का उपयोग करने के विषय जोड़ने के लिए, यह सबसे अच्छा समाधान है कि किसी को उपयोग कर सकते हैं .. आपको बस इतना करना है का अनुसरण करते हुए आरंभ UIActivityViewController कहते हैं।

UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:applicationActivities]; 
[activityViewController setValue:@"My Subject Text" forKey:@"subject"]; 

और आपका UIActivityViewController किसी विषय के साथ पॉप्युलेट किया गया है।

+0

पर टिप्पणी करें एक आकर्षण और बहुत सरल की तरह काम किया। धन्यवाद! – Jon

+1

यह काम करता प्रतीत होता है, लेकिन क्या यह प्रलेखित है? –

+1

केवीओ का उपयोग कर महान समाधान! – manderson

1

मुझे प्राप्तकर्ताओं के बारे में निश्चित नहीं है, लेकिन ऐसा लगता है कि आईओएस 7 में और बाद में आप UIActivityItemSource प्रोटोकॉल के अनुरूप एक ईमेल का विषय सेट कर सकते हैं और activityViewController:subjectForActivityType: विधि को कार्यान्वित कर सकते हैं।

+3

हां, यह विषय के लिए काम करता है, कोई पसीना नहीं। लेकिन प्राप्तकर्ता को सेट करने के लिए अभी भी कोई गैर-तेज तरीके से नहीं है। – matt

संबंधित मुद्दे