iOSアプリ with Swift 第1回 – Swiftの文法編 –

なんかこう、iOSアプリを作ろうとするにあたって、Swift独特の文法というか、書き方だけをまとめたようなのがパッと見つからない気がしたので書いてみた。
他のプログラミング言語をやってきて、Swiftをちょっとやってみよう、とか考えている人はだいたいこの辺を知っておけば良いのではないだろうか。

いや、まぁ、以下に書いたのが全部Swift独特か、って言ったら全然そんなことはないんだけど、Swift特有の安全さ、というのを武器にして書くには以下のことを理解しておくと、Swiftらしいコードが書けるのではないかと。

ちなみに、基本文法は押さえている前提で書いているので、まず基本文法はがあやふやな人は、まずは公式のSwiftのチュートリアルをやったほうが良い。
The Swift Programming Language (Swift 3.1): A Swift Tour

本日のお品書き

Optional

すべての基本。
optionalとはそれがnilになり得る変数、または状態のこと。
nilになり得ない変数、状態のことは、 un-optionalと言う。

すべてのオブジェクトにはoptionalか、un-optionalか、が決まっているし、自分で変数を定義するときは決めなければならない。
un-optionalの変数はoptionalの変数に入れることはできるが、optionalの変数はun-optionalに入れることができない。
Swiftはこの仕組を最大限に活用して、ぬるぽで死ぬ危険性を回避して安全に書くことが出来る。

var hoge: String? = "hoge"
var fuga: String = "fuga"

hoge = nil
fuga = nil // Error

hoge = fuga
fuga = hoge // Error

強制的にoptionalの変数をun-optionalの変数に入れたければ、optionalの変数のあとにつづけて!をつければ良い。
これをoptional変数のunwrapという。
安全にwrapされていたものを強制的に外す(unwrap)イメージ。

fuga = hoge! // unwrap

もし上記のhogeが動作上nilになった場合は、アプリはクラッシュする。
したがって、基本的にunwrapする場合は、明らかにnilになり得ないような場合にのみ限定して使うべき。
それ以外の場合は、後述するようにguard構文を使って回避するべし。

func

なんてことはない。
Swiftにはenum, struct, classなどのオブジェクトを作ることができるが、class以外のオブジェクトにもメソッドを追加することができる。地味に便利。

enum UserRole {
    case user
    case admin
    case owner

    func whichRole(roleNumber: Int) -> UserRole? {
        switch roleNumber {
        case 0:
            return .user
        case 1:
            return .admin
        case 2:
            return .owner
        default:
            return nil
        }
    }
}

struct User {
    let id: Int
    let name: String
    let role: UserRole
    let email: String
    let isPurchased: Bool
    let expired: NSDate

    func isAvailablePurchasedProduct() -> Bool {
        return isPurchased && expired.timeIntervalSinceNow > 0
    }
}

あれ、じゃあstructとclassって同じじゃね、って思うけど、地味にそれぞれできることが違う。
classはオーバーライドできるけど、structはできなかったり。
詳しくは下記。
Swiftのクラスと構造体の使い分けについてのメモ

それぞれの役割を考えて使い分けるべし。

enum & switch – case

enumとswitch – case文のあわせ技。
swiftのswitch – case文はInt以外にもString、enum等にも使うことができる。
特にenumを使ったswitch – case文はSwiftではよく使われる。

enum UserRole {
    case user
    case admin
    case owner

    func getUserRoleNumber() -> Int {
        switch self {
        case UserRole.user:
            return UserRole.user.hashValue
        case UserRole.admin:
            return UserRole.admin.hashValue
        case UserRole.owner:
            return UserRole.owner.hashValue
        }
    }
}

set, get, willSet, didSet

swiftにはどんな変数にもsetter、getterメソッドを簡単に追加することが出来る。

var _fugafuga: String?
var fugafuga: String {
    set(value) {
        _fugafuga = value
    }
    get {
        if _fugafuga == nil {
            return "unknown"
        } else {
            return _fugafuga!
        }
    }
}

さらに便利なことに、willSet、didSetという、変数への代入直前、代入直後のコールバック関数を簡単に追加することが出来る。

var hogehoge: String = "Hogehoge" {
    willSet(newValue){ // 変更後のhoge
        print(hoge)    // 変更前のhoge
    }
    didSet(oldValue) { // 変更前のhoge
        print(hoge)    // 変更後のhoge
    }
}

大変に便利。
特に特定の値の変化に同期してViewにも変更を加えたい時に、didSetをよく使う。
あんまり多用すると処理の順番が追えなくなって泣きを見るので、気をつけるべし。

lazy

lazyを付けたプロパティは、そのプロパティが必要とされるタイミングで値が参照される。

var initialRole = UserRole.admin
class UserManager {
    lazy var currentUserRole = initialRole
}

let manager = UserManager()
initialRole = UserRole.user
print(manager.currentUserRole) // lazyをつけないとadmin、つけるとuserになる

便利そうなんだけど使い所がわからなくて使っていない件。

guard

if文の逆みたいなものだけど、optional変数を扱うSwiftならではの構文。
Swift以外でif文でoptionalを判断する場合、普通は次のように書く。

var optionalValue: Int?
if optionalValue != nil {
    // nilチェック済みの処理
} else {
    throw NSError(domain: "optionalValue is optional", code: 0, userInfo: nil)
}

これをguardを使うと次のようになる。

guard optionalValue != nil else {
    throw NSError(domain: "optionalValue is optional", code: 0, userInfo: nil)
}

// nilチェック済みの処理

if文だとnilチェック済みの処理が一段インデントした箇所に書くことになるが、guard文だとそれがない。
なので複数の値をnilチェックしたい場合、if文だとインデント地獄に陥るが、guardだとそれがない。便利。
ちなみに上記guard文は下記のようにも書ける。というか、下記のように書くことが多い。

guard let _optionalValue = optionalValue else {
    throw NSError(domain: "optionalValue is optional", code: 0, userInfo: nil)
}

// nilチェック済みの処理 : _optionalValueは Int? ではなく、 Int になるので、以降の処理はこれを用いる

これはnilチェックをしつつ_optionalValue変数に入れているので、guard文以降は_optionalValueをIntとして扱って処理をすることが出来る。
optionalValueをわざわざunwrapして処理とかしなくて良い。

また、この書き方は以下のように型チェックにも応用できる。

var anyValue: Any = "hogehoge"
guard let stringValue = anyValue as? String else { // anyValueがStringとして扱えるなら。
    throw NSError(domain: "anyValue is string", code: 0, userInfo: nil)
}

// 以降はstringValueを使って処理をする

とっても便利。

defer

スコープを抜けた時に必ず行う処理を記述することができる。
先のguard文と合わせてよく使われる…ようだ。
便利そうだけど使い所がまだつかめてなくて、個人的にはあまり使っていない。
いや、実際使いそうなんだけど、非同期処理がはさんであるとdefer使えないし…。
とにかく以下の用に使うようだ。

func hogeFunc(hoge: Any) throws -> Bool {
    defer {
        print(hoge) // NSErrorを投げたり、returnする値にかかわらず必ず実行される処理
    }

    guard let _hoge = hoge as? String else {
        throw NSError(domain: "hoge is string", code: 0, userInfo: nil)
    }

    if _hoge == "Hogehoge" {
        return true
    } else {
        return false
    }
}

Generics

まぁ、どこにでもあるジェネリクス型。
これも多用すると元の型がわかんなくなるので注意。

class ObjectCountedList<T> {
    let count: Int
    let list: [T]
    init(count: Int, list: [T]) {
        self.count = count
        self.list = list
    }
}

let user = User(id: 0, name: "hoge", role: UserRole.user, email: "hoge@example.com", isPurchased: true, expired: Date())
let userObjectList = ObjectCountedList(count: 1, list: [user])

let url = URL(string: "https://www.google.co.jp")
let urlObjectList = ObjectCountedList(count: 1, list: [url])

Extension

swiftには既存のオブジェクトを拡張してメソッド等を追加することができるextensionというのがある。
たとえば既存のArrayのオブジェクトに対して、シャッフルするメソッドを追加するには以下のように書く。

extension Array {
    mutating func shuffle() {
        for i in 0..<self.count {
            let j = (self.count - 1) - i
            let k = Int(arc4random_uniform(UInt32(j + 1))) // 0 <= k <= j
            if j != k {
                swap(&self[k], &self[j])
            }
        }
    }
}

余談だが、extensionを使って既存のクラスに便利メソッドを頑張って実装したものの、実際にはすでに似たようなやつが公式で実装されていたことがよくある。かなしい。

Protocol

javaでいうinterfaceみたいなもの。
オブジェクトの振る舞いを予め規定することができる。
後述のDelegateモデルでよく使われる。

protocol HogeProtocol {
    func hoge()
}

class Hoge: HogeProtocol{
    func hoge(){ // HogeProtocolで規定されているhogeメソッドを実装しないとコンパイルエラー
        //何らかの処理
    }
}

Protocol + Extension

protocolにデフォルトの処理を実装することができる。
これを書いておくと、毎回protocolのメソッドを実装しなくてもよくなる。

protocol FugaProtocol {
    func fuga()
}

extension FugaProtocol {
    func fuga(){
        //何らかのデフォルトの処理
    }
}

class Fuga: FugaProtocol {
    // fugaメソッドを実装しなくてもエラーは出ない
}

Delegate(委譲)パターン

Protocol + Extensionの一番良く使う例。
UIKit等の基本的なコンポーネントでよく使われている。
あるオブジェクトAで複数のコールバック関数を設定したい時、予めprotcolで実装したいコールバック関数を規定しておき、そのprotcolを適用したオブジェクトBを実装、オブジェクトBをオブジェクトAのプロパティに追加して、オブジェクトA内の処理内でプロパティに追加されたオブジェクトBのメソッドを実行することで、コールバック処理を実行する方法。
ややこしいのでコードを書くと以下のようになる。

// 予めprotocolで実装したいコールバック関数を規定
protocol ObjectADelegateProtocol {
    func callbackA()
    func callbackB()
}

// ObjectBを追加するプロパティ、delegateを追加。delegateプロパティはObjectADelegateProtocolが適用されているはず。
class ObjectA {
    var delegate: ObjectADelegateProtocol?

    func methodA(){
        // 処理
        delegate?.callbackA() // delegateプロパティはObjectADelegateProtocolが適用されているので、callbackAメソッドがあるはず。
    }

    func methodB(){
        // 処理
        delegate?.callbackB() // delegateプロパティはObjectADelegateProtocolが適用されているので、callbackBメソッドがあるはず。
    }
}

// ObjectBにprotocolを適用
class ObjectB: ObjectADelegateProtocol {
    func callbackA() {
        // コールバック処理A
    }

    func callbackB() {
        // コールバック処理B
    }
}

let objectB = ObjectB()
let objectA = ObjectA()
objectA.delegate = objectB
objectA.methodA() // callbackA()が呼ばれる
objectA.methodB() // callbackB()が呼ばれる

ObjectAの処理の一部をObjectBに委譲しているので、Delegate(委譲)パターン。

こんなややこしいことして何が嬉しいんだよ、って感じだけど、これをやることによってObjectADelegateProtocolが適用されてさえいれば、別にObjectBに限らず他のオブジェクトでも委譲出来る。
これによって特定のオブジェクトへの依存度を減らすことができる。

UIKitは結構このパターンが使われていて、たとえばUITableView、UICollectionView、UITextField、UIPickerView…等、各種基本的なコンポーネントにはだいたい使われているので、覚えておいたほうが良い。

Read More

try! Swift Tokyoに参加してみた(1日目)

try! Swift Tokyoに参加してきました。

カンファレンスのネームプレート。try! Swift Birdちゃんが可愛い。
Twitterで名前を募集している。

カンファレンスの様子

僕はしばらく大きなカンファレンスに出ていなかったのですが、アプリも作ってるし、Swiftのイベントがこの時期にあることを知って参加することにしました。

参加してざっくり感じたこと。

  • 参加者は結構多い。
  • 同時に複数の場所で講演をやることはないので、見たい講演は必ず見れる。
  • 同時通訳の精度がすごい。
  • 朝ごはんと昼ごはんが出るよ!
  • 講演の大半が英語なので、ある程度英語ができるともっと楽しいと思う。(自分はできない)

こんな感じです。
他の言語のカンファレンスと比較して、参加料が高くしかも英語がメインな感じなので、ちょっと敷居は高いのですが、それだけの価値は十分にあると感じました。
特に同時通訳の精度が高く、専門用語も適切に翻訳できてて非常に聞きやすかったです。
…同時通訳レシーバーがあることを最初知らず、最初の2講演を詳しく理解できなかったのが悔やまれるところ。

以下、1日目のまとめ。


Swift開発者が知りたかったけど聞きにくい機械学習のすべて

  • 機械学習とは、男の場合の平均値、女の場合の平均値、体重がこれぐらいの人の平均値、こういう職業の人の平均値…etc等、属性ごとに平均値を出すみたいなもの。
  • 機械学習はUIデザインに似て、ちゃんんと動くか、それが正しいのか証明できないのが難しいところ。
  • 機械学習は、TensorFlowのチュートリアルや、ドキュメント、本が揃っている
  • python on the server, Swift in the hand

Swift on Android

  • C言語はすべてのプラットフォームで動く。なのでC言語にしちゃえばよくない?
  • Android NDK (native development kit)というAndroidをC言語で書くSDKがある。
    • AndroidはOSがなかなか統一されないので、Cの標準ライブラリも微妙に違っててやりづらい
    • Hell Problemだぜ!
  • Blurrr SDKというのを作った
    • Macアプリとか、Windowsアプリとかも動くぜ!

SwiftのPointy Bits

  • Swiftって安全な言語だよね。
  • でも安全じゃなく書けるよ。
    • unsafePointerを使おう
  • Unsafe Pointerは次の利点がある。
    • C言語のAPIが使える
    • 速度が速い
      • ただし安全性とのトレードオフはあるので注意。

アプリを新次元に導く3D Touch

  • Appleは3Dタッチに5年もの開発を費やしたんだからみんな使おうよ!
  • 3Dタッチを使う理由
    • ユーザーのショートカット
    • App Storeで3Dタッチ対応アプリのところに出せる
  • 3Dタッチでできること
    • ホーム画面のクイックアクション
    • Peek & Pop – 事前にページを開く前にプレビューをする等によく使われている
    • Notification Content Extension
      • 通知画面にアクションを追加できる
  • 3Dタッチは古い端末に対応していないので、長押しなどのアクションを代用して、同じ機能を古い端末で対応するようにしたほうが良い

Pixcels、プロセスと情熱

  • 主に開発おモチベーションをどう保つかという話
  • 講演者は去年あたりから、Blogを始めたり、様々なハッカソンに参加したりして精力的に活動してきたらしい
  • (あまり興味がなかったのでちゃんと聞いてない…)

毎日リアクティブ

  • シナリオ駆動にすることでステートを減らすというアプローチ
  • Swiftでリアクティブをやる方法
    • RXSwift
    • ReactiveSwift
    • etc…
  • 既存のどのような処理に適用していくか
    • MVVMモデル
    • async operation
  • observerパターンに適用するのがよくある
  • トレードオフ
    • デバッグがやりづらい
      • ログイベントを一連のストリームで発火させることでデバッグをやりやすくする
    • フランクにやりすぎるオーバーヘッドが大きくて死にやすい
    • 変更時の影響範囲のわかりにくさ
    • 多用するとカオスになりがち
  • 大事なのは、必要な箇所だけを使うということ

Unsafe Swiftの安全性(LT)

  • Unsafeで扱いたいことがある
    • C言語で書きたい
    • 速度をあげた
    • Lowレベルにアクセスしたい
  • https://www.raywenderlich.comでUnsafe Swiftについて書いた
  • ちゃんとした書き方をすれば、Unsafe Swiftでも安全性を担保することはできる、らしい…。

クックパッドアプリのテストを味わう

  • UITestにフォーカスした話
  • Cookpadアプリ
    • グローバルアプリと日本アプリの2つがある。統合はまだしていない
    • UIコンポーネントは複数大きく変えている
    • だいたい10万行ぐらいある
    • 以前は2週間、最近は1ヶ月毎にアップデートしている
  • kano-model という品質モデルがある
    • Attractive – Must-be Qualityの2つのパラメータ
    • Diachronic Quality for mobile
  • UITestのやり方
    • テストを書いてからリファクタリングをする
  • UITestの実際
    • マニュアルテストは簡単に出来る、ユニットテストはめんどくさい
    • でも理想はその逆
    • Cookpadでは2015年〜2017年にかけてUITestを初めてCrash率を下げ続けた
  • UITestの書き方
    • シナリオを書く
    • シナリオをRubyコードに変換
    • Appiumで実行
  • Appium
    • XPATHはOSのフレームワークにかなり依存している
    • テストをUIレベルからメソッドレベルに移動することが大事
  • image diffを見せるようにした。
  • 数ヶ月前にSwiftを実装し始めた
    • テストがあるので安心してSwiftの実装出来る
  • テストの自動化は、エンジニアのスキルとはまた違ったスキルセットが必要
  • (質問)Appium使ったことあるけどめっちゃ時間かかるんだけどどうしてAppiumなのか?
    • システムアラートを制御することができる
    • 外部の環境をいじれるのでこれを選択している
    • コミット毎にテストを回しているわけではない
  • (質問)時間がかかるboundaryのテストの代替テストはどういうものを考えたか
    • よくある文字入力などのバリデーションにかかわるテストは、UIテストではやらず、ユニットテストで担保する

データレイヤを分離する

  • MVAモデル(Mininmum Viable Architecture)という考え方
    • 必要最小限のアーキテクチャー
  • CoreDataやRealmObjectはスレッドを意識したりしないといけないけど、Viewレイヤーでそれを意識したくはない。
  • DTOモデルに変換するというアプローチ
  • Plain old swift Object(POSO)で書く
  • CoreDataやRealmObjectからDTOモデルに変換する
  • デメリット
    • 自分たちでモデルを管理しないといけない
    • 変換処理を書く必要がある
  • (質問)DTOに変換するのはオーバーヘッドがあるわけだけど、その線引きをどうするか
    • チームの規模が大きかったら、全員が全員スレッドとかを考えなきゃいけないとめんどくさいので、そういう視点で線引をどうするか考える

UIをSwiftlyに書く

  • Resultライブラリを使う
    • API読み込み時に、成功時のパターン、失敗時のパターン、失敗したけどデータを受信したパターン、通信は成功したけどデータが不正のパターン…等色々考えると大変
    • Resultライブラリを使って、成功/失敗に応じて処理を分ければ2つ考えるだけでよい
  • AutoLayout
    • storyboard、xibではIDベースでコンポーネントが管理されている
    • プログラマティックにAutoLayoutを実現するのは大変
    • Autolayoutを書くとよくわからない
    • Cartograpyというライブラリを使う
      • Autolayoutをわかりやすいコードに書けるラッパーライブラリ
  • ステート管理
    • APIはロード中/成功/失敗3つの主要なステートがある
    • コレをboolで扱う
      • このパターンはisError && isLoadingのステータスの場合がよくわからなくなる
    • enumとswitchステートメントで管理すれば良い
  • コード共通化
    • ProtocolとProtocol extensionを利用する

SwiftのWeb APIとアプリをともに構築する

  • API設計
    • Paginationの例
      • Get /posts?page=2
        • 各ページでのpostコンポーネントの担保
      • Get /posts?before=2
        • このようにすることで、ID 2のページの前のページの要求をすることができる
    • APIのバージョニング
      • /v1/posts
    • REST
    • APIの問題点
      • クライアントのアップデートが必要
        • Web Linking RFC5988を使うというアプローチ
        • SwiftではWebLinking.swiftというライブラリがある
        • application/hal+json, application/vnd.siren+jsonという方式で書くと、APIのアップデートに耐えうる実装にできる
        • さらにHypermedia APIを使うことで、ビジネスロジックをバックエンドに持ってくるができる
  • APIを実装する上で使えるSwiftのウェブフレームワーク
    • 主にfrank, kitura, vaporの3つが有名
    • frankは軽量なフレームワーク
  • テスト
    • linuxでXCTestを使える
  • デプロイ
    • herokuが楽
    • IBMのブルーミックスというのもある
    • 他にもDockerを使ったり、もちろんマニュアルデプロイでも良い
  • ロギング
    • paperteailを使ってプリントしたエラーを取得する等

楽しく便利なSwiftチャットボット

  • 去年は色んなチャットボットサービスが出て来た
  • まだまだ微妙な感じ
  • LINEで言語学習ボットを作ってみた
  • グーグル翻訳のAPIを使う
  • ボット上で言語登録ができる
  • Spaced Reptirionで言葉を覚えたか確認する
  • ボットの作り方
    • 制限のあるインタラクション
      • テキストとかスタンプとか画像とか動画とか、全部に対応しようとしない
    • とにかくシンプルにする
    • 他のサービスのapiを活用する
    • 不必要にユーザーを長く拘束しないようにする
  • (質問)VRにボットを拡張する可能性はあるのか
    • 今すぐではないが、VRが軌道に乗れば、確実にくると考えている

Realmを使ってコラボレーションアプリを作る

  • コラボレーションアプリとは?
    • Google Docs/Slack/JIRA等の複数のユーザーが同時進行で作業をすることができるアプリ
  • Realmとは?
    • 大事なのはDBマッパーではない
    • データーベースそのもの
    • schemalessではない
  • Realmの利点
    • オブジェクト思考で書ける
    • クラスを実装するように書けるので、新しいことを覚えなくてよい
    • React NariveやXamarinにも対応しているので、クロスプラットフォーム
    • すべての環境で同じデータを使いまわせるので、バックアップがとれる
    • トランザクション管理をしているので、リアルタイムの共同編集ができる
    • サーバー、モバイルの両方でRealmを採用すれば、アプリからjsonを排除することが可能
  • Realmの通知機能
    • プロパティの変更、オブジェクトの変更、コレクションの変更、ファイルの変更など、様々な変更に対して通知を行える
    • イベントハンドリング
  • アクセス権の管理
    • Admin Realm, Management Realm, Permission Realmなどの特別なRealmを使えば、アクセス権の管理が可能
  • (質問)RealmをPHPから操作する等、さらに多言語対応をしていく予定はあるか
    • 今のところPHPの予定はないが、いくつかの言語をサポートする予定はあり、そこになくてもGithubで要望を上げてくれれば検討する

独自のツールを構築する

  • ネイティブアプリの問題点
    • ネイティブアプリのテストが長くなってしまう問題
    • ウェブアプリケーションも提供していたが、カスタムUIがたくさんあるとウェブ側の開発のスピードについていけない
  • これらの問題は、コードの再利用が出来ていないことによるのではと考えた
  • 独自コンポーネントのインフラの構築のアプローチ
    • jsonベースのコンポーネント
    • React in swift – Katana
    • React Native
  • すべての実装を、Swiftにするか、Javascript(React Native)にするかすれば、コードが使いまわせるのでは。
    • Swift
      • メリット – 盛り上がっているし非常にエキサイティング
      • デメリット – コンパイルは遅い、独自実装が沢山必要
    • React Native
      • デメリット – 依存性が593もある、まだ若い、アップデートが早い
      • メリット – ただしAPI思考アプリと親和性が高い
  • その他のReact Nativeのメリット
    • シンプルなレイアウトシステム
    • テスト界隈は進んでいる(javascriptなので)
    • コミュニティはオープン
  • React Nativeでコンポーネント化することで、コードを再利用をはかった。
  • (質問)複雑なコンポーネントをReact Nativeだけでできるのか
    • 今のところ自分達のアプリでは、問題になっていない

リアルタイム物体検出アプリでよりよいフィードバックを提供する(LT)

  • Wantedlyで行っている名刺の検出の例
  • 前提
    • カードの認識はできていて、位置が定まっているという前提
  • 複数のオブジェクトがカメラに写っている時に、各フレーム間のオブジェクトラッキングが問題
    • オープンCVの標準のトラッキングを実装したけど、一部の端末で微妙だった
    • なので独自トラッキングメソッド実装した
  • その他iOSアプリでは、CoreImageを使ったトラッキングがあるが、あくまで顔認識に特化したもの
    • サンプルコードをGithubにあげた

UXエンジニアという働き方

  • エンジニアもUXを考える必要があるということ
  • エンジニアにしかできない提案がある
  • UXを良くするためにやっていること
    • リテラシーが高くなく、アプリに馴染みがないユーザーをターゲットにした場合
    • 実際にユーザーにプロトタイプをいじってもらって検証した
  • デザイン思考の学習
    • デザイナーの思考法であり、これによりイノベーションを起こすような思考法
    • ユーザーへの共感がポイントらしい

以上、本日はこんな感じでした。

今日の講演の内容を振り返ると、全体的に

  • Swiftの安全性について
  • ネイティブアプリのテスト、特にUI Test

についての話が多かったように思います。
特にテストについては、質問でもそれに関連した質問が多かったですし、やはりどこもテストについては苦労しているんだな、と。

また、講演の内容によっては自分もやっているようなことについての話もあったので、これはもっとちゃんとブログを書いて情報発信をしたほうがみんな幸せになれるかもれしないな、と。
本ブログではアプリについてあまり書いてないですが、今後は積極的に書いていこうかと思います。

あ、あと夕方ぐらいにMacのバッテリーが持たなくて、最後はiPhoneで講演をメモっていました。
Macのバッテリーを長持ちさせるにはどうしたら良いんだろうか?

とにもかくにも、とても刺激的な一日でした。
明日もまたtry! Swiftに行ってきます!
ではまた明日。

Read More

けんかをやめて

竹内まりや版でも河合奈保子版でもいいので、感情混めてまずは歌いましょう…

さあ浮かんできませんか? “ごめんなさいね 私のせいよ” そうです、SwiftさんとObjective-Cさんがけんかをしてしまうのは、あなたのせいです!

では仲直りさせましょう!!

SwiftからObjective-Cを利用する場合は、

1. SwiftのプロジェクトからObjective-Cのファイルを作成したとき
2. Objective-CプロジェクトからSwiftのファイルを作成したとき

その際に以下のようなダイアログが表示されますので’YES’を選択します。

bridgingheader_2x

するとプロジェクトネーム-Bridging-Header.hというファイルが作成されます。このファイル内で必要なObjective-Cのヘッダーファイルを管理します。

In CustomObject.h

#import <Foundation/Foundation.h>

@interface CustomObject : NSObject

@property (strong, nonatomic) id someProperty;

- (void) someMethod;

@end

In CustomObject.m

#import "CustomObject.h"

@implementation CustomObject 

- (void) someMethod {
    NSLog(@"SomeMethod Ran");
}

@end

とりあえず用意したObjective-Cファイルがこのようなものだった場合、Swift側では以下のようにします。

1. プロジェクトネーム-Bridging-Header.hに、#import “CustomObject.h”を追加
2. 例として、以下のように使う

var instanceOfCustomObject: CustomObject = CustomObject()
instanceOfCustomObject.someProperty = "Hello World"
println(instanceOfCustomObject.someProperty)
instanceOfCustomObject.someMethod()

なおGitHubなどの外部Frameworkを使う場合でも、ダミーでファイルを作成する必要があります。プロジェクトネーム-Bridging-Header.hが作成されたら削除して構いません。

Objective-CからSwiftを利用する場合は、

たとえば以下のような内容で、MySwiftObject.swiftを作成します。

import Foundation

class MySwiftObject : NSObject {

    var someProperty: AnyObject = "Some Initializer Val"

    init() {}

    func someFunction(someArg:AnyObject) -> String {
        var returnVal = "You sent me \(someArg)"
        return returnVal
    }

}

Objective-C側では、以下のようにします。

1. プロジェクト名が’Test’だった場合、利用したいObjective-Cファイル内に#import “Test-Swift.h”を追加
2. 例として、以下のように使う

#import "Test-Swift.h"

.....................

MySwiftObject * myOb = [MySwiftObject new];
NSLog(@"MyOb.someProperty: %@", myOb.someProperty);
myOb.someProperty = @"Hello World";
NSLog(@"MyOb.someProperty: %@", myOb.someProperty);
NSString * retString = [myOb someFunction:@"Arg"];
NSLog(@"RetString: %@", retString);

で、一件落着! 仲直りしましたょ!!

Read More

Swiftさん、アレないっす

Swiftに興味津々のおヒトに言語仕様つらつら逝っちゃうのもいいかと思ったけどぉ…
本日は、入り口編

新規カラのProjectつくるとないんですょ、アレが… そお、main関数です !!

Objective-Cでいえば、こんなの

#import <UIKit/UIKit.h>

#import "AppDelegate.h"

int main(int argc, char * argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

Objective-CはCの仲間なんで、main関数があるんですね。UIApplicationMainの前で行いたい処理、あるでしょ?!
Swiftではファイルごとありません。えぇぇぇ、ダメダメじゃん!!
あわてちゃいけませんよ、お客さん!! Swiftは、ちゃあんと隠し持っています。
それが、コレ@UIApplicationMain AppDelegate.swiftにあります。

でもコレじゃぁ、UIApplicationMainの前に処理入れられないって!!
だからあわてないでって言ってるじゃないですか。

import UIKit

UIApplicationMain(C_ARGC, C_ARGV, NSStringFromClass(UIApplication), NSStringFromClass(AppDelegate))

こんなかんじのmain.swiftをつくって、@UIApplicationMain をコメントアウトすればいいんです!!

Read More

iPhoneとiPadで、$.on、$.delegateまたは$.bindから割り当てたクリックイベントが発火しない場合の対処法

原因はよくわからないけど、対処は簡単。
clickイベントを割り当てた要素の属性に「onclick=””」を指定する。

Click here

こちらにあった
http://stackoverflow.com/questions/10165141/jquery-on-and-delegate-doesnt-work-on-ipad

Read More