sakaharaのブログ

アプリ開発に関する話や日々の出来事など

iOSでFacebookのログイン方法について整理してみた

久しぶりにiOS向けFacebook SDKを使う機会があったのですが、ログイン方法が本当に多様になってたのでざっくり整理しました。 種類が増えててドキュメントちゃんと見ないと混乱します・・・。 ということで内容の整理兼ねてのメモとして書いています。

ざっくり整理してるだけなのでもっと詳細を知りたい方は公式ドキュメントを見てください。

https://developers.facebook.com/docs/facebook-login/ios/v2.0

  • FBLoginView

これは知らなくて驚いたのですが、専用のログインボタンができたようです。 ドキュメント見る限りかなり簡単に使えそうです。

  • Facebookネイティブアプリ・ログインダイアログ

これはFacebookアプリをインストールしている場合に使えます。 アプリにログイン済みであれば認証は必要ないのでユーザーの負荷は少ない言えます。 欠点としてはiOS6以上でアプリをインストール済みでないと使えないことです。

  • iOSログインダイアログ

iOS6から追加されたOSに組み込まれたFacebookのログイン形式です。 すでにログイン済であればログインフローをユーザーが意識する必要がないので一番理想的な方法だと思います。 欠点としてはユーザーがログインしていない場合、設定画面からログインしてもらうよう誘導する必要があります。

  • Facebookネイティブアプリ・Webベースログインダイアログ

古いバージョンのFacebookアプリをインストールしている場合に使えます。 ネイティブアプリのログイン画面より遅いの欠点です。

  • モバイルSafari・ログインダイアログ

Facebookネイティブアプリをインストールしていない場合に使えます。 欠点としてSafariへの切替が発生や、ネイティブアプリと比較して速度が遅い点などがあげられます。

  • WebViewログインダイアログ

ログインダイアログを表示するコードを毎回直接書いて表示します。 ログインフローで毎回ユーザーがユーザーID、パスワードを入力する必要があります。 また欠点としてネイティブアプリと比較して速度が遅い点やがあげられます。

ログインするためのサンプルでも書こうと思いましたが、すでによいものがあるのでそちらを 見た方が早いです。

http://github.com/fbsamples/ios-howtos

とこんな感じでログイン一つとっても多種多様になってました。 ログインするプロセスというのはユーザーにとってとてもストレスがかかるところなので、 負担をなるべくかけないようにするための努力の後が伺えます。 しかし使う側はなんだか混乱してしまいますが・・・ある程度はSDKが自動で制御してくれるのでそれらを踏まえて使うのがよいです。

Swiftを使ったAFNetworking 2.0 のまとめ [iOS]

概要

以前書いた記事を勉強がてらSwiftに置き換えてみました。 習うより慣れろ!と言う言葉通り実際触ってみるのがやはり使えるようになるための一番の近道です。

AFNetworking 2.0以降を使うには下記が必須要件となっていますので導入前に確認してください。

大きな変更点としてドキュメントにあるようにiOS7以降のサポートのみでよければAFHTTPSessionManagerのサブクラスを作成して実装することが推奨されています。 iOS6やそれ以前のバージョンをサポートする場合の選択肢としてAFHTTPRequestOperationManagerが用意されています。

前回のまとめ同様に主にAFHTTPRequestOperationManagerの使い方について触れておきます。

使い方

Objective-Cを使う際と同様にインストールもCocoaPodsで簡単に導入できますので、下記Podfileをプロジェクトのルート直下に作成してインストールしましょう。

platform :ios, '7.0'
pod "AFNetworking", "~> 2.0"

GETで使う場合

let manager = AFHTTPRequestOperationManager()
manager.responseSerializer = AFHTTPResponseSerializer()
manager.GET("http://hoge/sample.json", parameters: nil,
    success: { (operation: AFHTTPRequestOperation!, responseObject:AnyObject!) in
        println("response: \(responseObject)")
    }, failure: { (operation: AFHTTPRequestOperation!, error: NSError!) in
        println("error: \(error)")
    })

POSTでパラメータを設定する場合

let manager = AFHTTPRequestOperationManager()
var param:Dictionary<String, String> = ["param1" : "value1", "param2" : "value2"]
manager.POST("http://hoge/sample.json", parameters: param,
    success: { (operation: AFHTTPRequestOperation!, responseObject:AnyObject!) in
        println("response: \(responseObject)")
    }, failure: { (operation: AFHTTPRequestOperation!, error: NSError!) in
        println("Error: \(error)")
    })

レスポンスがJSONではない場合

let manager = AFHTTPRequestOperationManager()
manager.responseSerializer = AFXMLParserResponseSerializer()

としてAFHTTPResponseSerializerをセットしておきましょう。 デフォルトがAFJSONResponseSerializerのためJSONのパースエラーになります。

レスポンスがXMLの場合

let manager = AFHTTPRequestOperationManager()
manager.responseSerializer = AFXMLParserResponseSerializer() as AFHTTPResponseSerializer
// 許可するContentTypeの設定が必要
manager.responseSerializer.acceptableContentTypes = NSSet(object: "application/rss+xml")

結果のresponseObjectがNSXMLParserなので自前でパースする必要があります。 パースするSerializerを自前で用意してもよいでしょう。

リクエストパラメータをJSONにしたい場合

let manager = AFHTTPRequestOperationManager()
manager.requestSerializer = AFJSONRequestSerializer()

上記ようにAFJSONRequestSerializerを設定します。

通信ログについて

通信の詳細なログが見たい時はAFNetworkActivityLoggerを別途インストールするとリクエストヘッダー、レスポンスヘッダーもログ出力してくれます。

platform :ios, '7.0'
pod "AFNetworking", "~> 2.0"
pod "AFNetworkActivityLogger", "~> 2.0"

PodfileにAFNetworkActivityLoggerを追加してインストールします。

AppDelegate.swift'の'application:didFinishLaunchingWithOptions::にログを開始する処理を記述します。

AFNetworkActivityLogger.sharedLogger().startLogging()

ログレベルをAFLoggerLevelDebugにすればリクエストヘッダー、レスポンスヘッダーを含む通信のやりとりをログに出力できます。

AFNetworkActivityLogger.sharedLogger().level = .AFLoggerLevelDebug

キャッシュポリシー、タイムアウトについて

AFHTTPRequestOperationManagerを使用せずAFHTTPRequestOperationを直接使用する場合はcachePolicyの設定ができます。

let URL = NSURL.URLWithString("http://hoge/sample.json")
let request = NSURLRequest(URL: URL, cachePolicy: .ReloadIgnoringLocalCacheData, timeoutInterval:60.0)
let operation = AFHTTPRequestOperation(request: request)
operation.responseSerializer = AFJSONResponseSerializer()
operation.setCompletionBlockWithSuccess({ (operation: AFHTTPRequestOperation!, responseObject:AnyObject!) in
    println("response: \(responseObject)")
}, failure: { (operation: AFHTTPRequestOperation!, error: NSError!) in
    println("Error: \(error)")
})

operation.start()

セキュリティポリシー

テスト環境などでSSL通信をする際にオレオレ証明書(自己署名証明書)を使っている場合は、AFHTTPRequestOperationManagerオレオレ証明書を許可する設定を行うことで通信できます。

let manager = AFHTTPRequestOperationManager()
manager.securityPolicy.allowInvalidCertificates = true
// 以降は通常通りAFHTTPRequestOperationManagerを使って通信を行う

まとめ

NSURLSessionの登場によって今後はNSURLConnectionがベースとなっているAFHTTPRequestOperationManagerではなくAFHTTPSessionManagerが主流になるのでそちらについても書きたいと思ったのですが時間の都合上、別の機会に書くことにします。

Swiftに書き換えた印象として、Swiftはスクリプト言語の経験がある方ならすんなり入れるはずです。 Objective-CのBlocks構文などとても書きづらく辛さしかなかったのですが、Swiftにシフトすればそんな問題からも解放されるし、いいこと尽くめではないかと思います。 もう少しSwiftのノウハウがたまってからでもよいかもしれませんが、個人的には新規アプリはSwiftで書いてしまう方が開発効率上がってよいと思いました。

WWDCの予想しながら気になることを書いてみる #expectWWDC

今回はまわりで参加する人が多い気がしてなんかそわそわしている・・・。 というわけで弊社エンジニアも参加するWWDCの予想!というよりただ欲しいものを書いてみました。

みなさんも是非予想してみてください。 http://developer.hatenastaff.com/entry/2014/05/28/174653

最近のiPhoneはいろいろ出尽くした感あるので、 新しいハードウェアに期待したいですな。

  • ハードウェア

    • iWatch早くほしい!(コレは無いな・・・)
    • MacBook Air Retinaもほしいからもういい加減発表してほしい
    • Apple TVは最近買ったばかりだから発表あってもスルーで
  • ソフトウェア

    • iOS8の発表(ほぼ間違いないので予想関係ない・・・)
    • アプリ間の連携強化(AndroidのIntent並みに使いやすくなってほしい)
    • アップ独自の決済サービス
    • ネームスペース(これなんでないんだろ?よくわからん・・・C++にすらあるのに。この際Objective-C 3.0出ろ)
    • UITextViewをなんとかしろ!(こういうの地味に一番大事だよ)
    • TestFlightの機能強化(配布がもっと楽になってほしい)

とうだうだ書いたけど、なんか気持ちが晴れないので来年は絶対行くぞ!

【岐阜】第1回iPhoneアプリ開発勉強会に参加してきました #iOS_nagoya

初回となる岐阜でのiPhoneアプリ開発勉強会に参加してきました。

滋賀から岐阜までは電車の乗り継ぎなど含めると2時間くらいかかってしまってしんどかった・・・。 懇親会に参加したので車は無理だったんですが、車ならもうちょっと気楽に行けそうです。

しゃべる気なかったんですが、LT大会やるということで急遽参加させてもらいました。

技術的な話ではなくてアプリ広告について軽く話しをしました。 タイトルはちょっと釣りっぽかった・・・。

でも5分で話すお題としてはむずかしくて、かなり早口でしゃべってもちょっと時間足りなかった感じで反省点多かったです。

勉強会自体は自己紹介しあったりする時間もあって終止ほのぼのした感じで楽しめました。

通常は名古屋で定期的にやってるようなので都合がつけばまた参加したいと思います。

参加されたみなさんお疲れ様でした!

Google Tag Manager for iOSについて調べてみた

Google Tag Manager(以下GTM)に自動イベントトラッキングなるものがあると聞き、 iOSアプリにも導入してみようと調査してみました。

自動イベントトラッキングとはWebではHTMLにイベント毎に特別な記述を書かなくても、 トラッキングすることが可能になるというすばらしい機能です。

これが実現できればアプリ審査を通さなくても いつでもトラッキング情報の変更ができるという正に夢のようなツールです。

期待に胸を膨らませながら調べ続けて数時間、一切情報を得られないまま・・・潔く諦めましたw 結論からいうとiOS SDKにはこの機能は無いみたいです。

ドキュメントにかじり付いて読んでみたんですが、 自動イベントトラッキングに関する情報は一切登場しませんでした。

https://developers.google.com/tag-manager/ios/v3/#intro

Web版の方にはありますね・・・。 興味ある方は下記をご覧ください。

https://support.google.com/tagmanager/answer/3420054?hl=en

ドキュメントに書いてあったGTMで管理できる項目は下記のようなものくらいです。

  • 様々なUIの設定や表示する文字列など
  • アプリ内のサイズ、場所、広告の種類
  • ゲームの設定

簡単に言ってしまえばアプリ内の設定情報などを持つのではなく Google Tag Managerで設定情報を取得するようにして 変更したくなったら再ビルドすることなくWebの管理ツールでできるよって感じです。 その他にはGTMから条件を設定して、その条件を満たしたイベントのみを送信するとかでしょうか。

使えない、全然使えないよ!って言いたくなりますが、 再ビルド無しで設定値などの管理ができるのはそれなりのメリットはあると思うので良しとしましょう。

せっかくなので暇な時に使い方でも書いておきます。

Cocoa勉強会関西 #55 に参加してきました #cocoa_kansai

Cocoa勉強会関西に初めて参加してきました。 せっかく参加するので20分ほどいただいて、前から気になっていたMagicalRecordについて軽く話しをさせてもらいました。

その時使った資料です。

もう10年近くやっている勉強会ということもそうですが、Mac開発者の方が結構おられるようでiOSアプリから入った自分からすると結構驚きでした。

地元広島では中々こういった勉強会というのもなかったので、いい刺激になっていいなと思います。

@es_kumagaiさんのコメントに絵文字が使えるという話が妙に印象に残ってますw

懇親会に参加できなかったのが残念なので、次回も是非参加しようと思います。

勉強会に参加された皆様お疲れ様でした。 次回も宜しくお願いします!

ソースコードを一切書かなくてもアニメーション処理ができるCanvasがおもしろい

f:id:sakahara:20140405233909p:plain

概要

ソースコードを一切書かな くてもアニメーションのエフェクトをUIViewに設定できるライブラリです。ちょっとしたアニメーションさせたい時などに使えそうです。

http://canvaspod.io/

種類はまだ多くないですが、アニメーション処理をUIViewControllerから完全に分離できるのでコンセプトはとてもよいと思います。 現在サポートしているアニメーションの種類については上記サイトで確認できます。

導入手順

CocoaPodsでインストールできるのでPodfileを作成します。

platform :ios, '7.0'
 
pod 'Canvas', '~> 0.1'

次にインストールです。

pod install

導入は以上でオッケーです。

アニメーション設定手順

アニメーションに関する設定はInterface Builderで行うので、その設定方法を紹介します。 まず下記の項目を設定します。

Key Path Type 説明
type Number アニメーションの種類
duration Number アニメーションを実行する時間
delay Number 設定した時間経過後にアニメーションを実行
pauseAnimationOnAwake Boolean チェックすると初期表示時にアニメーションを実行しない

アニメーションを実行したいUIViewのクラスをCSAnimationViewに変更します。 設定内容は下記を参考にしてください。

f:id:sakahara:20140405233258p:plain

アニメーション実行手順

CSAnimationViewを設定したUIView、またはその親となるUIViewのstartCanvasAnimationメソッドを実行することでアニメーションさせることができます。

[self.animationView startCanvasAnimation];

このメソッドは指定したUIViewのSubview中でCSAnimationViewが設定されているものがあれば全て実行してくれます。 下記を参照してもらえばstartCanvasAnimationメソッドが実行されているのが確認できるので興味がある方は見てみてください。

https://github.com/CanvasPod/Canvas/blob/master/CanvasLibrary/CSAnimationView.m

実際に使用するアニメーションタイプはこちらのソースコードを参照してください。

https://github.com/CanvasPod/Canvas/blob/master/CanvasLibrary/CSAnimation.h

またアニメーションの実装はCSAnimationに定義してあるので、どのような処理をしてるかはここを見れば確認できます。

https://github.com/CanvasPod/Canvas/blob/master/CanvasLibrary/CSAnimation.m

まとめ

アニメーション処理とUIViewControllerを完全に分離できるのでメリットは大きいと思います。 課題としてはアニメーションの種類が少ない点と独自で作ったアニメーションをこのライブラリに手をいれずに 追加する方法が公式に用意されていない点が上げられます。(この部分はCAAnimationクラスを継承するなどで対応できるかもしれません) この辺は今後のアップデートに期待するか、独自で作ってみてもよいと思います。