Xcodeのプラグイン管理ツール「Alcatraz」を使う

あまりにも自分好みのColor Schemeがなかったので、
Xcodeプラグイン管理ツール「Alcatraz」を使って、愛するSolarizedDarkに設定してみた。

Alcatrazのインストール方法

curl -fsSL https://raw.github.com/supermarin/Alcatraz/master/Scripts/install.sh | sh

これたたいてしばらく経つと、ビールがカチンと完了します。

Xcode > Window にPackageManagerが追加されている

メニュー>Windwowの中に「Package Manager」が追加されているので、
どんどん自分のエディタを作り上げていきましょう。
私も無事愛するSolarizedDarkに設定しました。これで安心して眠れます。

Swiftでシングルトン

Swift2.0でも当然シングルトンが書きたい。
[環境]iOS SDK 9.0, Xcode7.0.1

シングルトンの書き方

参考: http://krakendev.io/blog/the-right-way-to-write-a-singleton

class Singleton {
    static let sharedInstance = Singleton()
    private init() {} 
}

検証

初期化メソッドのinitがprivateになっているので、クラス内でしかインスタンスが生成できません。 以下のようにインスタンスを生成すると、当然警告が出て作れません。

let sigleton = Singleton()

非常にシンプルなコードで良いですね。
ちなみに記事を書いた時点では、動作確認していません。(おい)

SwiftでWebView(1)

題通り、SwiftでWebViewを表示させるという基本的なことをやってみました。
[環境]iOS SDK 9.0, Xcode7.0.1

いろんなWebView

Objective-CにてUIWebViewをちちくり回していた時代とは異なり、

  • WKWebView
  • SafariViewController

という二つのWebViewが用意されていました。

WKWebView

iOS8から導入のWebKitFrameWorkのクラス。
UIWebViewよりも高速な処理を実現できるWebViewだそうです。
参考: http://grandbig.github.io/blog/2014/09/23/wkwebview2/

SafariViewController

iOS9から追加された新たなクラス。 以下の点が今までのWebViewとは異なる。

SafariのUIを使用できる
Safariツールバープログレスバーを利用することができる。

Safari の機能を使用できる
Safari AutoFill (クレジットカード、パスワード、連絡先の自動入力)
Safari Reader (サイトのテキストだけを抽出)
Content Blocking(コンテンツ制御 例:広告ブロック) など

・クッキーなどのデータをSafariと共有できる

WKWebViewでYahooを表示して見る

まずはじめにWKWebViewを使ってYahoo(http://www.yahoo.co.jp/)を表示してみた。
注意点は、iOS9より実装されたATS(App Transport Security)。
iOS9ではHTTPSでの通信が推奨されているため、
HTTP通信を行う際には、Info.plistにATSによる制限を回避するキーを含めてあげる必要があります。

Info.plist

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

ViewController

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate {
    
    var _webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        _webView                    = WKWebView(frame: self.view.bounds)
        _webView.navigationDelegate = self
        _webView.UIDelegate         = self
        self.view.addSubview(_webView)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        
        let url = NSURL(string: "http://www.yahoo.co.jp/")
        let request = NSURLRequest(URL: url!)
        _webView.loadRequest(request)
    }
}

ATSを知らなかったので、
たかだか、やほおも表示させられない腕の落ちっぷりに焦りました。 ブランクは怖いですね。

SwiftでFacebookログイン

SwiftFacebookログインを実装する方法をまとめました。

環境: MacOSX Yosemite 10.10.5, iOS SDK 9.0, Facebook SDK v4.7.0
参考サイト: http://blog.hello-world.jp.net/ios/3745/

1. Facebook SDKをDLする

FacebookSDKをダウンロードして、~/Documents/FacebookSDK に移動する。

2. Facebook App を作る

Facebook開発者 - 開発者向けFacebookにアクセスして、MyApps > Add a New App を選択して、Facebook Appを作る。

3. Facebook App の設定を変更する

  1. Facebook Appのダッシュボードにて左欄から「Settings」を選択する
  2. Settings画面の「Add Platform」をクリックし、iOSを選択する
  3. Bundle IDフィールドに、XcodeプロジェクトのBundle Identifierを入力する
  4. Single Sign On を YESに変更する
  5. Save Changes を押す

ここまでは、はまる箇所もなくスムーズに進められるはずです。

4. XcodeプロジェクトにFacebookSDKを追加する

XcodeのProject Navigator(command + 1)に、~/Documents/FacebookSDK内の 「FBSDKCoreKit.framework」「FBSDKLoginKit.framework」「FBSDKShareKit.framework」を追加する。 そして、Build Settings > Search Path に 「~/Documents/FacebookSDK」を設定する。(下図) f:id:umadash:20151011100123p:plain

5. Info.plistに追記する

Project Navigator(command + 1)の、Info.plistを右クリックしてOpen As > Source Codeを選択する。
そして、下のコードを追記する。 * {FACEBOOK_APP_ID},{Your App Name}には、上で作成したFacebook AppのIDと名前を入力する。

<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>fb{FACEBOOK_APP_ID}</string>
    </array>
  </dict>
</array>
<key>FacebookAppID</key>
<string>{FACEBOOK_APP_ID}</string>
<key>FacebookDisplayName</key>
<string>{Your App Name}</string>
<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>facebook.com</key>
    <dict>
      <key>NSIncludesSubdomains</key> <true/>        
      <key>NSExceptionRequiresForwardSecrecy</key> <false/>
    </dict>
    <key>fbcdn.net</key>
    <dict>
      <key>NSIncludesSubdomains</key> <true/>
      <key>NSExceptionRequiresForwardSecrecy</key>  <false/>
    </dict>
    <key>akamaihd.net</key>
    <dict>
      <key>NSIncludesSubdomains</key> <true/>
      <key>NSExceptionRequiresForwardSecrecy</key> <false/>
    </dict>
  </dict>
</dict>
<key>LSApplicationQueriesSchemes</key>
<array>
        <string>fbapi</string>
        <string>fb-messenger-api</string>
        <string>fbauth2</string>
        <string>fbshareextension</string>
</array>

6.AppDelegate

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        
        return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
    }
    
    func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
        return FBSDKApplicationDelegate.sharedInstance().application(
            application,
            openURL: url,
            sourceApplication: sourceApplication,
            annotation: annotation)
    }

    func applicationDidBecomeActive(application: UIApplication) {
        FBSDKAppEvents.activateApp()
    }

7.ViewController

import UIKit
import FBSDKLoginKit

class ViewController: UIViewController, FBSDKLoginButtonDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let btn = FBSDKLoginButton()
        btn.center = self.view.center
        btn.delegate = self
        btn.readPermissions = ["public_profile", "email", "user_friends"]
        self.view.addSubview(btn)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func loginButton(loginButton: FBSDKLoginButton!, didCompleteWithResult result: FBSDKLoginManagerLoginResult!, error: NSError!) {
        // ここいらはお好きなように

        if ((error) != nil)
        {
            // Process error
        }
        else if result.isCancelled {
            // Handle cancellations
        }
        else {
            // If you ask for multiple permissions at once, you
            // should check if specific permissions missing
            if result.grantedPermissions.contains("email")
            {
                // Do work
            }
        }
    }
    
    func loginButtonDidLogOut(loginButton: FBSDKLoginButton!) {
        
    }
}

気になるエラーが・・・

ログインボタンを押すと、以下のような警告がコンソールに吐き出された。 検索しても解消する方法は見つからなかったため現状放置している。

-canOpenURL: failed for URL: "fbauth2:/" - error: "(null)"