PhoneGapによるiPhoneアプリ作成(Object-C拡張)
はじめに
ハイブリッドアプリ作成のための覚え書きです。忘れないためのメモ程度ですので、初心者に懇切丁寧に教えるコンセプトでないため、ところどころ、はしょったりしてます。
Object-Cによる機能拡張
PhoneGapeを使用するにあたり、やはり限界があります。そのため、ChildBrowserのObject-Cコードを拡張し、新しく機能を追加することにしました。今回はSafariが立ち上がるアイコンを押すと、代わりにアクションシートが起動し、Safariで開く、Twitter共有、メール送信、URLコピーとしてChildBrowserで閲覧中のURLを引数に渡す機能を追加します。個々の機能はFrameworkとして提供されているものを呼び出します。
アクションシートの追加
ChildBrowserViewController.xib から ChildBrowserViewController.h へアクションシート起動用アイコンをControlキーを押しながらドラッグします。するとボタン接続情報の設定がでるので、値を、
Connection: Action
Name: safariBtn(ここはアイコンと同じ奴)
Event: Touch Up Inside
Arguments: Sender
に設定。次に@interface にUIActionSheetDelegate を追記
@interface ChildBrowserViewController : UIViewController <UIWebViewDelegate, UIActionSheetDelegate>{}
すると、ChildBrowserViewController.m に- (IBAction)safariBtn:(id)sender が追記されます。
ここにアクションシートのメニューを宣言していきます。
UIActionSheet *actionSheet = [[UIActionSheet alloc]
initWithTitle:@"メニュー" delegate: self cancelButtonTitle:@"キャンセル" destructiveButtonTitle:@"閉じる" otherButtonTitles:@"Safariで開く",@"Twitter共有",@"メール送信",@"URLコピー", nil
];
[actionSheet showInView:self.view];
[actionSheet release];
次にアクションシートの内容を記述します。
- (void)actionSheet:(UIActionSheet *) actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
NSString *requestPath = [[self.webView.request URL] absoluteString];
NSURLRequest* requestURL = self.webView.request;
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
switch ((buttonIndex)) {
case 0:
/* チャイルドブラウザを閉じる */
if (self.delegate != nil) {
[self.delegate onClose];
}
if ([self respondsToSelector:@selector(presentingViewController)]) {
// Reference UIViewController.h Line:179 for update to iOS 5 difference - @RandyMcMillan
[[self presentingViewController] dismissViewControllerAnimated:YES completion:nil];
} else {
[[self parentViewController] dismissModalViewControllerAnimated:YES];
}
break;
case 1:
/* Safariで開く */
if (self.delegate != nil) {
[self.delegate onOpenInSafari];
}
if (self.isImage) {
NSURL* pURL = [NSURL URLWithString:self.imageURL];
[[UIApplication sharedApplication] openURL:pURL];
} else {
NSURLRequest* request = self.webView.request;
[[UIApplication sharedApplication] openURL:request.URL];
}
break;
case 2:
/* Twitterで共有 */
if ([TWTweetComposeViewController canSendTweet]) {
// ツイート用の画面を表示する
TWTweetComposeViewController *tweetViewController =
[[TWTweetComposeViewController alloc] init];
[tweetViewController setInitialText: @"Tweet文"];
[tweetViewController addURL: requestURL.URL];
[self presentViewController:tweetViewController animated:YES completion:nil];
[tweetViewController release];
}else {
// ツイッター設定なし
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Teitter未設定"
message:@"アカウントの設定が未設定です。"
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:@"OK" , nil];
[alert show];
[alert release];
}
break;
case 3:
/* メール送信 */
if( [ MFMailComposeViewController canSendMail ] == NO )
{
[ [ [ [ UIAlertView alloc ] initWithTitle:@"エラー" message:@"メールアカウントを設定してください"
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:nil ] autorelease ] show ];
}
else
{
MFMailComposeViewController * controller =
[ [ [ MFMailComposeViewController alloc ] init ] autorelease ];
[ controller setSubject:@"タイトル" ];
[ controller setMessageBody: requestPath isHTML:YES ];
controller.mailComposeDelegate = self;
[ self presentModalViewController:controller animated:YES ];
}
return;
break;
case 4:
/* クリップボードへコピー */
[pasteboard setValue:requestPath forPasteboardType:@"public.text"];
break;
default:
break;
}
}
- (void)mailComposeController:( MFMailComposeViewController* )controller didFinishWithResult:( MFMailComposeResult )result error:( NSError* )error
{
if( error != nil )
{
NSLog( @"エラーが発生しました。" );
}
else
{
switch( result )
{
case MFMailComposeResultSent: NSLog( @"メールを送信" ); break;
case MFMailComposeResultSaved: NSLog( @"メールを保存" ); break;
case MFMailComposeResultCancelled: NSLog( @"キャンセル" ); break;
case MFMailComposeResultFailed: NSLog( @"失敗" ); break;
default: NSLog( @"不明な結果" ); break;
}
}
[ controller dismissModalViewControllerAnimated:YES ];
return;
}
インポートするFramework
# import <Twitter/TWTweetComposeViewController.h>
# import <UIKit/UIPasteboard.h>
# import <MessageUI/MessageUI.h>
# import <MessageUI/MFMailComposeViewController.h>
PROJECTのSummaryのLinkedFrameworks and Libraries からも各Frameworkを読み込むのを忘れずに。
まとめ
PhoneGapではある程度の拡張をObject-Cで記述することで可能になります。
ネイティブに依存するため移植性は犠牲になりますが、便利といえば便利。