SkyReporterのiOS8対応奮戦
自作アプリSkyReporterのiOS8への対応。
現在わかってる不具合
・SNS(Twitter、Facebook)およびメールに投稿できない
・マップの現在位置が機能しない
・画像の撮影情報(EXIFやGPS)が表示されない(iPad実機は表示されるようなので、シミュレータ上だけかも)
◆SNSで投稿できない件
iOS7では以下のようにしてたんだけど、いろいろエラーが出て、SNS投稿用モーダルウィンドウが出なかったり、ウィンドウは出ても画像が添付できなかったりした。
SLComposeViewController *composeCtl = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
[composeCtl setInitialText:@"ツイート内容"];
[self presentViewController:composeCtl animated:YES completion:nil];
エラーの内容
LaunchServices: invalidationHandler called
Warning: Attempt to present
と出て投稿用のモーダルウィンドウすら出てくれない。
この書き方自体は間違ってないようなんだけど、写真のライブラリから添付画像を取得するメソッドがblocksを使った非同期処理なんだけど、そこで
[composeCtl addImage:image];
とかやってもうまくaddされてくれないことがわかった。
非同期、かつblocksということでタイミングと変数のスコープに違いが出てきちゃったのかも。
そのため、画像がaddされてないcomposeCtlを使ってpresentViewController〜メソッドを実行するからいけなかったみたい。
同期処理をするように書きなおしたところ、うまくいった。
あと、直前にSNSの選択に非推奨のActionSheetを使っていたため、iPadで問題になったようだ。(iPhoneでも非推奨)
iOS8からはAlertControllerとUIPopoverPresentationControllerを組み合わせたものを使うことで、iPadでも投稿用のモーダルウィンドウが出てくれるようになった。
ただし、まだWarningが出るし、iPadでは画像が添付されない。(iPhoneは大丈夫)
//iOS8からActionSheetが非推奨になるので、UIAlertControllerを使う
float iOSVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
NSLog(@"iOS %f", iOSVersion);
if(iOSVersion >= 8.0)
{
UIAlertController *alertCtl = [UIAlertController alertControllerWithTitle:nil
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
[alertCtl addAction:[UIAlertAction actionWithTitle:@"Twitter"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[self sendTwitter];
}]];
[alertCtl addAction:[UIAlertAction actionWithTitle:@"Facebook"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[self sendFacebook];
}]];
[alertCtl addAction:[UIAlertAction actionWithTitle:@"Mail"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[self sendMail];
}]];
[alertCtl addAction:[UIAlertAction actionWithTitle:@"Cancel"
style:UIAlertActionStyleCancel
handler:nil]];
// iPad用にUIPopoverPresentationControllerを使った以下のコードがないとダメ
// (このコードがあっても、iPhoneでの実行時には変化なし)
alertCtl.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popCtrl = alertCtl.popoverPresentationController;
popCtrl.barButtonItem = _shareButton; //barButtonItemをpopのソースにする場合
//popCtrl.sourceView = self.view; //【参考】viewをソースにする場合
//popCtrl.sourceRect = CGRectMake(100.0, 100.0, 20.0, 20.0);
[self presentViewController:alertCtl animated:YES completion:nil];
◆SNS、メールを送信するSLComposeViewControllerを表示後、AlertControllerのモーダルウィンドウが出ない
これはiOS8のバグっぽいのだが、通常「送信」とか「キャンセル」とか押した後に送信のビューが消えるわけだが、画面上消えてても内部的に消えてくれてないことになっているようで、
[composeCtl dismissViewControllerAnimated:YES completion:nil];
とやったらちゃんとAlertが出てくれるようになった。
ただ、retainがどうのというWarningが出てよろしくない。
そこで
[self dismissViewControllerAnimated:YES completion:nil];
としたらWarningも出なくなった。
ただしここでのselfはcomposeCtlじゃなくて親viewなので、ちょっと心配。特に外見上問題はないようだから、iOS8のバグが直るまでこのままにしちゃおうと思うけど。
◆メール送信できない件
iPad実機ではちゃんと画像付きで送信できて問題なさそう。
しかしシミュレータではiPhone、iPadとも、一度メールを書くモーダルウィンドウが出るものの、しばらくすると勝手に閉じてしまい、
viewServiceDidTerminateWithError: Error Domain=_UIViewServiceInterfaceErrorDomain Code=3 "The operation couldn’t be completed. (_UIViewServiceInterfaceErrorDomain error 3.)" UserInfo=0x7f9c88127800 {Message=Service Connection Interrupted}
などとエラーメッセージが出る。
海外のデベロッパー情報サイトでは、シミュレータの不具合が疑われているようだ。
◆マップの現在位置がつかめない件
CLLocationManagerのメソッドを実行。
_locationManager = [[CLLocationManager alloc]init];
[_locationManager startUpdatingLocation];
位置情報がつかめたらdelegateで以下のメソッドが呼ばれるはずなのだが、呼ばれてくれない。
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
どうやらLocationManagerの仕様が変更されたようだ。

まず、プロジェクトのSupporting Files内のInfo.plistに以下の2つのキーを追加する。
注:中のstringは、Stack overflowというデベロッパ質問サイトで紹介されてたからこうなってるけど、実際はアプリで位置情報を利用する際の確認ダイアログに表示され、iOS8の設定の「プライバシー/位置情報サービス/アプリ名」に、「Appの説明:」として出るので、アプリに合わせて変更するか、消去すればいい。
こうすると、アプリ実行時に「(アプリ名)の使用中に位置情報の利用を許可しますか? The Spirit of stack overflow is 〜〜〜」とかメッセージが出た後、ちゃんとdelegateメソッドが呼ばれてくれる。
同時に、以下のいずれかメソッドもstartUpdatingLocationメソッドの前に実行した方がいいようだ。
//バックグランドでも位置情報を取得し続ける場合
[_locationManager requestAlwaysAuthorization];
//フォアグランドでのみ位置情報を取得する場合
[_locationManager requestWhenInUseAuthorization];
単なる仕様変更というより、プライバシーに配慮した措置なんじゃないだろうか。
でも、いちいちplistをいじらせたりするのはスマートじゃないよね。Xcodeのアップデートでもっと簡単になるかもね。
AppleDeveloperの動画でも一応紹介されてるようだけど、こんなんいちいち見てらんないわな。
◆画像のメタ情報が取得できない
EXIFやGPSの情報を画像から取り出せない。
これはどうもシミュレータ上だけで起こる現象っぽい。
実機のiPadでは問題なく取得できる。
◆iOS7.1の頃からだけど、実機確認のiAdが緑がかってしまう
ググってもほとんど出てこなかったんだけど、Apple Developer Forumなどでようやく、緑になるのは正常で、これが赤くなったら良くないことがわかった。つまり、緑でいいと。
それならもっと他の人も騒いでてもいいような気がするけど、それがいないのはなぜか?
結局、実機の「設定」の中の「デベロッパ」、「Highlight Clipped Banners」がONになってたのを一度OFF、さらにONにしたらちゃんと表示されるようになった。
ONになってていいんだろうけど、何かのせいで緑になっちゃってたんだね。直ったからいいや。
« iOS8リリース | トップページ | SkyReporter 1.0.1、App Store提出 »
「自作アプリ」カテゴリの記事
- AR/VRグラス購入(2018.10.12)
- アプリ第2弾、エスパー発見!?(2014.12.10)
- アプリ制作うまくいかない(2014.11.14)
- SkyReporter 1.0.2審査提出(2014.10.15)
- SkyReporter 1.0.1、App Store提出(2014.09.27)

コメント