iOS 8.0対応のために僕が苦労したこと(Locationが取れない、Enterprise Appがインストール出来ない)

iOS 8 icons
iOS 8 icons / microsiervos

iOS 8.0がやって来て、PhoneGapでの業務アプリ開発を現在の仕事としている僕は、困ったことがいくつか起きました。

iOS 8.0でWKWebViewが公開されて、それにPhoneGapが対応し始めたりしたら、いろいろと問題が起こるだろうなー、でもまだそれはないから大丈夫だろうなーと、のほほんとしていたのですが、案外、そんなこともありませんでした。

もうちょっと、事前にちゃんと調べておくべきだった。。。

iOS 8.0でLocationが取れない

僕の作っている業務アプリでは、Location(位置情報)を取得しています。
PhoneGapが提供するGeolocationプラグインも使っているし、それとは別にネイティブコード内でも。

それが、iOS 8.0ではLocationが取得できないようになってしまいました。
こんなメッセージをログに残して。

Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.

懇切丁寧なメッセージだったので、このとおりに対応したらLocationは取得できるようになりました。

if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
    [self.locationManager requestAlwaysAuthorization];
}

requestAlwaysAuthorizationというのはアプリがバックグラウンドにあるときもLocationの取得を許可するということです。
一方、requestWhenInUseAuthorizationはアプリがフォアグラウンドにあるときのみLocationの取得を許可します。

PhoneGapのGeolocaitonプラグインでは?

最新のGeolocaitonプラグインのコードを見ると、下記のような処理が入っているので、問題ないようです。

#ifdef __IPHONE_8_0
    NSUInteger code = [CLLocationManager authorizationStatus];
    if (code == kCLAuthorizationStatusNotDetermined && ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)] || [self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])) { //iOS8+
        __highAccuracyEnabled = enableHighAccuracy;
        if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"]){
            [self.locationManager requestAlwaysAuthorization];
        } else if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) {
            [self.locationManager  requestWhenInUseAuthorization];
        } else {
            NSLog(@"[Warning] No NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription key is defined in the Info.plist file.");
        }
        return;
    }
#endif

Enterprise Appの配布に困った

plistが作れないよ!

これはiOS 8.0というよりXcode6だと思うのですが、まずArchivesのボタン構成が違うじゃないの!

まず、Exportを選びます。
Xcode6 archives

次は、Save for Enterprise Deployment。(Xcode5では、Enterprise or AdHocにまとまっていたのになぁ。)
Xcode6 export

で、この後も順調に?Xcode5とはUIが違う感じなのですが、順当に画面を進めていって、はたと悩む。以前だったら、Enterprise Appの配布時に必要となるplistファイルをipaファイルと同時に作成出来たのですが、それが出来ない!

Stack Overflowに下記のようなネタがあって、それを見てみると、「以前作ったplistを使い回すしかないね」とのこと。マジで?

I’m having the same problem. Needed to put a build out last night. I ended up just reusing an old plist and updating it.

Xcode 6 Save for Enterprise Deployment does not create plist for ipa anymore?

Enterprise Appがインストール出来ないiOS 8.0デバイスがあるよ!

で、とりあえず以前のplistを使い回して、私のiPad mini Retina(iOS 8.0.2)については事なきを得たのですが、他の人が使っているiOS 8.0デバイスで、アプリがインストール出来ないという問題に遭遇。

LoadExternalDownloadManifestOperation: Ignore manifest download, already have bundleID:...

なんていうメッセージがコンソールに出ていて、はてなと調べてみると、またしてもStack Overflow。

I’ve also encountered this problem with our app distribution. We were able to fix this issue by ‘faking’ the bundle identifier inside the .plist using for download distribution, keeping our ipa bundle identifier the same.

change com.mycom.MyApp to com.mycom.MyApp.ios8fix

Enterprise App Update Distribution on iOS 8

つまり、plistのbundle-identifierの値を偽装して、本来のAppのBundle Identifierとは別の値にしろ!ということなんですね。
なんと乱暴な!と思いますが、たしかに、これでインストールは出来るようになりました。

おまけ。Xcode6でのDeviceのコンソール

iOSデバイスをUSBケーブルでMacに接続して、コンソールのログフローを見てみようと思うことがあると思います。Xcode6だとDevices画面の左下の方にあるボタンをクリックすると、コンソールが表示されます。
これも、Xcode5からの変更点ですね。

Xcode6 devices console

この記事を書いた人

井上 研一

経済産業省推進資格ITコーディネータ/ITエンジニア。株式会社ビビンコ代表取締役。
北九州市出身、横浜市在住。AIやIoTに強いITコーディネータとして活動。北九州市主催のビジネスコンテスト「北九州でIoT」に応募したアイディアが入選し、メンバーと株式会社ビビンコを創業。著書に「初めてのWatson」、「ワトソンで体感する人工知能」など。日本全国でAI・IoTなどをテーマにしたセミナーや研修講師での登壇多数。