スマホゲームの「みどりのほしぼし」がめっちゃ癒される

なんか仕事疲れたわ〜もう何も考えたくないわ〜って時にやると癒やされるゲーム。瀬戸弘司が紹介してて知った。

ゲームオーバーが無いから無心になれる

ねこあつめみたいに、とくになにか敵にやられて死ぬとかが無い。だからボーっとやれる。
ゲームの趣旨は、彗星をミサイルとかビームで破壊してエネルギーを貯めて、そのエネルギーで星を緑化するというもの。

IMG_0849

とにかくドット絵の宇宙人がかわいい

続きを読む スマホゲームの「みどりのほしぼし」がめっちゃ癒される


写真で好みを分析!らーめん屋推薦アプリ『麺利き』をリリースしました

Men-kiki-icon

App Storeでダウンロード

らーめんを愛するすべての人に捧ぐ!
ありそうでなかったらーめん屋推薦アプリです。
名前は『麺利き』。

写真で「こんな感じ!」が伝えられる新しい探し方

食べておいしかったらーめん、ありますよね。
その写真をアプリに入力してください。
すると、アプリが似た雰囲気のらーめんを出すラーメン屋を探します。

例えば、野菜たっぷりのらーめんを入力すると・・

iphone6-03

見事に二郎系のらーめん屋が提示されましたwww

ぜひ、みなさんのお気に入りらーめんで試してみてください。
きっといいお店が見つかりますよ!

開発には30万枚のらーめん画像を使用

開発には、最近何かと話題のディープラーニングという機械学習アルゴリズムの一つを使用しました。

推薦アルゴリズムのために、30万枚のらーめん画像を集めて学習させました。

つまり、このアプリは「らーめんとは何か」を理解しているのです!(どーん)

開発の裏話はまた別のエントリで書きますので、お楽しみに!!

App Storeでダウンロード


iOSのクラッシュログファイルをシンボリケートする

どこでクラッシュしたのか見通しを良くする

Appleから受け取ったクラッシュログは、クラッシュした状態のスタックトレースをバイナリ上のアドレスで示されています。
このままだと、内容を見てもソースコード上のどこが悪いのかさっぱり分かりません。
シンボリケートとは、主にバイナリ上のアドレスからソースコードの場所を突き止める事をいいます。

使用するコマンド

クラッシュログのシンボリケートにはsymbolicatecrashコマンドを使用すると便利です。
XCode 6では以下のパスに存在しています。

/Applications/Xcode.app/Contents/SharedFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash

/usr/bin あたりにシンボリックリンクを貼っておくと吉。

必要なファイル

クラッシュログを吐いたバイナリと同じビルドのもので、以下が必要です:

  • appファイル
  • dSYMファイル

XCodeのOrganizerを開き、アーカイブ一覧から該当のビルドを探します。
次に、該当ビルドの項目を右クリックしてShow in Finderします。
開かれたディレクトリに、上記二つのファイルが存在します。

シンボリケートの実行

以下のように実行します。

export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"

symbolicatecrash -v crashファイル dSYMファイル appファイル

トラブルシューティング

DEVELOPER_DIRを予め設定しておかないと、以下のようなエラーが出ます。

Error: "DEVELOPER_DIR" is not defined at /Applications/Xcode.app/[snip]Resources/symbolicatecrash line 53.

[iOS] Swiftの隠し機能:数学記号をカスタムオペレータとして使う

swift-book

新言語Swiftでは、C++のようにカスタムのオペレータを定義できます。
このオペレータには、Unicodeの文字が使えるとのこと!
下記のツイートのような感じで使えるらしいです。

let r = ¬(a ∧ b)

詳しい例はこちら:


[iOS] アカウント情報をアプリ間で安全に共有する方法

keychain500x500

はじめに

google-642x309

Google Drive, Docs, SheetsのiOS版では、アプリ間でGoogleアカウント情報を共有しています。
いずれかのアプリで一度認証すれば、他のアプリでは面倒な認証手順が不要になります。
これはどういう仕組みで行われているのでしょう?
アプリはどのようにして、ユーザの入力無しにユーザを識別しているのでしょう。

Keychain:安全に機密情報を取り扱う仕組み

実は、先に述べたGoogleのアプリ達は、KeychainというOSの仕組みを使っています。
Keychainは、もしあなたがMac OSXユーザであればなじみ深いと思います。実はiOSにも備わっています。
これは、パスワードや秘密鍵、証明書などの機密情報を安全に管理するための仕組みです。
Keychainで保管されるデータは暗号化されます。

アカウント情報の取り扱いに最適

Keychainと同じようにユーザ情報を保存するための仕組みとして、UserDefaultsというものがあります。
UserDefaultsは、主にプリファレンスなどを保存するための仕組みです。
UserDefaultsと比べて、Keychainが機密情報の取り扱いに優れている点は以下です:

  • アプリが削除されてもデータが残る
  • 同じKeychain Access Groupに属するアプリ同士でアクセスできる (Keychain Access Groupは後ほど詳しく説明します)
  • データが暗号化される

Keychain Servicesとは

Keychain Servicesは、Keychainを使うためのAPI群です。
以下からAppleのドキュメントを参照できます:

Mac OSXとiOSではAPIが異なるので注意です。
ここでは、iOSでの使用を前提として説明します。
日本語の資料では以下が参考になります。

しかしながら上記ページは古くて、XCode上の手順が有効でない部分があります。
本ページでは、XCode 5で設定する場合を説明します。

Keychain Servicesの基本的な使い方

Framework

利用するには、Security.frameworkをプロジェクトに追加してください。

便利なラッパモジュールを使おう

Appleが用意したAPIをそのまま使うのもいいですが、我々には時間がありません。
オススメは LUKeychainAccess です。
LUKeychainAccessを使えば、NSUserDefaultsと同じ感覚でKeychainのアイテムを管理できます。
以降は、このラッパを使う前提で説明します。

基本的な使い方

NSUserDefaultsと全く同じです。

[[LUKeychainAccess standardKeychainAccess] setBool:NO forKey:@"authorized"];
BOOL authorized = [[LUKeychainAccess standardKeychainAccess] boolForKey:@"authorized"];

Keychainでのアクセス制御

制御の軸はアイテムに「いつ」アクセスできるのかと、「どれが」アクセスできるのか、の2つがあります。

Accessible属性

アプリケーションが「いつ」アクセスできるのかを制御します。詳しくはこちら
LUKeychainAccessでは、それぞれ以下の定数で指定できます。

  • LUKeychainAccessAttrAccessibleAfterFirstUnlock
    • 再起動後最初のアンロック以降/次の再起動まで
  • LUKeychainAccessAttrAccessibleAfterFirstUnlockThisDeviceOnly
    • 再起動後最初のアンロック以降/次の再起動まで
  • LUKeychainAccessAttrAccessibleAlways
    • 常にアクセス可
  • LUKeychainAccessAttrAccessibleAlwaysThisDeviceOnly
    • 常にアクセス可
  • LUKeychainAccessAttrAccessibleWhenUnlocked
    • デバイスがアンロックされた状態
  • LUKeychainAccessAttrAccessibleWhenUnlockedThisDeviceOnly
    • デバイスがアンロックされた状態

以下のように指定します。

LUKeychainAccess* keychainAccess = [LUKeychainAccess standardKeychainAccess];
keychainAccess.accessibilityState = LUKeychainAccessAttrAccessibleWhenUnlocked;

Keychain Access Group

「どの」アプリケーションがアイテムにアクセスできるのかを制御します。
デフォルトでは、アクセスできるアプリケーションはそのアイテムを格納したアプリケーション自身だけです。
グループの指定によって、同じグループに属するアプリケーションからのアクセスを許可出来ます。
このグループは、アイテムごとに指定できます。

例えば、あなたのapplication-identifiercom.foobar.applicationだとします。
あなたのアプリケーションが読み書き可能なグループは、そのグループ識別子がapplication-identifier前方一致する場合です。
グループによる権限の違いは以下の通りです。

  • アクセス可なアイテムのグループ
    • com.foobar.application
    • com.foobar
  • アクセス出来ないアイテムのグループ
    • com.apple.calendar
    • com.foobar.mailer

つまり、com.foobarというグループに属するアイテムを作成すると、アクセス出来るアプリケーションはapplication-identifiercom.foobar.*に相当するものになります。

また、注意点ですが、同じグループに属していてもアクセスできない場合があります。
それは、Code Signing Identityがアプリケーション間で異なる場合です。
つまり、アイテムを共有するアプリケーションは同一ベンダーのものでなければなりません

Keychain Access Groupの変更

Keychain Access Groupをデフォルトのapplication-identifierから変更するには、Entitlementsを作成します。
XCode 5ではこの作成手順が簡単になっています。

まず、ビルドターゲットのCapabilitiesタブを開きます。

Screen Shot 2014-07-10 at 12.02.58 AM

Keychain Sharingという項目を見つけたら、スイッチをONにしましょう。
Keychain Groupsというリストが現れたはずです。
ここに、指定したいグループの識別子を入力します。
グループは複数指定できます。
一番上に記述したものが、デフォルトで使用されるグループになります。

シミュレータにおけるグループの取り扱い

シミュレータでも動作しますが、テストは実機でやる事を強くおすすめします。
というのは、シミュレータだと常にグループがtestとなるからです。
シミュレータ上では、グループ指定に関わらず全てのアプリケーションから全てのアイテムにアクセス出来ます。

TestFlight用ビルドとデバッグ用ビルド間ではアイテムを共有出来ない

ここで、TestFlight経由でインストールしたビルドと、USB経由でインストールしたビルドのapplication-identifierを別々にすればテストできるかもしれないと思いますが、これも無理です。
理由は、Code Signing Identityが異なるからです。
共通のCode Signing Identityで、異なるapplication-identifierのアプリを用意しましょう。

アイテムのキー

基本的な使い方のセクションで説明した通り、アイテムのキーは単純な文字列で指定できます。

[[LUKeychainAccess standardKeychainAccess] setBool:NO forKey:@"authorized"];

これは以下のような単純なkey/valueストアです。

key = value

Keychain Servicesでは、この単純なキーに加えて、オプションでサービス名も付けられます。
以下のようにserviceディレクトリにkey/valueを格納していくイメージです。

service.key = value

サービス名の指定は、TwitterやFacebookの認証情報をセットにして格納したい場合に便利です。

サービス名つきアイテムへのアクセス方法

残念ながらLUKeychainAccessは、サービス名の指定にまだ対応していません。。
そこで、このラッパをフォークして対応させてみました。

サービス名対応版なら、以下のようにサービス名を指定できます。

[[LUKeychainAccess standardKeychainAccess] setBool:NO forKey:@"authorized" service:@"Twitter"];
BOOL authorized = [[LUKeychainAccess standardKeychainAccess] boolForKey:@"authorized" service:@"Twitter"];

簡単ですね!
本家にはこの拡張をプルリクエストしておきました。


Core Dataライブラリと便利ツールの紹介

iOSアプリにおいて、Core Dataは永続的で大きなオブジェクトグラフが取り扱えるモデルを提供する。
多くの有名アプリで使われているけど、複雑だしそのまま使おうとすると開発効率が悪い。

Core Dataを置き換えようとするライブラリが多くあるが、さらに多くのライブラリはCore Dataをよりよくしようとするものだ。
それらのライブラリは糖衣構文(シンタックスシュガー)からフルスタックのフレームワークまで幅広い。

本記事では、CoreDataを取り扱うオープンソースのライブラリを紹介する。
あなたのCore Data要件にマッチするものを見つけて下さい。

ライブラリ一覧

ラッパー


Magical Record
Saul
Mora
Objective-Record Marin
Usalj
SSDataKit Sam
Soffes
ios-queryable Marty
Dill

ReactiveCoreData
Jacob
Gorban

アダプター

RestKit Blake
Watters

AFIncrementalStore
Mattt
Thompson
MMRecord Conrad
Stoll

SLRESTfulCoreData
Oliver
Letterer
Overcoat Guillermo
Gonzalez
Mantle GitHub

シンクロナイザ

TICoreDataSync Tim
Isted
, Michael Fey,
Kevin
Hoctor
, Christian Beer,
Tony
Arnold
, and Danny Greg

UbiquityStoreManager
Maarten
Billemont
FireData Jonathan
Younger

ユーティリティ

mogenerator Jonathan
‘Wolf’ Rentzsch

ラッパー

ラッパーライブラリはいくつかの糖衣構文や便利メソッド群を提供するもの。
Core Dataの冗長で複雑なAPIを簡単にしてくれる。

例えば、新しいManaged ObjectをManaged Object Contextに挿入するには、NSManagedObjectでもNSManagedObjectContextのクラスメソッドではなく、NSEntityDescriptionのものを呼び出す必要がある。
それは、NSEntityDescription +insertNewObjectForEntityForName:inManagedObjectContext:だ。
わかりにくい!

Core Dataのこのような分かりにくいAPIをラフにラップするオープンソースのライブラリが沢山存在している。
AppDelegateの外でMainコンテキストとPrivateコンテキストを管理できるものや、クエリの生成を簡単にできるものなどなど。

SSDataKit

Core Dataのアプリケーションを書くのには、多くのボイラープレート(初めに必要なコード)が必要だ。
これはだるい。
SSDataKitはこれを楽にする。

Active Recordにインスパイアされたもの

ある方法論を学んだら、それを別の技術にも適用しようというアイデアは何も驚くものではない。
Active Recordに詳しいRubyプログラマーがiOSアプリの開発に流入した事によって、それは起こった。

Magical Record

MagicalRecordはRuby on RailsのActive Recordの取得方法にインスパイアされたもの。
このコードのゴールは、Core Data関連のコードをクリーンアップし、シンプルで、一行で取得できる、かつ最適化のためにNSFetchRequestを変更できる余地を残す事。

Objective-Record

ライトウェイトにActiveRecord的にCore Dataのオブジェクトを取り扱えるもの。
シンタックスはRuby on Railsに酷似している。
AppDelegateのコードはなし。
Kiwiで完全にテストされたライブラリだ。

LINQにインスパイアされたもの

面白いことに、.Netから来た開発者も、同じように慣れ親しんだパラダイムをiOS開発でも行おうとする。
それは、LINQのパラダイムだ。

LINQはSQLライクだが、言語に統合されたものだ。
NSPredicateNSSortDescriptorのようなキーバリューコーディングは、以下のようにいい感じの構文になる:

from c in SomeCollection
  where c.SomeProperty < 10
  select new {c.SomeProperty, c.OtherProperty};

ios-queryable

ios-queryable supports LINQ-style query composition and deferred execution, and implements a subset of IEnumerable’s methods, including where, take, skip, orderBy, first/firstOrDefault, single/singleOrDefault, count, any, and all.

ReactiveCocoaにインスパイアされたもの

ReactiveCocoa は、Objective-CでFunctional Reactive Programmingのパラダイムを可能にするライブラリ。
それをCore Dataにも使ったものが存在する。

ReactiveCoreData

ReactiveCoreData (RCD)は、ReactiveCocoaの世界にCore Dataを持ち込もうとするもの。

アダプタ

ほとんどのiOSアプリはウェブサービスと通信する。
Core Dataを使うアプリにとって、RESTまたはRPCスタイルのウェブサービスからレコードを取得・更新・削除する事は共通だ。
ローカルのキャッシュとサーバ側との一貫性を保持するのは、トリッキーだ。

オブジェクトを常に最新の状態に保ち、重複を削除して、APIのエンドポイントとエンティティをマップし、衝突を調整し、ネットワーク到達性を管理する…これらは頑健なクラサバ型アプリの作成においてデベロッパが直面するいくつかの問題だ。

幸運な事に、これらの心配を軽減するライブラリが多く存在する。

RestKit

RestKitは、RESTfulなウェブサービスとクライアントを連携させるためのiOSとMac OS Xで動作するモダンなObjective-Cフレームワークだ。
Core Dataとシームレスに統合するオブジェクトマッピングエンジンを提供し、AFNetworking上に構築されたプリミティブなHTTP通信機能群を提供する。
エレガントで入念にデザインされたAPIによって、RESTfulのモデリングは魔法のように簡単になる。

AFIncrementalStore

AFIncrementalStoreはNSIncrementalStoreのサブクラスで、AFNetworkingを使ってプロパティとリレーションシップが必要な時に自動で取得してくれる。

MMRecord

MMRecordはブロックベースでシームレスにウェブサービスと統合できるiOSとMac OS Xで動作するライブラリ。
Core Dataモデルの構成を利用して、APIのレスポンスから自動的にオブジェクトグラフを作成する。
どのネットワークライブラリでも動作するようにできていて、シンプルな導入方法を提供する。

SLRESTfulCoreData

SLRESTfulCoreDataはAFNetworkingSLCoreDataStack上に構築されたもので、JSON REST APIとCore Dataモデルを数分で統合できる。

Overcoat

OvercoatはAFNetworkingの拡張で、デベロッパに簡単にMantleモデルオブジェクトが使えるようにする。

Mantle

MantleはCocoaとCocoa Touchアプリケーションで簡単にモデルレイヤーを記述できるようにする。

シンクロナイザ

アダプターはRESTなどの一般的な用途のインターフェースを通じて情報を同期するのに対して、シンクロナイザはもっと直接的なプロトコルを用いて、よりよい統合性とパフォーマンスを提供する。

TICoreDataSync

MacとiPhone、iPhone同士、iPhoneとiPadなど、デバイス間でCore Dataを自動で同期する。

UbiquityStoreManager

UbiquityStoreManagerはCore DataでiCloud統合を実装するコントローラ。

FireData

FireDataはシームレスにCore DataとFirebaseを統合する。

ユーティリティ

Mogeneratorを紹介しないで、Core Data系ライブラリを紹介しているとは言えないだろう。
MogeneratorはiPhone以前の時代から存在し続けている、Core Dataを使ったアプリケーションの開発において欠く事ができないツールだ。
Core Dataはここ数年で大きく変わったのに、Apple提供のツールは機能性に乏しいままだ。
でも幸運なことに、Wolf Rentzsch氏がカバーしてくれた。

Mogenerator

Mogeneratorはコマンドラインツールで、.xcdatamodelファイルを渡すとエンティティごとに2つのクラスを生成する。
1つめのクラスは_MyEntityで、マシン向けのもので継続的に上書きされ、データモデル設計と同じ状態に保たれる。
2つめのクラスはMyEntityで、_MyEntityのサブクラス。こっちはカスタムなロジックを記述するためのもので、生成以降は上書きされない。

いかがでしたでしょうか。
万能薬は存在しませんが、用途ごとに合ったものを使う事で劇的に開発効率は向上するでしょう。

(翻訳元: Core Data Libraries & Utilities – NSHipster)


[Objective-C] 任意のクラスのサブクラスをランタイムで列挙する方法

objective-c

プラグイン的なアーキテクチャでファクトリ部が肥大化する問題

複数種類のファイルを取り扱うようなアプリを思い浮かべてみて下さい。
対応するファイル形式を柔軟に増やせるようなアーキテクチャを、Objective-Cではどう構築するのが良いでしょう?
各形式を取り扱うモジュールがあって、それらは定型化された仕様に則って振る舞うような一般的なsubclassingモデルと、ファクトリパターンが良さそうです。

しかし、取り扱える種類が増えると、モジュールを統括する部分(ファクトリ部)の実装が肥大化する問題が発生します。
例えば、指定した拡張子に対応するクラスのインスタンスを返す関数とか。
更に、新しい形式を追加した時に、ファクトリ部への追加実装の手間も後々に負担となったり、実装漏れが生ずる可能性があります。

モジュールをランタイムで列挙してスッキリさせる

ファクトリ部をスッキリさせるには、通常のsubclassingモデルよりももう少し粗結合な実装方法を検討してみると解決するかもしれません!
それは、基底クラスのサブクラスの列挙部をハードコーディングするのではなく、ランタイムで列挙する方法です。
サブクラスに、ファクトリ部で取り扱いが必要な情報を提供するGetterメソッドやプロパティを持たせます。

これなら、新モジュールの登録忘れや一貫性を崩す心配を軽減できます!

ランタイムAPIを使って実現

NSObjectに対してメソッドを追加するカテゴリを紹介します。
追加されるメソッドの+ classNamesForSubclasses を、あるクラスをレシーバにして呼び出すと、その子クラスの名前がNSArrayで返ります。
チョー簡単ですね!

ヘッダファイル(NSObject+AutomaticFactory.h):

#!objectivec
#import &lt;Foundation/Foundation.h>

@interface NSObject (AutomaticFactory)

+ (NSArray*) classNamesForSubclasses;

@end

ソースファイル(NSObject+AutomaticFactory.m):

#!objectivec

#import "NSObject+AutomaticFactory.h"
#import &lt;objc/runtime.h>

@implementation NSObject (AutomaticFactory)

+ (NSArray*) classNamesForSubclasses;
{

    int numClasses = 0, newNumClasses = objc_getClassList(NULL, 0);
    Class *classList = NULL;

    while (numClasses < newNumClasses) {
        numClasses = newNumClasses;
        classList = (Class*)realloc(classList, sizeof(Class) * numClasses);
        newNumClasses = objc_getClassList(classList, numClasses);
    }

    NSMutableArray *classesArray = [NSMutableArray array];

    for (int i = 0; i < numClasses; i++) {
        Class superClass = classList[i];
        do {
            // recursively walk the inheritance hierarchy
            superClass = class_getSuperclass(superClass);
            if (superClass == [self class]) {
                [classesArray addObject:NSStringFromClass(classList[i])];
                break;
            }
        } while (superClass);
    }

    free(classList);

    return classesArray;
}
@end

プラグイン的な実装をしている場合は、検討してみてはいかがでしょうか?

参考ページ: Automagic Factories in Objective-C