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

GoによるiOSアプリの開発