コンユウメモ @kon_yu

作ったガラクタとか、旅行とかの話

XcodeにCarthageを入れてOSSライブラリを利用する

はじめに

いつのまにやらiOSのライブラリ管理ツールはCocoapodsよりもCarthageになってきているらしい cocoapodsでは必須だった謎のxcworkspaceは不要になり、全然良くわかってないがビルドの速度が上がるようだ

https://github.com/Carthage/Carthage

Carthageの読み方は町の名前のカルタゴではなく英語読みのカーセッジが一般的らしい

Carthageの良さについての日本語はCarthageのReadMeを訳した下記の記事が詳しい http://qiita.com/nori0620/items/b81ae171f0e82b0c2d8a

ゴール

  • Carthageを利用できるようMac及びXcodeの設定
  • サンプルプロジェクトにCarthageを適用し、httpクライアントの定番OSS Alamofireを入れて動作確認する
  • チーム開発が可能な形でGitで管理できる設定をする

  • Carthageの細かいバージョン指定や、ローカルや非公開のライブラリを取得するような細かい使い方は今回は調べない

動作環境

  • xcode 7.3.1
  • osx 10.11.4
  • Homebrew 0.9.9

Carthageをhomebrewからインストール

# インストール
> brew install carthage

# インストールの確認でバージョン番号を調べる
>carthage version
0.16.2

carthageをすでにインストールしてアップデートしたい場合もbrewのupgradeコマンドを素直に実行するだけで良い

> brew upgrade carthage

サンプルのXcodeプロジェクトを新規作成する

適当にSimpleViewApplicationのプロジェクトを作成する

git管理にする

プロジェクト作成時に、プロジェクト名を決めて設置する場所をしてするダイアログで 「Source Control」のチェックが入っていて、セレクトボクスMy Macになっていればローカル保存のGit管理にされていることになる

gitignoreファイルを作成する

xcodeのGit管理がだけが入っている状態ではxcode上では変更・削除されたファイルはxcodeのプロジェクトで管理されたものだけが表示されるが、 コンソールからxcodeのディレクトリに行き git statusで確認するとunstageなファイルとしてテンポラリーで利用するファイルがやらある

xcodeからはCartFileとかはコミットできないのかこの辺はよくわかってない

Githubが公開してくれているgitignoreファイルのテンプレートをつかう https://github.com/github/gitignore/blob/master/Swift.gitignore 上記テンプレートを見るとどうやらCarthegeで作られる余分なファイルにも対応してくれている

xcodeプロジェクト直下で以下のコマンドでgithubのテンプレートから.gitignoreファイルを作成する

> curl    https://raw.githubusercontent.com/github/gitignore/master/Swift.gitignore > .gitignore

.gitignoreファイルから下記項目のコメントを外す

# Carthage/Checkouts
Carthage/Checkouts

こうすることで、CarthageでDLしたライブラリのリポジトリをクローンしたソースコードが入っているだけなので、git管理を無視する対象にする。対象のライブラリのURLが無くなったり変わったりしないかぎり、ここを許容する必要が無いため

Carthageを使ってライブラリをインストールする

Cartfileファイルを作成

xcodeプロジェクトの直下にCartfileファイルを作成する

> touch Carthage

これを"Emacs"で編集する(vimで編集しようとするとmacが爆散します)

Cartfileファイルに内に以下のように追記して保存する 今回使うAlamofireをgithubからDLして利用できるようにする記述をしている

github "Alamofire/Alamofire"

AlamofireをCarthageを利用してビルド

ビルドには時間がかかるので、ビルド対象を選ばないと様々なプラットフォーム向けにビルドしてしまうので必要な物だけ利用する

# --platformオプションを付けてiOSを指定してビルドする
> carthage update --platform iOS
 carthage update
*** Fetching Alamofire
*** Checking out Alamofire at "3.4.0"
*** xcodebuild output can be found in /var/folders/lg/h7kjqrs51qs417r4ysy2z_3r0000gn/T/carthage-xcodebuild.COQug2.log
*** Building scheme "Alamofire iOS" in Alamofire.xcworkspace

/Carthage/Build/iOS/Alamofire.framework のコンパイルされたframeworkファイルが有るのが確認できる

XcodeのプロジェクトでAlamofireを利用する

Linked Frameworks and Librariesにライブラリを追加する

Xcodeでプロジェクトファイルを選択し、 Generalメニューを開く Linked Frameworks and Libraries の項目にあるリストに、 Finderで/Carthage/Build/iOS/Alamofire.framework を選択しドラックアンドドロップで追加する

またプラスボタンでダイアログを使って追加することも出来る。

Run Scriptの追加

Xcodeでプロジェクトファイルを選択し、 Build Phraseメニューを開く

プラスボタンを押し、「New Run Script Phrase」を選択する 選択すると「Run Script」と言う項目が追加されるので、そこをクリックして詳細設定を開く

ここでまず「Shell」の下にある黒い部分に以下を追記する

/usr/local/bin/carthage copy-frameworks

つぎにinput fileにあるプラスボタンを押し以下の様に、Alamofire.frameworkのパスを追加してやる。

$(SRCROOT)以降はどこでAlamofire.frameworkをコンパイルしてもこのパスで書かなければならないっぽい、ここもよくわかってない

$(SRCROOT)/Carthage/Build/iOS/Alamofire.framework

 Alamofireを利用してみる

ViewController.swiftファイルのviewDidLoadメソッド内に、 Alamofireを利用してTwitterのトップページを取得してコンソールに出力するコードを追加する これでシミュレータを起動してコンソールにHTMLが吐き出される

import UIKit

# 追記
import Alamofire

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        
         # ここから追加 
        Alamofire.request(.GET, "https://twitter.com/")
            .responseString { response in
                print(response.result.value)
        }
        # 追加終わり
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
}

refs: * https://github.com/Carthage/Carthage * http://blog.dalt.me/1199 * http://blog.morizotter.com/2015/07/19/how-to-carthage-distribution/

買っておいて損はない

詳解 Swift 改訂版

詳解 Swift 改訂版

クロージャを引数としたメソッド記法の整理

UIAlertActionをインスタンス化するサンプルコードが、定義されているコンストラクタ

public convenience init(title: String?, style: UIAlertActionStyle, handler: ((UIAlertAction) -> Void)?)

と違って引数のhandlerが括弧の外に書くようになっていたので気になって、クロージャを引数に取るメソッドの書き方調べた。

この書き方を、詳解Swiftでは「末尾クロージャ」とという項に書いてあり、

AppleSwiftのlanguage guide では「Trailing Closures」に記されている

注意

  • 勉強中なので情報は間違っている可能性があります
  • 動作確認: Swift2.0
func function1(handler: ()->Void) {
    handler()
    print("this is function1!!!")

}
// クロージャを引数として渡す
let closure = {
    print("this is closure!!!")
}

function1(closure)
//=> this is closure!!!
//   this is function2!!!


func function2(){
    print("this is function2!!!")
}

function2()
// => this is function1!!!


// メソッドとクロージャの引数として渡せる
function1(function2)

//=> this is function1!!!
//   this is function2!!!

// クロージャを直接引数として渡す
function1({
    print("inside")
})
//=> inside
//   this is function2!!!


// クロージャを直接引数とする場合は括弧()の外でOK
// クロージャの引数が一番最後の時のみ
function1(){
    print("outside")
}
//=> outside
//   this is function2!!!

// つまり
// この最後がクロージャが引数の場合はOKで
//  末尾クロージャ/Trailing Closuresの書き方がこれ
func function3(arg1: String, handler: ()->Void) {
    handler()
    print("this is \(arg1)!!!")
}
function3("arg1 string"){ print("arg1 handler")}


// こちらの第二引数がクロージャの場合にはエラーになる
func function4(arg1: String, handler: ()->Void, arg2: String) {
    handler()
    print("this is \(arg1), \(arg2)!!!")
}

function4("arg1", handler: { print("arg1 handler")},arg2: "arg2 string")
//=> arg1 handler
//   this is arg1, arg2 string!!!

// よってこう書くとエラーになる
//function4("aaa", arg2: "arg2 string"){ print("arg1 handler")}

オススメSwift技術書

詳解 Swift 改訂版

詳解 Swift 改訂版

Swiftポケットリファレンス

Swiftポケットリファレンス

分報をタイムライン表示して、もれなくチームの流れを把握しよう

Slackに書き込んだ分報をタイムライン表示しよう

f:id:kon_yu:20160325235052p:plain

対象のhubotのscriptだけさくっと知りたい人はこちらを参照すると良い slackで分報をタイムライン表示して一覧性を手に入れろ - Qiita

分報とは

c16e.com

課題解決へのアクションが遅れてしまうという日報の弱点を克服するために、僕のチームでは「分報」という独自の取り組みをしている。分報ではSlackなどの社内チャットツールを使い、「今やっていること」や「困っていること」をつぶやく。課題をリアルタイムに共有できるのが特徴だ。日報が社内mixi日記だとすると、分報は社内Twitterにあたる。

端的に言うと、slsckに各エンジニアの部屋を作り、作業ログを書き込んでいくというものだ。 また各人の部屋を覗いて、困っていることに素早く気づいて開発の効率化を図ることができる。

いままでの自社での分報的な取り組み「dev/null」で共用作業ログを書く

自社でもすでに思考を吐き出すような感じで「dev/null」と言う共用の作業ログを書く部屋を作っていた。

Twitterでツイートしてもよいが、社内のプロテクトしておくべきことを迂闊に野に放つリスクよりは、クローズドな領域を設けたほうが、これは外に出して大丈夫かな?と考える必要がなく楽で良い。

2,3人なら良いがそれ以上に人数が増えた際に、個々のエンジニアの部屋を見に行くのが億劫ではないと思い、 分報よりも、こちらの方が一覧性があってすぐれいるのでは考えていた

実際に聞いてみた

このような回答を得た。なるほど、よく見るべき人に注力しながら確認すると良いと

それでも全員分のデータが見たいな、オレにはショートカットを駆使してもslackの部屋移動が面倒だ タイムライン的に見られたらチーム全体の雰囲気の一体感が出るのではなかろうかか?

やっぱ、共用の部屋を作った方がいいんじゃないかな?

リモートワークを推進されている会社ソニックガーデンの社長である倉貫さんに聞いてみた

先日ソニックガーデンバーというイベントで、ソニックガーデンの社員さんとお話するチャンス得た sonicgardenbar1.peatix.com

ソニックガーデンではRemottyと言う自社ツールを使ってチャットコミュニケーションをとっている。

また分報と言う概念の前から、Remottyでは各エンジニアの部屋を作って作業ログを書く言う方式を実践されていた。

※「dev/null」の共用部屋を作ったのも過去にRemottyを使ってみて、各人の部屋に書かれると一覧性がないので作ったという経緯もある

リモートワークを推進されている会社ソニックガーデンの社長である倉貫さんなら、

分報はいいと思うんだけど、一覧性がないのが不便だと思う、共用の部屋のほうがいいと思うんだがどうお考えになりますか?

という問題の答えが出せるのではないかと聞いてみた。

頂いた答え(意訳)

  • 共用の部屋だと、自己所有感が無いので気軽に書き込みにくい
  • 共用の部屋で複数のトピックが走っている場合、ログを追いにくい
  • 現在のRemottyにはタイムライン機能が画面右にあるので、一覧性がないと言う問題を克服している

そうRmottyで実は同じようなことが出来るのだ!

タイムラインの特定の書き込みをクリックすると、その書き込みのある部屋に行くことが出来て、前後の書き込みを様子を見たり、アドバイスをしたりできる

Remotty自分の部屋 画面右に自分の部屋の書き込みが表示される f:id:kon_yu:20160325234705p:plain

Remotty グループの部屋 画面右に複数人のグループの書き込みも表示される f:id:kon_yu:20160325234724p:plain

じゃあRemottyを使えばいいじゃないというところだが、ところがどっこい我々はSlackにどっぷりハマっているのだ

それでもSlackを使いたい

以下のことをSlackで通知を受け取っているので、今更Slackから抜け出せない。分報だけ別ツールにはしたくないのだ。

  • デプロイした結果
  • CIを実行した結果
  • エラー発生の通知
  • 異常検知のログ
  • チケットのアサインや通知

というわけで分報やり方を踏襲しつつ、各エンジニアの部屋での書き込みを一纏めに表示するタイムラインの部屋を作るツールが欲しい

HubotでSlackに分報をタイムライン表示する

各エンジニアの部屋での書き込みを一纏めに表示するタイムラインの部屋を作るツールがほしい が無かったので自分で作った

hubotで各エンジニアの部屋をチェックし、発言があればタイムライン用の部屋にリンクを書き込む スクリプト

hubotで各エンジニアの部屋をチェックし、発言があればタイムライン用の部屋にリンクを書き込むことができるようにする

このスクリプトでは以下のことを実施する

  • times_ユーザ名 という部屋で発言をチェックする
  • 発言のオブジェクトから、その発言のパーマネントリンクを作成
  • timelineの部屋に発言のパーマネントリンクを投稿する

hubotのscriptディレクトリにこのようなファイルを作成する script/hunhou2timeline.coffee

# 自分のslackのURL
slack_url = "https://your_tame_name.slack.com"

module.exports = (robot) ->
  # どんな文字列があっても拾う
  robot.hear /.+/, (msg) ->
    room = msg.envelope.room
    # idにドットがあるとURLを展開してくれないので取り除く
    id = msg.message.id.replace(".","")

    # ユーザ名_channelの部屋だけウォッチ対象
    if room.match(/^times_.+/)
      # 展開可能なURLを作成し、タイムライン表示用の部屋に投稿する
      # roomの指定で、 投稿するchannelを指定
   # 第二引数でslackのパーマネントURLを構築
      robot.send {room: "#timeline"}, "#{slack_url}/archives/#{room}/p#{id}"

※ チャンネルに追加しないと、hubotが部屋をウォッチしない(入力内容に対してリアクションをしない)のでtimes_ユーザ名のチャンネルにhubotを追加する

  • 個別のチャンネルにhubotが追加された状態 f:id:kon_yu:20160325234749p:plain

自分のチャンネルに投稿すると f:id:kon_yu:20160325235049p:plain

タイムライン用のチャンネルに投稿されれる f:id:kon_yu:20160325235052p:plain

あわせて読みたい

Team Geek ―Googleのギークたちはいかにしてチームを作るのか

Team Geek ―Googleのギークたちはいかにしてチームを作るのか

小さなチーム、大きな仕事〔完全版〕: 37シグナルズ成功の法則

小さなチーム、大きな仕事〔完全版〕: 37シグナルズ成功の法則

  • 作者: ジェイソン・フリード,デイヴィッド・ハイネマイヤー・ハンソン,黒沢 健二,松永 肇一,美谷 広海,祐佳 ヤング
  • 出版社/メーカー: 早川書房
  • 発売日: 2012/01/11
  • メディア: 単行本
  • 購入: 21人 クリック: 325回
  • この商品を含むブログ (36件) を見る