Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

GoによるiOSアプリの開発

5,969 views

Published on

iOSDC Japan 2017で発表したスライドです。
https://iosdc.jp/2017

Published in: Technology
  • Be the first to comment

GoによるiOSアプリの開発

  1. 1. The Go gopher was designed by Renée French. The gopher stickers was made by Takuya Ueda. Licensed under the Creative Commons 3.0 Attributions license. Goによる iOSアプリの開発 @iOSDC Japan 2017 2017年9月16日(土) 1
  2. 2. 自己紹介 上田拓也 @tenntenn 2 所属 コミュニティ活動 & Go ビギナー Go Conference
  3. 3. ソウゾウ エキスパートチーム 技術をアウトプットするところに技術は集まる ■ エキスパートチームとは? ● 50%以上の時間を技術コミュニケーションへの貢献に充てる ■ エキスパートチームの役割 ● 社内に新しい技術を取り取り込む ● 社外のコミュニティなどを通じて社会へ還元する ■ エキスパートチームの活動 ● カンファレンス・勉強会の開催/運営 ● 対外的な講演活動 ● 執筆、雑誌への寄稿、インタビュー ● 社内外での担当技術の普及推進 3 @tenntenn 担当:Go・GCP @mhidaka 担当:Android メンバー
  4. 4. アジェンダ ● Goについて ● Go Mobile ● Nativeアプリ ● SDKアプリ 4
  5. 5. Goについて 5
  6. 6. Goとは? Googleが開発しているプログラミング言語 ■ 特徴 ● 強力でシンプルな言語設計と文法 ● 並行プログラミング ● 豊富な標準ライブラリ群 ● 周辺ツールの充実 ● シングルバイナリ・クロスコンパイル 6
  7. 7. Goの特徴 − 強力でシンプルな言語設計と文法 − ■ スクリプト言語の書きやすさ ● 冗長な記述は必要ない ■ 型のある言語の厳密さ ● 曖昧な記述はできない ■ 考えられたシンプルさ ● 機能を増やすことで言語を拡張していくことはしない 7 Goに入ってはGoに従え = 言語の思想を理解しよう
  8. 8. Goの特徴 − 並行プログラミング − ■ ゴールーチン ● 軽量なスレッドに近いもの ● goキーワードをつけて関数呼び出し ■ チャネル ● ゴールーチン間のデータのやり取り ● 安全にデータをやり取りできる 8 チャネル ゴールーチン A ゴールーチン B データ データ // 関数fを別のゴールーチンで呼び出す go f()
  9. 9. Goの特徴 − 豊富な標準ライブラリ − ■ 標準ライブラリ一覧  https://golang.org/pkg/ 9 net/http HTTPサーバなど archive, compress zipやgzipなど crypto 暗号化 encoding JSON, XML, CSVなど html/template HTMLテンプレート os, path/filepath ファイル操作など
  10. 10. Goの特徴 − 周辺ツールの充実 − ● go tool として標準/準標準で提供 ● サードパーティ製のツールも充実 ● IDEによらない独立したツールとして提供 10 go build ビルドを行うコマンド go test xxxx_test.goに書かれたテストコードの実行 go doc, godoc ドキュメント生成 gofmt, goimports コードフォーマッター golint コードチェッカー、リンター gocode コード補完
  11. 11. Goの特徴 − シングルバイナリ・クロスコンパイル − ■ 環境変数のGOOSとGOARCHを指定する  開発環境とは違うOSやアーキテクチャ向けにクロスコンパイルできる 11 シングルバイナリになるので 動作環境を用意しなくてよい # Windows(32ビット)向けにコンパイル $ GOOS=windows GOARCH=386 go build # Linux(64ビット)向けにコンパイル $ GOOS=linux GOARCH=amd64 go build ※ go build はGoのソースコードをビルドするコマンド
  12. 12. Go Mobile 12
  13. 13. サーバサイドとのコードの共通化 ■ クライアントとサーバのコードの共通化 ● サーバとクライアントの責務の曖昧化 ● ロジックをクライアントに持たせる ○ 通信を減らす:モバイルゲームなどで有効 ■ コードの自動生成 ● モデルデータの共通化 ● 定義ファイルからのサーバ・クライアントのコード生成 ● Protocol Buffers ■ クライアントとサーバで同じ言語を採用 ● C# : Unity ● Go? 13
  14. 14. Goによるクライアント開発 14 ■ GopherJS ● GoのソースコードからJavaScriptを生成 ● ほとんどのGoの標準ライブラリをサポート ● JavaScriptでゴルーチンとチャネルを実現 ■ Shiny ● デスクトップアプリのライブラリ ● golang.org/x/exp/shinyとして開発 ● Linux、Windowsでも動く! ■ Go Mobile ● Android/iOSアプリの開発ができるツール群
  15. 15. Go Mobile ■ Goでモバイルアプリを作るツール群 ● iOS / Androidに対応 ● golang.org/x/mobile ■ 2通りのスタイル ● SDKアプリ ⇒ Goで書いたライブラリを呼び出す ● Nativeアプリ ⇒ Goだけで書く 参考:https://github.com/golang/go/wiki/Mobile 15 Androidの実機で動かした図
  16. 16. 16 https://github.com/golang/mobile
  17. 17. 17 Go Mobileのインストール ■ 事前に必要なもの ● Goの開発環境(1.5以上) ● XCode・Androidの開発環境 ■ gomobileコマンドのインストール ● go getでgomobileコマンドをインストールする ● gomobile initでツールチェインのコンパイルなどを行う $ go get -u golang.org/x/mobile/cmd/gomobile $ gomobile init -v
  18. 18. gomobileコマンド ■ gomobileのサブコマンド 18 bind iOSまたはAndroid向けのライブラリのビルド build iOSのappまたはAndroid APKの作成 clean オブジェクトファイルとgomobileのキャッシュファイルを削除 init gomobileコマンドの初期化とツールチェインのビルド install Android APKを実機にインストールする(adb install経由) version バージョンを表示
  19. 19. Go Mobileのしくみ ■ cgoを用いてバインディング作成する ● cgoを用いてiOS/Androidから呼び出す ● モバイル用にクロスコンパイルを行う ● .aや.soを作り、Cからcgo経由でGoのコードを呼び出す 19 Go C Java Obj-C JNI cgo Android iOS
  20. 20. buildmode ■ どうビルドするかを指定するオプション ● アーカイブや共有ライブラリを生成することができる ● Cから利用することができる 20 archive, c-archive アーカイブ(.a)を作る shared, c-shared 共有ライブラリ(.so)を作る exec 実行可能ファイルを作る pie PIE形式の実行可能ファイルを作る(Go1.6以上) plugin プラグインを作る(Go1.9以上)
  21. 21. cgo ■ CとGoをつなぐためのしくみ ● Cで書かれたコードやライブラリが使える ● Goの関数などをCにエクスポートする ■ Cで書かれたライブラリのラッパーで多用されている ● SQLiteのドライバ ● OpenGLのライブラリ ■ cgo is not Go ● クロスコンパイルが難しくなるので多用しない ● Cの世界の話はGoからはコントロールができない ○ メモリリークなど 21
  22. 22. cgoを利用する 22 import "unsafe" /* #include <stdio.h> #include <stdlib.h> void hello(char *s) { printf("Hello, %sn", s); } */ import "C" func main() { str := C.CString("iOSDC Japan 2017") C.hello(str) C.free(unsafe.Pointer(str)) } import "C"の上の コメント内にCのコードが書ける GoからCのコードを呼び出せる C上で扱われる値はGoのGCに回収されない Cの char * の変数を用意
  23. 23. cgoのクロスコンパイル (for Android) 23 $ CGO_ENABLED=1 CC=arm-linux-androideabi-gcc GOOS=android GOARCH=arm GOARM=7 go build -buildmode=pie hellocgo.go $ adb push hellocgo /data/local/tmp PC darwinも指定可能 $ chmod 755 /data/local/tmp/hellocgo $ /data/local/tmp/hellocgo Hello, iOSDC Japan 2017 adb shell
  24. 24. NativeアプリとSDKアプリ 24 Go framework file バインディング (Obj-C) 静的ライブラリ Obj-C/Swift UI, IAB, ... ライブラリとして利用 gomobile bind app file Go UIApplication 実行可能ファイルUI, audio, ... gomobile build ■ Nativeアプリ ■ SDKアプリ
  25. 25. Nativeアプリ 25
  26. 26. Nativeアプリの例 26 ■ Flappy Gopher ○ Go Mobileで書かれたゲーム ○ Go Conference 2015 Winter 向けに Andrew Gerrandが開発したもの ○ ソースコード
  27. 27. Nativeアプリの機能 ■ 描画 ● OpenGL ES 2(gl, exp/gl/glutil) ● 2Dシーングラフ(exp/sprite) ■ イベント ● タッチイベント(event/touch) ● ライフサイクル(event/lifecycle) ■ センサー(exp/sensor) ● 加速度、ジャイロ、磁気センサ ■ 音(exp/audio) 27 パッケージ名
  28. 28. Nativeアプリの基本 ■ ループしながらイベントを受信して処理 28 イベントループ 描画イベント タッチイベント ライフサイクルイベント イベントの種類ごとに 分岐して処理
  29. 29. Nativeアプリの描画 ■ OpenGL ES 2 ● gl, exp/gl/glutil パッケージ ● 自前でShaderなどを書く ■ スプライトエンジン ● exp/sprite パッケージ ● 2Dシーングラフ ● OpenGLの関数を余り触らなくて良い ● お手軽に2Dゲームを作れる (OpenGLをゴリゴリ書くよりかは) 29
  30. 30. スプライトエンジン 30 scene gopher スプライトエンジン ground1 ・・・ ノード テクスチャ サブテクスチャ 描画 シーングラフ
  31. 31. スプライトエンジンを使った描画 31 ・テクスチャのロード ・シーングラフの構築 描画イベント ライフサイクルイベント (画面表示開始) ・ノードの再配置 ・サブテクスチャの張替え 繰り返す 初期化処理 アフィン変換行列をセットして、 座標、角度、縮尺を設定
  32. 32. Nativeアプリの問題点 32 ■ テキスト入力 ● テキスト入力が出来ない ● テキストの描画は頑張ればできる ■ プラットホームのAPIが呼べない ● Go側にインタフェースがない
  33. 33. SDKアプリ 33
  34. 34. SDKアプリの例 34 ■ Ivy big number calculator(コード) ● APLっぽい言語の処理系のアプリ ● Rob Pikeが書いた実装をライブラリとして呼び出す ● Android版とiOS版でライブラリは同じ Google PlayApp Store
  35. 35. gomobile bind ■ frameworkファイルを作成 ● Goからビルドした静的ライブラリが入っている ● -targetを指定しないとAndroid Archive ができる ● パッケージ名を指定する 35 $ gomobile bind -target ios mypkg
  36. 36. Obj-Cからの利用 36 #import "ViewController.h" @import Hello; // Gomobile bind generated framework @interface ViewController () @end @implementation ViewController @synthesize textLabel; - (void)loadView { [super loadView]; textLabel.text = HelloGreetings(@"iOS and Gopher"); } @end package hello import "fmt" func Greetings(name string) string { return fmt.Sprintf("Hello, %s!", name) } Obj-C Go 呼び出し
  37. 37. frameworkファイルの利用 37 ビルド プロジェクトに追加
  38. 38. Swiftからの利用 38 import UIKit import Hello class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() print(HelloGreetings("gopher")) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } Swift
  39. 39. gomobile bindで使えるGoの型 39 ■ 基本的な対応型 ● 符号付き整数と浮動小数点数 ● ブーリアン型と文字列型 ● バイトスライス([]byte) ■ 関数 ● 引数と戻り値が対応型の関数 ○ 戻り値は原則1つまで、error型は2つ目にできる ○ 2つ目のerror型はExceptionになる ■ 構造体 ● 公開された対応型のメソッドとフィールド ■ インタフェース ● 対応型のメソッド スライス = 配列の参照型 Goは多値が返せる
  40. 40. 従来のSDKアプリの問題点 ■ Obj-C/SwiftからGoのコードは呼び出せるが逆ができない ● できなくはないけど自分でcgo経由で呼び出すバイン ディングを書く必要がある 40 Go Obj-C Swift
  41. 41. リバースバインディング ■ Goのimport文からバインディング生成 41 import "ObjC/Foundation/NSDate d := NSDate.Date() import "Java/android/app/Activity" type MainActivity struct { app.Activity } For iOS For Android
  42. 42. まとめ ● クライアントをサーバの言語と共通化する ● Nativeアプリ ○ Goだけで書く ○ プラットフォームのAPIが使えないので辛い ● SDKアプリ ○ ライブラリとして組み込む ○ 共通の処理をGoで書いて組み込む ○ 型の制限がある ○ リバースバインディングに期待 42
  43. 43. Thank you! twitter: @tenntenn Qiita: tenntenn connpass: tenntenn 43

×