Help us understand the problem. What is going on with this article?

プロジェクト作成時に用意したほうがいいこと

More than 5 years have passed since last update.

この記事はiOS Second Stage Advent Calendar 2013の13日目の記事です。

今回、NSNullで定義されてるNSNullのシングルトンインスタンスを返す+ null;とか、よくわからんことを書こうと思ってました。(よく考えると、iOSというよりObjective-C)

しかし、既にNSNullについて詳しく書かれている記事を見つけてしまいました。。

なので、書くネタなくなりました。

つまり、13日は書くネタを何にしようかなーとずっと迷っておりました。(これが遅れた原因。嘘じゃない。嘘やないや…すみません…)

結局書く事が13日に決まらず、帰宅中の13日の23:40にやっと書く事が決まりました。そして書いてる間に寝落ちしてました。

さて、今回のAdvent Calendarのお題は「プロジェクト作成時にやっておいたほうがいい事」です。

それでは、本題に入りましょう!

※今回の参考コードを載せましたが、載せる程度だったのでFacebookとGAIのライブラリが入ってないゆえにエラります。

時間があったらちゃんと整理しますー

バージョントラッキング

自分の中で、アプリのバージョンは1.2のように [major version].[minor version] となるようにしています。

そして、ビルドバージョンは1.2.3のように [major version].[minor version].[patch version] となるようにしています。

このアプリバージョンの方をアプリ起動時にNSUserDefaultsで保持しておき、ユーザがアプリのバージョンアップをしたのがわかるようにしたほうがよいです。(経験則)

何故かというと、初回インストール後の起動時に何か出したい!とか、アップデート後の起動で何かしたい!とか、絶対あるんですよね。

そして、その何かしたいときに前のバージョンで用意しておかないと出来ないので、プロジェクト立てた時点で用意しておくと絶対に良いです。

以下、コード抜粋(コードはgithubに上げてます)

- (ATAppVersionState)appVersionState
{
    NSString *trackingAppVersion = [ATObject getTrackingAppVersion];
    NSString *currentAppVersion = [ATObject appVersionString];
    ATAppVersionState state = ATAppVersionStateNotChanged;
    if (trackingAppVersion == nil) {
        state = ATAppVersionStateFirst;
        [[NSNotificationCenter defaultCenter] postNotificationName:kATAppVersionStateFirst object:nil];
        if ([_delegate respondsToSelector:@selector(appVersionStateFirst)]) {
            [_delegate appVersionStateFirst];
        }
    } else if (![trackingAppVersion isEqualToString:currentAppVersion]) {
        state = ATAppVersionStateBumpedUp;
        [[NSNotificationCenter defaultCenter] postNotificationName:kATAppVersionStateBumpedUp object:nil];
        if ([_delegate respondsToSelector:@selector(appVersionStateBumpedUp)]) {
            [_delegate appVersionStateBumpedUp];
        }
    } else {
        [[NSNotificationCenter defaultCenter] postNotificationName:kATAppVersionStateNotChanged object:nil];
        if ([_delegate respondsToSelector:@selector(appVersionStateNotChanged)]) {
            [_delegate appVersionStateNotChanged];
        }
    }
    if (state > ATAppVersionStateNotChanged) {
        [ATObject setTrackingAppVersion];
    }
    if ([_delegate respondsToSelector:@selector(appVersionState:)]) {
        [_delegate appVersionState:state];
    }
    return state;
}

トラッキングバージョン(既に保持しているもの)と、今のバージョンを比較しています。

  • トラッキングバージョンが無ければそのアプリは初回インストール
  • トラッキングバージョンが存在し、トラッキングしてるのと今のバージョンが違う場合はバージョンアップ
  • 上記満たさなければ変化なし

です。

これをうまく利用すればNSFoundationの判定もできるので、ユーザがiOSのバージョンアップしたのもわかります。(コードにそれっぽいの載せてます)

また、アプリやAPIで使用するアプリのバージョンはintまたはdoubleに変換したものを利用したほうがいいです。(1.2などをそのまま使用しない)

+ (NSString *)appVersionString
{
    return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
}

+ (NSString *)appBuildVersionString
{
    return [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey];
}

+ (NSNumber *)appVersionNumber
{
    NSString *appVersionString = [ATObject appVersionString];
    NSArray *array = [appVersionString componentsSeparatedByString:@"."];
    appVersionString = [NSString stringWithFormat:@"%d%02d", [array[0] integerValue], [array[1] integerValue]];
    return [NSNumber numberWithInteger:appVersionString.integerValue];
}

+ (NSNumber *)appBuildVersionNumber
{
    NSString *appVersionString = [ATObject appVersionString];
    NSArray *array = [appVersionString componentsSeparatedByString:@"."];
    appVersionString = [NSString stringWithFormat:@"%d%02d.%02d", [array[0] integerValue], [array[1] integerValue], [array[2] integerValue]];
    return [NSNumber numberWithDouble:appVersionString.doubleValue];
}

しっかりとintやdoubleに直しておくと、値の大小でバージョンの切り分けができるからです。

クラッシュトラッキングフレームワーク

上記二つはアプリがクラッシュした際にレポートを送ってくれるツールです。

アプリがクラッシュしても「どういう状態起こったのかなんてわからぬ!!」なんで、これらのフレームワークを導入してレポートを見れると非常に心強いです。

これは12日に発表したmuukii0803が弊社アプリに導入してくれました。

当分はここに出てくるレポートを減らすのが目標となりそうです。

CocoaPods

言わずもがな、有名なCocoaPodsですが、先日、導入していなかったプロジェクトから移行する際に意外と大変でした。

ライブラリの管理についてはgit submoduleをやったりもしていましたがCocoaPodsが一番いいですし、CocoaPodsに存在しないライブラリはあまり使わない方が良い気もします。

※大変だった理由が、GoogleAnalytics for iOSに嵌りました。たしか静的ライブラリが入ってなかったとかだった気が。。

バージョンアップが頻繁に起こるライブラリのラッパークラス・ヘルパークラス

GoogleAnalyticsやFacebook SDKってバージョンアップするとメソッド自体変わって、マイグレーションがマジ半端ないです。

だからといってそのバージョンで放置してても良くないので、私の場合はヘルパークラスを作成してその中に処理を書くようにしました。

メソッド名は単純で、application:didFinishLaunchingWithOptions:に記述する必要がある場合、そのヘルパークラスに同様の命名をして、呼び出します。

そうしておけばコードが散り散りとならず、メンテ性が確保できます。

この参考となりそうなコードもgithubにあげたものへ一部載せてあります。

今回紹介したアプリプロジェクトに入れておいたほうがいいものは、実際にアプリを開発し続け、しっかりと運用をしないと意外と気付かないものです。

kaneshin
I'm the CTO at Eureka. I relish building things with Go, C, PHP, Bash and so on. I have substantial experience in cloud solutions which are GCP and AWS. I also have a strong mathematics experience.
https://kaneshin.co
eure
オンラインデーティングサービス「Pairs」の運営・開発をしている企業。様々なモダンな技術を駆使してビジネスを成長させています。
https://eure.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away