読者です 読者をやめる 読者になる 読者になる

yoneapp@iPhoneアプリ開発

スタートアップの支援を行うiOS&Railsエンジニアのブログ

CircleCI + Fastlane "ベータ版エンタイトルメントがありません"

ベータ版エンタイトルメントがありませんとiTunesConnectで表示されている場合、Testflightで使用することが出来ません。

Provisioning Profileをリセットすればいいという情報もありますが、おそらく要因が複数あるようで、本件では上手く行きませんでした。

この問題が起きる場合は、ビルドログに次のような警告が表示されている場合が多いです。

WARNING ITMS-90191: "Missing beta entitlement. Your app does not include the beta-reports-active entitlement. If you intend to distribute this build via TestFlight for beta testing, please re-build this app with a newly generated provisioning profile."

私のケースは、ローカル環境だと上手くいくが、CircleCIだと失敗していました。

結論としては、何故かCircleCIでビルドするとuse_legacy_build_apiがtrueになっていました。ローカルではuse_legacy_build_apiはfalseでした。Fastfileでは特に設定していませんでした。*1

ENV['GYM_USE_LEGACY_BUILD_API'] = "false"のように明示的に指定することでCircleCIで本問題が起きることはなくなりました。*2

*1:use_legacy_build_apiをfalseにすると成功する説や、trueにすると成功する説もあります

*2:CircleCIは何らかの理由でtrueで初期設定にしているのかもしれません

iOSでアプリのアップデートを依頼考察+スクリーンショット付き

[iOS]アプリに強制アップデート機能を導入すべき理由と、簡単に実装する方法 - Qiita はOSSのコードが少し古いけど、良い手の一つかも。

強制的にアプリをアップデートさせたい - 未処分利益 のまとめを読んだ。

参考になりそうなスクリーンショット 

続きを読む

Swiftで線とか円グラフを書く

この辺読むと出来そうメモ

Libraryとか

iOSアプリの共通機能をライブラリを使って逃がす

はじめに

同じ機能があるアプリを2〜3も作ってると結構メンテナンスが辛い。共通機能を小まめにライブラリ化して、ライブラリを更新するだけで両方が更新される状況を作りたい。

ただ、両方のコードを全て共通化させて楽をするというのは上手く行かなさそうなので、あくまで小さいパーツに切り分けて、操作は各アプリで違ってくるという考え方良いと思っています。

CocoaPodsによる、外部ライブラリの利用と作成 | Developers.IO を読んでライブラリを作ってみます。

結構簡単にできました。今回は複数のアプリで使っていたTableViewControllerをライブラリに逃がしてみました。

try! Swift 文化を調和させる で学んだDataSourceの外出しを試してみました。ちょうど、最後の方のスライドの上に外出しした部分をライブラリにした具合ですね。

ライブラリを更新して、複数のアプリでpod updateすれば修正が全てに適応されます。ライブラリコードを固めることで良くも悪くも、自由度が下がり保守コストが下がります。

何はともあれCocoapodsの設定ファイルを作る

ライブラリは作成済み前提です。以下の様なコマンドを実行します。

$ pod spec create XXX

作成されたXXX.podspecを適切に編集する。

プライベートなCocoaPodsのSpecsを作成してデプロイ

githubで空っぽのCocoaPodsSpecsを作成してから作業する。

$ pod repo add yoneapp https://github.com/yoneapp/CocoaPodsSpecs
$ pod repo push yoneapp --allow-warnings --verbose

Podfileを書き換える

source 'git@github.com:yoneapp/CocoaPodsSpecs.git'
source 'https://github.com/CocoaPods/Specs.git'

use_frameworks!
platform :ios, '8.0'

target 'YYY' do
  pod 'XXX'
end

自分のライブラリ内で外部ライブラリを使う

Pod::Spec.new do |s|
  ...
  s.dependency 'PullToRefreshSwift', "= 2.0.0"
end

ios - How to import Alamofire/AFNetworking in my custom cocoapod - Stack Overflow

まとめ

今回作ったライブラリは公開できなさそうなんだけど、自前コードをライブラリ化する癖をつけておけば Motivation based library abstraction のようにライブラリを公開出来る日が来るんじゃないかなと思いました。

try! Swiftで学んだこと

私のスキル的に、1発表に対して実際に取り込めるのは1〜2個が限界なので、学んだことが少ないのは申し訳ない。

一番学んだことは、海外からの出席者が居るカンファレンスなんだから英語出来たほうが良かったねということ。HiNative Trekの今月のテーマが「カンファレンスでの会話」らしいので受講を開始しました。

続きを読む

Realm + 高さが可変するTableViewの考察

f:id:yoneapp:20160229102101p:plain

何度か、Realm + 高さが可変するTableViewにチャレンジしてみて、自分の中で最終的にこんな感じかなと思ったのでサンプルを作成してみました。アドバイス頂けると嬉しいです。

GitHub - yoneapp/RealmTableViewSample

高さを計算する処理が重く、バックグラウンドに逃したいがRealmはスレッドをまたげないのでバックグラウンド処理において、どう書けばいいのかについて悩み続けています。

ここに至った経緯を記します。現在、四個目です。

一個目

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat にて text.boundingRectWithSize を使用して高さを計算する。もちろん text.boundingRectWithSize をMainThreadで実行すると重い。

二個目

バックグラウンドで text.boundingRectWithSize を実行する。もちろん、Realmを使っているので落ちる。また、上手くごまかせたとしてもデータが書き換わった時に対処しにくい。

三個目

全てのデータをRealmから取り出し、普通のオブジェクトにしてしまう。この場合、Realmの遅延評価による高速性を犠牲にする。また、データが何千件もある場合に処理に時間が掛かる。更新にも時間がかかる。

四個目

仮想のCellを作成して、そこで高さ計算を行う。Realmオブジェクトに識別子を付け、仮想のCellと結びつける。仮想のCellの計算が終わってない場合は、仮のセルを表示しておく。

仮想のCellは、現在表示されてるCellのプラスマイナス5個ぐらいを常にバックグラウンドで計算するようにする。

実際にRealmのデータが削除された場合でも、データがない場合は仮のセルが表示されるのでクラッシュせずに動作します。

五個目

RealmのSlackで質問させて頂いた所、複雑なことをしなくても UITableViewAutomaticDimension で解決できるとアドバイス頂きました。実際の所、高さ計算はそんなに重くないようでした。estimateHightを合わせて使えば、計算されるセルの数も限定できるので簡単に実装することができそうです。