Swift3.0-preview-1で追加されたswift packageを試してみた
Swift3.0-preview-1で追加されたswift packageを試してみた
3.0-preview-1-SNAPSHOT-2016-05-31-a
のSwiftがリリースされ、このバージョンからswift package
コマンドが使えるようになりました。
これはSwift Package Managerを使用する際に利用するコマンドになります。この記事では環境構築、使い方を説明していきます。
Swift Package Managerの環境を構築する
SwiftのバージョンをSwift3.0-preview-1版に変更する
swift packageコマンドが使えるようになった3.0-preview-1-SNAPSHOT-2016-05-31-a
のSwiftを使用します。
swift.orgからSwift3.0-preview-1版のsnapshotをダウンロードしてくる
上記からSwift3.0-preview-1版Swiftのsnapshotをダウンロードし、インストールしておきます。
swiftenvでSwiftのバージョンをSwift3.0-preview-1版に切り替える
今回はswiftenvを利用してSwiftのバージョンを変更します。
swiftenvは上記記事にてセットアップについて説明してますので参考にしてください。
swiftenv global 3.0-preview-1-SNAPSHOT-2016-05-31-a
これで設定してるSwiftが3.0-preview-1-SNAPSHOT-2016-05-31-a
のバージョンに変更されました。
念のためにバージョンが変更されたか確認しておきましょう。
$ swift --version Apple Swift version 3.0-dev (LLVM 3863c393d9, Clang d03752fe45, Swift e996f0c248) Target: x86_64-apple-macosx10.9
$ swiftenv version 3.0-preview-1-SNAPSHOT-2016-05-31-a (set by /Users/__moai/.swiftenv/version)
ここでバージョンが切り替わっていれば成功です。
TOOLCHAINSにパスを通す
swift package
コマンドを利用するためにパスを通します。
OS、環境によって違うので、それに合わせて変更しましょう。
Xcode 7.2の場合
export PATH=/Library/Toolchains/swift-latest.xctoolchain/usr/bin:$PATH
Xcode 7.3の場合
export TOOLCHAINS=swift
Linuxの場合
export PATH=path/to/toolchain/usr/bin:$PATH
swift packageがの環境が構築できたか確認する
swift package
のコマンドが利用できるようになったかを確認します。
バージョンが表示されるかどうか以下のコマンドを叩いて確認しましょう。
$ swift package --version Swift Package Manager – Swift 3.0
エラーが出る場合はSwiftのバージョン、pathの設定がおかしい可能性があるのでその辺りを調べてみると良いかもしれません。
Swift Package Managerを試してみる
それではswift packageコマンドを試していきましょう。
swift package
コマンドを叩いてみます。
$ swift package OVERVIEW: Perform operations on Swift packages USAGE: swift package [command] [options] COMMANDS: init [--type <type>] Initialize package (library|executable) fetch Fetch package dependencies update Update package dependencies generate-xcodeproj [--output <path>] Generates an Xcode project show-dependencies [--format <format>] Print dependency graph (text|dot|json) dump-package [--output <path>] Print Package.swift as JSON OPTIONS: -C, --chdir <path> Change working directory before any other operation --color <mode> Specify color mode (auto|always|never) -v, --verbose Increase verbosity of informational output --version Print the Swift Package Manager version -Xcc <flag> Pass flag through to all C compiler invocations -Xlinker <flag> Pass flag through to all linker invocations -Xswiftc <flag> Pass flag through to all Swift compiler invocations NOTE: Use `swift build` to build packages, and `swift test` to test packages
上記のように使い方が出力されてますね。
swift packageから雛形を作る
Hogeディレクトリを作成して0の状態からPckageの雛形を作成します。
雛形を作成するときにはswift package init
コマンドを叩きます。
mkdir Hoge cd Hoge swift package init
すると、下記のログが出力され雛形が生成されます。
Creating library package: Hoge Creating Package.swift Creating .gitignore Creating Sources/ Creating Sources/Hoge.swift Creating Tests/ Creating Tests/LinuxMain.swift Creating Tests/Hoge/ Creating Tests/Hoge/HogeTests.swift
それでは自動生成されたファイルの中身を見ていきましょう。
Package.swift
親ディレクトリ名をそのままPackage名として定義しています。
import PackageDescription let package = Package( name: "Hoge" )
.gitignore
ビルドによる成果物、依存してるPackage群、Xcodeプロジェクトファイルなどがignoreとしたいファイルのようです。
.DS_Store /.build /Packages /*.xcodeproj
Sources/Hoge.swift
親ディレクトリ名の構造体が定義されており、textのプロパティにはHello, World!
が値として入っています。
雛形的にrootの構造体としてここからライブラリにアクセスさせたい意図があるようにも思えます。
struct Hoge { var text = "Hello, World!" }
Tests/LinuxMain.swift
Tests/LinuxMain.swiftがテストの際に最初に呼ばれるファイルになります。
ここではターゲットとなるTestの全クラスをXCTMainに渡して教えてあげています。
import XCTest @testable import HogeTestSuite XCTMain([ testCase(HogeTests.allTests), ])
Tests/Hoge/HogeTests.swift
自動生成するHoge構造体が保持してるtextの中身をテストしています。
先ほどのTests/LinuxMain.swift
で見たようにallTestsとしてTestする内容の一覧を返すようにしています。
import XCTest @testable import Hoge class HogeTests: XCTestCase { func testExample() { // This is an example of a functional test case. // Use XCTAssert and related functions to verify your tests produce the correct results. XCTAssertEqual(Hoge().text, "Hello, World!") } static var allTests : [(String, (HogeTests) -> () throws -> Void)] { return [ ("testExample", testExample), ] } }
swift packageからXcodeのプロジェクトファイルを生成する
Hogeディレクトリで自動生成したファイルを元にXcodeのプロジェクトファイルを生成します。
swift package generate-xcodeproj
すると下記ログが出力されプロジェクトファイルが生成されます。
generated: ./Hoge.xcodeproj
早速Xcodeで開いてみましょう。
自動でコードがプロジェクトファイルに紐付けされた状態になっていますね。
このようにswift package
コマンドを使えばSwiftのコーディングに集中することができます。
どんどんSwiftで良いコードを書いていきましょう。
swiftenvでSwiftのバージョンを管理する
swiftenvでSwiftのバージョンを管理する
Swift3.0の開発版が公開されてからSwiftの2系と3系の間のタイミングである今、iOSなどのアプリ開発ではSwiftの2系、Swift3の変更点の確認ではSwift3.0というような使い分けをする場面が出てくるかもしれません。
そのような時こそSwiftのバージョン管理をしてくれるswiftenvがオススメです。
Homebrewからswiftenvをインストールする
Macで簡単に設定をするためにHomebrewからインストールします、ターミナル上から下記コマンドを入力します。
brew install kylef/formulae/swiftenv
swiftenvのpathを設定する
インストールが完了したらswiftenvのパスを設定します、使ってるシェル環境に合わせて設定しましょう。
bash
~/.bash_profile
の部分は環境によって変わると思うので、環境に合わせて~/.bashrc
なり変更してください
echo 'if which swiftenv > /dev/null; then eval "$(swiftenv init -)"; fi' >> ~/.bash_profile
zsh
echo 'if which swiftenv > /dev/null; then eval "$(swiftenv init -)"; fi' >> ~/.zshrc
fish
echo 'status --is-interactive; and . (swiftenv init -|psub)' >> ~/.config/fish/config.fish
swiftenvを反映する
swiftenv側で設定してるSwiftを参照するように反映させます。
swiftenv rehash
swiftenvを動かしてみる
swiftenv
コマンドを入力してヘルプが出れば設定が正常に完了になります、基本的にはpyenvやrbenvと使い方は変わりません。
$ swiftenv Usage: swiftenv [--version] <command> version Displays the current active Swift version versions Lists all installed Swift versions global Sets the global version of Swift local Sets the local application-specific version of Swift install Installs a version of Swift uninstall Uninstalls a specific Swift version rehash Installs shims for Swift binaries Visit https://swiftenv.fuller.li for more info.
現在の環境で設定されてるSwiftのバージョンを確認する
swiftenvで管理してるSwiftのバージョンのうち、設定してるバージョンを確認します。
system
というのがswiftenvで管理する前からインストールされているSwiftになります。
$ swiftenv version system (set by /Users/__moai/.swiftenv/version)
swiftenvで管理してる複数のSwiftのバージョンを確認する
swiftenvで管理してるSwiftのバージョンの一覧を確認します。
下記のようにsnapshotのタグ名で管理されていることが分かります。
$ swiftenv versions * system 3.0-preview-1-SNAPSHOT-2016-05-31-a DEVELOPMENT-SNAPSHOT-2016-05-09-a 2.2
設定するSwiftのバージョンを変更する
swiftenvでSwiftのバージョンを切り替える際は、local
とglobal
という概念の2種類があります。
local
がそのディレクトリ内だけでSwiftのバージョンを変えたい場合、global
が全てのディレクトリでSwiftのバージョンを変えたい場合に使い分けます。
まずはglobalでSwiftのバージョンを変更してみます。
swiftenv global 3.0-preview-1-SNAPSHOT-2016-05-31-a
Swiftのバージョンが変わったどうか確認します。
$ swift --version Apple Swift version 3.0-dev (LLVM 3863c393d9, Clang d03752fe45, Swift e996f0c248) Target: x86_64-apple-macosx10.9
$ swiftenv version 3.0-preview-1-SNAPSHOT-2016-05-31-a (set by /Users/__moai/.swift-version)
このようにSwiftから見ても、swiftenvから見てもバージョンを変更したことが確認できます。
それでは続いてlocalでSwiftのバージョンを変更してみます。
ここではhoge
ディレクトリを新しく作成し、その中でSwiftのバージョンをsystem
に変更します。
mkdir hoge cd hoge swiftenv local system
ここで変わったことを確認します。
$ swift --version Apple Swift version 2.2 (swiftlang-703.0.18.8 clang-703.0.31) Target: x86_64-apple-macosx10.9
$ swiftenv version system (set by /Users/__moai/hoge/.swift-version)
Swiftのバージョンが先ほどと同じswiftenvを入れる前のSwiftのバージョンになっていることが確認できました。
仕組みとしてはlocal
で切り替えたSwiftのバージョンは、ディレクトリ内に.swift-version
というファイルが作成されており、その中でSwiftのバージョンが記載されています。
なのでhogeディレクトリ内のSwiftのバージョンを再度globalのSwiftのバージョンに変更したい場合はこの.swift-versionを削除すれば反映されます。
rm .swift-version
おわりに
このようにSwiftのバージョン管理を楽にしてくれる便利なswiftenv
の紹介でした。
みなさんもどんどんバージョンアップが進むSwiftの変更を追いかける際の便利な道具として是非試してみてください。
Swift3.0で文字列操作
Swift3.0で文字列操作
Swiftでは文字列周りの操作はFoundationのライブラリを使うことで簡単に操作することができます。
ですが今回はあえてFoundationを使わないで文字列の操作を一通り行うコードを乗せつつ説明していきます。
文字列同士を結合する
文字列の結合は単純に「+
」演算子を繋げるだけです。
"123" + "456" // -> "123456"
対象の文字列の配列から1つの文字列に集約する
文字列を配列から集約する場合はjoined(separator: String)
関数を使用します。
["1", "2", "3", "4", "5", "6"].joined(separator: "") // -> "123456"
対象の文字列から指定の1文字の位置を検索する
対象の文字列をCharacterの配列として扱い、enumeratedで文字とインデックスを取るようにしておきます。
そして指定の1文字でfilterをかけて、最初にヒットしたインデックスの値を元にString.Indexの値として取得します。
この例では取得したString.Indexの値が取れてることを確認するためにsubscriptでアクセスできるかどうかを確認しています。
extension String { func index(character: Character) -> String.Index? { let index = self.characters.enumerated().filter { (idx, c) in c == character }.first?.0 guard let offset = index else { return nil } return self.index(self.startIndex, offsetBy: offset) } } let string = "123456" if let index = string.index(character: "3") { string[index] // -> "3" }
対象の文字列から指定の文字列の範囲を検索する
対象の文字列が指定の文字列の先頭1文字を含んでいた場合に、一致したインデックスから指定の文字列の長さの数だけ終端のインデックスを取得しておきます。
先頭から終端のインデックスを元にRangeを用意して対象の文字列をスライスし指定の文字列と同じかどうかを比較します。
同じだった場合のみRangeを返します。
extension String { func range(string: String) -> Range<String.Index>? { guard let startIndex = self.index(character: string[string.startIndex]) else { return nil } guard let endIndex = self.index(startIndex, offsetBy: string.characters.count, limitedBy: self.endIndex) else { return nil } let range = startIndex..<endIndex if self[range] != string { return nil } return range } } let string = "123456" if let range = string.range(string: "34") { string[range] // -> "34" }
指定する1文字ごとに対象の文字列を分割する
対象の文字列をCharacterの配列として扱い、split(separator: String)
関数を利用して分割しています。
extension String { func separatedComponents(separator: Character) -> [String] { return self.characters.split(separator: separator).map(String.init) } } "1,2,3,4,5,6".separatedComponents(separator: ",") // -> ["1", "2", "3", "4", "5", "6"]
指定する1文字を対象の文字列から取り除く
対象の文字列をCharacterの配列として扱い、指定する1文字でfilterをかけてもう一度文字列として集約をかけます。
extension String { func removed(character: Character) -> String { return self.characters.filter { $0 != character }.map { String($0) }.joined(separator: "") } } "1,2,3,4,5,6".removed(character: ",") // -> "123456"
指定する文字列を対象の文字列から取り除く
replaceSubrange(range: Range<String.Index>, with: String)
を内部で再帰的に呼び出して文字列を取り除きます。
extension String { func removed(string: String) -> String { if let range = self.range(string: string) { var mutatingSelf = self mutatingSelf.replaceSubrange(range, with: "") return mutatingSelf.removed(string: string) } return self } } "1, 2, 3, 4, 5, 6".removed(string: ", ") // -> "123456"
Xcodeで開発版のSwift3.0を試してみた
XcodeでSwift3.0の開発版を動かす
Swiftが世に出てから2年経ち、オープンソース化されてから半年経とうとしています。
Swift3は今までの下位バージョンとの互換性を意識せず大幅な変更を加えており、ベースとなるProtocol名の一新、C言語のfor文のスタイル撤廃、カリー化の文法変更などがあり、よりモダンな言語として生まれ変わっています。
そしてSwift3以降の変更に関しては最小限の変更で留めてアップデートをしていくとのことで、Swift3から変更点を追いかけてもSwift4以降も十分に追いかけられるでしょう。
そこでMac OSでXcodeを使って開発版のSwift3.0を動かしてみます。
Swift3.0を試す開発環境
Swift3.0のsnapshotをダウンロードする
Swift.orgからXcodeの最新版をダウンロードします。(現時点だとMay 9, 2016
)
snapshotをインストールする
ダウンロードしてきたpkgファイルをインストールしましょう。
Xcodeにsnapshotを反映させる
準備としてはこれだけであとはXcodeを開いてSwift3.0のsnapshotをXcode側に設定します。
Xcodeを起動して、メニューからXcode > Toolchains
を選択し先ほどインストールしたsnapshotを選択してください。
Swift3.0をXcodeで動かす
それではXcodeで動かすための環境ができたので、新しく変更されたカリー化の文法を試してみます。
func calclate(_ a: Int) -> (Int) -> Int { return { b in return a + b } } let calclator = calclate(3) print(calclator(10)) print(calclator(14))
上記のコードをPlaygroundで動かそうとしたのですがsnapshotからだと動かないのか反応しなくなりました。
なので適当なプロジェクトを用意して、そこで動かします。
ちゃんとカリー化できてることが確認できてますね。
このように新しいバージョンのSwiftはこれだけの手順を踏めば試すことができます。
これからもどんどんよりよくなっていくSwiftを追いかけていきましょう。