Showing posts with label Swift. Show all posts
Showing posts with label Swift. Show all posts

2018-12-31

Swift の Protocol Extension で save(_ models: Sequence<Model>) みたいなことをやる

前提あるいは Array 版

Swift でシンプルな Protocol を用意して...

protocol ModelType: Hashable {}
protocol Repository {
    associatedtype Model: ModelType
    func save(_ models: [Model])
}

これらのプロトコルに適合するモデルとリポジトリーを作ってみる。

// MARK: - モデル  
struct Book: ModelType {
    let title: String
}

// MARK: - リポジトリー
extension Repository {
    func save(_ models: [Model]) {
        models.forEach { model in
            print(model)
        }
    }
}

struct BookRepository: Repository {
    typealias Model = Book
}

今回は Book モデルと BookRepository を作ってみた。Repository Protocol の save メソッドは Protocol Extension で実装した。中身はダミー。ちゃんとやるなら、Dictionary を使ったメモリー・キャッシュか Realm 等を使ったディスク・キャッシュの実装を書くことになると思う。

これらのメソッドの使い方は次の通り:

let array = [ Book(title: "book 1"), Book(title: "book 2"), ]
let repository = BookRepository()
repository.save(array)

Set でも使いたい

さて、時には Array ではなく Set を使いたいケースがある。その場合の使い方は次の通り:

let set: Set = [ Book(title: "book 3"), Book(title: "book 4"), ]
let repository = BookRepository()
repository.save(Array(set))

Repository の save メソッドは Array しか受け付けないので、Set から Array に変換する手間がかかる。

この変換をなくしたい。Array とか Set とか気にせず使いたい。そんなことは可能だろうか?

Set 用のメソッドを用意する

Swift は型を厳密に区別するので、Set 用のメソッドを用意してみる。

protocol Repository {
    associatedtype Model: ModelType
    func save(_ models: [Model])
    func save(_ models: Set<Model>)
}
extension Repository {
    func save(_ models: [Model]) {
        models.forEach { model in
            print(model)
        }
    }
    func save(_ models: Set<Model>) {
        models.forEach { model in
            print(model)
        }
    }
}

こうすると、さっきのコードは Array への変換が不要になる:

let set: Set = [ Book(title: "book 3"), Book(title: "book 4"), ]
let repository = BookRepository()
repository.save(set)

目的達成。ただ、力業で凌いだきらいが強い。もう少しスマートにできないものか?

Sequence を使いたい

Protocol Extension のコードを見てみると、中のコードは全く同じ。forEach を使っている。forEach メソッドは Sequence Protocol にある。そして Sequence Protocol は Array にも Set にも適合されている。

すると、Array や Set のメソッドを用意しなくても、Sequence Protocol に対して save メソッドを用意すれば良さそう。そう、こんな感じに...

protocol Repository {
    associatedtype Model: ModelType
    func save(_ models: Sequence<Model>)
}

残念ながら上のコードは動かない。やりたいことは分かったけど、実現方法が分からない。

というわけで、本記事のタイトルに書いたスタート地点に立った。

Set.union を参考に

そういえば、Set の union メソッドは引数に Set でも Array でも渡すことができた。あの実装はどうなっているんだろう?

コード・ジャンプを使って実装を見てみよう:

extension Set : SetAlgebra where Element : Hashable {
    public func union<S>(_ other: S) -> Set<Set<Element>.Element>
        where Element == S.Element, S : Sequence

なるほど、Sequence.Element で型を指定している。この方法を真似ればよさそう:

protocol Repository {
    associatedtype Model: ModelType
    func save<S>(_ models: S) where S: Sequence, S.Element == Model
}
extension Repository {
    func save<S>(_ models: S) where S: Sequence, S.Element == Model {
        models.forEach { model in
            print(model)
        }
    }
}

これでコードを書いてみると...

let array = [ Book(title: "book 1"), Book(title: "book 2"), ]
let set: Set = [ Book(title: "book 3"), Book(title: "book 4"), ]
let repository = BookRepository()

repository.save(array)
repository.save(set)

Array でも Set でも問題なく使うことができた。

あとがき

Sequence Protocol を意識することで、Array でも Set でも使えるメソッドを用意することができた。やったことはプロトコルへ興味を開げただけ。実装に手詰まっても、Apple のソースコードからヒントを得ることができる。時間があったら Swift の標準プロトコルを見て回るのも面白いかもしれない。

2017-07-05

技術書クラウド・ファンディング「iOS 11 Programming」プロジェクト成立

PEAKS で出資を募っていた技術書クラウド・ファンディング「iOS 11 Programming」が、目標の 500 人を達成しプロジェクトが成立した。プロジェクトの出資受付開始が 2017-06-26 (月)。プロジェクト成立の報告は 2017-07-04 (火)。8 日で 500 人分の出資が集まった。

2017-07-05 (水) 現在、548 人が出資済。出資は 2017-07-28 (金) 23:59 まで受け付ける。

書籍のリリース予定日は 2017-10-23 (月)。

なお、PEAKS のページには、著者の一人である加藤尋樹のインタビューが掲載されている。

あとがき

プロジェクト成立おめでとうございます。

ぼくも出資したので人ごとじゃない。本が読めるのが楽しみ。

あと出資者のアーリー・アクセス特典:

これはどんな形で提供されるのかな? 今からワクワク。

2017-04-04

Inside Swift -- 技術書クラウド・ファンディングに出資した!

Realm 社の iOS エンジニア、try! Swift の主催者で有名な岸川克己氏が技術書クラウド・ファンディングで出資を募っている。一冊 3,000 円。クレジット・カード支払い。800 人の出資でプロジェクト開始。2017-04-04 (火) 9:00 現在 201 人が出資済。〆切は 2016-04-30。目標人数に達しなかった場合は、プロジェクト不成立。決済は行なわれない。

面白そうなので、出資してみた!

内容

フォーマットは PDF で 250 ページ以上を予定。プロジェクト・ページに書きかけの目次がある。概要は以下の通り:

Swiftのソースコードを理解し、Swiftの内部へ手を入れるための入門・実践書を執筆するプロジェクトです。概要編ではSwiftで書いたコードが実行可能になるまでの流れなど、基本的な事項を手を動かしながら確認できる章を用意します。 その後、実践編では実際に使えるツールを開発しながらSwiftの内部をより深く理解できる内容にします。

PEAKS(ピークス)|岸川克己 - iOS開発の第一人者が執筆するSwiftの専門書「Inside Swift」の執筆プロジェクト! より引用

著者の岸川さんも本プロジェクトをツイートしている。

技術書クラウド・ファンディングを提供している PEAKS を今回初めて聞いたのだけど、URL を見るとプロジェクト番号が 1 になっている。これが最初のプロジェクトなのかな? 運営会社は ROLLCAKE Inc.

リリース予定日は 2017-09-01 になっているけど、クラウド・ファンディングや執筆って予定日通りに出ることの方が少ないから、そんなに期待はしていない。少し遅れても良いから、充実した本が出来上がると嬉しいな。

2016-03-09

Swift で複数ファイルのコンパイルを行なう

Swift ではスクリプト・ファイルのような実行が可能。

例えば Hello.swift というファイルを次のように書いてみる。

#!/usr/bin/env swift

print("Hello, World!")

これを swift コマンドで実行する。

$ swift --version
Apple Swift version 2.1.1 (swiftlang-700.1.101.15 clang-700.1.81)
Target: x86_64-apple-darwin15.3.0
$ swift Hello.swift
Hello, World!

実行権限を付けることも可能。

$ chmod +x Hello.swift
$ ./Hello.swift
Hello, World!

複数ファイルのコンパイル

Swift は swiftc コマンドを使ってコンパイルを行なうこともできる。スクリプト実行より高速になることと、複数の Swift スクリプトを一つの実行ファイルにまとめられる点がメリット。

この場合、main.swift というファイルが起点になる点に注意。

あと、ぼくが試した時は -sdk フラグに SDK のパスを指定する必要があった。少しハマったので、Makefile をここに写しておく。実行ファイル名は foo。

OUTPUT = foo

SDKPATH = `xcrun --show-sdk-path --sdk macosx`
SWIFTFLAGS = -sdk $(SDKPATH)
SOURCES = main.swift Foo.swift Bar.swift
SWIFTC = /usr/bin/swiftc

$(OUTPUT): $(SOURCES)
 $(SWIFTC) $(SWIFTFLAGS) $^ -o $@

あとがき

Swift で書くスクリプト言語については、まだ興味を持った程度。少しずつ学んでいくつもり。

2015-07-29

Notification 用の deviceToken をコンソールに表示する (Swift)

Push Notification 用の deviceToken をコンソールに表示するコードを書いてみた。

NSData 型の変数 deviceToken を文字列に変えるのに deviceToken.description で十分だったのがびっくり。

deviceToken.description は 「<スペース区切りのトークン>」な形式なので、stringByTrimmingChaaractersInSet で「<>」を削り、stringByReplacingOccurencesOfString でスペースを削ってる。

2015-06-09

WWDC 2015 で発表された開発環境

2015-06-09 (火)、Apple は WWDC 2015 において Swift 2 を発表した。

Swift 2 はオープン・ソースで提供される。

WWDC 2015 において、この発表は、一番の熱狂をもって迎えられた。

Swift 2 に新しい最適化機能が備わったとか、コメントに Markdown が使えるようになったとか、@testable というコードが書けるようになったとか、Protocol Extensions が使えるようになったとか、そういった種々の変更よりも Swift がオープンソースになったことの方が大ニュースだった。

XCode 周りでは、UI テストツールが使えるようになった。

GameplayKit, Model I/O, ReplayKit などが追加された。HealthKit, HomeKit にも改良が加えられた (HomeKit は iClouds と連携する)。Car Play 対応も進んだ。

でも、やっぱり Swift 2 オープンソース化の歓迎の声ほどには盛り上がらなかった。開発系のネタは WWDC 以降、チラホラ出てくると思うのでゆっくりフォローしていこう。

2014-10-29

「詳解 Swift」予約受付中

「詳解 Objective-C 2.0」の作者で有名な萩原剛志氏による Swift の解説本が発売される。

Amazon の情報によると発売日は 2014-12-11。あと一か月と少し。価格は 3,456 円。ページ数は 400 ページ。これは詳解 Objective-C 2.0 第3版 の 636 ページよりかは少ない。また、Kindle 版はマダ用意されていない (詳解 Objective-C 2.0 第3版 に Kindle 版があるので、近いうちに Kindle 版も用意されるとは思うけど...)。

Apple が Swift を発表したのが 2014 年の WWDC。もうそろそろ半年を迎えるけれど、小さな (?) 仕様変更は数多い。とはいえ、いつまでも手を出さないでいたんじゃジリ貧なのは明白。そろそろ、本腰を入れる時期かな〜。

2014-06-03

【WWDC】iOS 8 開発者向け新機能

2014-06-03 の WWDC で Apple は開発者向けの発表を行なった。特に新 SDK はアップル・ストア始まって以来の大きなリリースになるという。新 API の数は 4,000。

TestFlight

TestFlight は開発中アプリのテスト公開用プラットホーム。Burstly 社が開発していたけど、2014 年 2 月に Apple により買収されていた。その TestFlight が Apple の正式サービスとして再開される。価格は無料。

アプリ拡張

他のアプリとの連携が可能になる? やり方はよく分からないけど、一度 iOS のセキュリティ・システムを経由する形で、アプリ間の連携が可能になるっぽい。例えば iOS 標準の「共有」項目に自分のアプリを追加したり、アクションを追加したりできる。

Notification Center に置くウィジェットの開発も、この機能を使う。

サードパーティー・キーボード

システムワイドに使えるサードパーティー・キーボードの開発。

Touch ID

指紋認証をアプリにも組み込めるようになった。アプリのログインなどに利用できる。

HomeKit

家庭のデバイスと連携するための仕組み。ライト・鍵・カメラ・ドア・温度計・プラグ・スイッチ etc. を iOS から操作できるようになる。デバイス側の開発も必要なので家電メーカーの開発を待ちしかないのかな?

Cloud Kit

iOS 用のサーバーを提供・開発に利用する仕組み。Amazon EWS や Google App Engine を使わなくても、サーバー・システムを開発できる。

Metal

OpenGL を置き換える Apple の 3D エンジン。特にゲームでオーバーヘッドへ少なくして 10 倍の速さを叩き出す。

XCode - Swift

Objective-C に代わる新しい開発言語 Swift を発表した。

Swift は Objective-C にないモダンな機能を提供する:

  • Closures
  • Generics
  • Namespaces
  • Type interface
  • Multiple return types

Swift は REPL を採用しインタラクティブな開発が可能となる。コード量の削減も大きい。

これは WWDC で出た Objective-C のサンプル・コード:

if (myDelegate != nil) {
  if ([myDelegate respondsToSelector:@selector(scrollViewDidScroll:)]) {
    [myDelegate scrollViewDidScroll:myScrollView];
  }
}

このコードが Swift だと、こうなる:

myDelegate?.scrollViewDidScroll?(myScrollView)

う〜ん、すごい。サラリと説明されてたけど Autovectorizer (自動ベクトル化) もサポートするらしい。メモリー管理は GC (ガベージ・コレクション) ではなく ARC。ランタイムは Objective-C と同じ。

落ち穂拾い

  • Camera APIs (ホワイトバランス etc.)
  • PhotoKit
  • HealthKit
  • SpriteKit
  • SceneKit

盛り沢山。