MFMailComposeViewControllerの確認画面がうざい。
一律に、確認しないとメールを送れないようにするんじゃなくて、所定の手続きを踏んでユーザに確認すれば、確認画面を出さないでバックグラウンドでメールを送れるようにして欲しい...
で、skpsmtpmessage Quick SMTP client code for the iPhone を使おうかと思ったけど、デフォルトで設定されているE-Mailアカウントを使えない。
それじゃ意味がなさすぎるので。
なんか方法ないかなーってさまよってたら、cocoa touch - iPhone send email not using MessageUI - Stack Overflowというのを見つけた。Sendボタン押しちゃうわけね。絶対、審査とおんないんだろうなぁ。
通んないのかなぁ。とりあえず投げてみてから考えるか。っつーわけで、実装してみた。
まず、MFMailComposeViewControllerの設定。ちなみにSimulatorではメールを送れない。あと、サブジェクトがないとAlertが出てうざいので、ちゃんと埋めておく。
/*! * submit content */ - (id)submitContent:(PhotoSubmitterContentEntity *)content andOperationDelegate:(id<PhotoSubmitterPhotoOperationDelegate>)delegate{ MFMailComposeViewController *mailComposeViewController = [[MFMailComposeViewController alloc] init]; if([MFMailComposeViewController canSendMail] == NO){ [self completeSubmitContentWithRequest:mailComposeViewController andError:nil]; return mailComposeViewController; } mailComposeViewController.mailComposeDelegate = self; [mailComposeViewController setToRecipients:[NSArray arrayWithObject:self.sendTo]]; NSString *subject = nil; NSString *body = nil; if(content.comment == nil && self.defaultSubject != nil){ subject = self.defaultSubject; } if(content.comment != nil && self.commentAsSubject){ subject = content.comment; } if(content.comment == nil && self.defaultBody != nil){ body = self.defaultBody; } if(content.comment != nil && self.commentAsBody){ body = content.comment; } if(subject == nil || [subject isEqualToString:@""]){ subject = @"tottepost photo"; } [mailComposeViewController setSubject:subject]; [mailComposeViewController setMessageBody:body isHTML:NO]; NSDateFormatter* dateFormat = [[NSDateFormatter alloc] init]; [dateFormat setDateFormat:@"M/d/y h:m:s"]; NSDateFormatter *df = [[NSDateFormatter alloc] init]; df.dateFormat = @"yyyyMMddHHmmssSSSS"; NSString *filename = nil; NSString *mimeType = nil; if(content.isPhoto){ filename = [NSString stringWithFormat:@"%@.jpg", [df stringFromDate:content.timestamp]]; mimeType = @"image/jpeg"; }else{ filename = [NSString stringWithFormat:@"%@.mp4", [df stringFromDate:content.timestamp]]; mimeType = @"video/mp4"; } [mailComposeViewController addAttachmentData:content.data mimeType:mimeType fileName:filename]; if(self.confirm == NO){ [mailComposeViewController view]; }else{ dispatch_async(dispatch_get_main_queue(),^{ [self presentModalViewController:mailComposeViewController]; }); } return mailComposeViewController; }
で、composeし終わってMFMailComposeViewControllerが表示されそうになったら、controllerのsubviewを辿ってsendボタンを探す。探すのは再帰になるのでこんな感じのメソッドを作る。
/*! * find views named */ - (NSArray *)searchForViewsNamed:(NSString *)name fromView:(UIView *)view found:(NSMutableArray *)found{ if(found == nil){ found = [[NSMutableArray alloc] init]; } for (UIView *subview in [view subviews]) { if([NSStringFromClass([subview class]) isEqualToString:name]){ [found addObject:subview]; } [self searchForViewsNamed:name fromView:subview found:found]; } return found; }
でUINavigationBarの右側にあるSendボタンを探すので、こうなる。
/*! * on composed */ - (void) mailComposeController:(MFMailComposeViewController*)controller bodyFinishedLoadingWithResult:(NSInteger)result error:(NSError*)error { if(self.confirm == NO){ id button = nil; NSArray *views = [self searchForViewsNamed:@"UINavigationBar" fromView:controller.view found:nil]; if(views.count == 0){ return; } views = [self searchForViewsNamed:@"UINavigationButton" fromView:[views objectAtIndex:0] found:nil]; if(views.count == 0){ return; } for (UIView *v in views) { if(v.frame.origin.x > 200){ button = v; } } if(button == nil){ return; } [button sendActionsForControlEvents:UIControlEventTouchUpInside]; [self checkForSizeConfirmWindow]; } }
でもって、sendボタン押した後、写真のサイズが大きすぎると、選択するUIActionSheetが出てしまう。出ている場合にはUIApplicationのkeyWindowからUIActionSheetを辿れるので、適当に選択するようにする。
/*! * select size confirm button */ - (void) checkForSizeConfirmWindow{ UIActionSheet *actionsheet = nil; NSArray *buttons = [[NSMutableArray alloc] init]; NSArray *views = [self searchForViewsNamed:@"UIActionSheet" fromView:[UIApplication sharedApplication].keyWindow found:nil]; if(views.count == 0){ return; } actionsheet = [views objectAtIndex:0]; buttons = [self searchForViewsNamed:@"UIAlertButton" fromView:actionsheet found:nil]; if(actionsheet && buttons.count > 2){ [[buttons objectAtIndex:1] sendActionsForControlEvents:UIControlEventTouchUpInside]; } }
で、これで黙ってSendできます。多分審査は通らないと思うけど、とりあえず出してみる。まぁ、確認画面が毎回出るだけなんだけど。
当然、AppStore通さないアプリなら問題なく使えます。
追記
審査とおった。多分、運だと思います。