GOをgopherjsでjavascriptに変換してからCordovaで利用することを考えます。
os.Open()
などでファイルを開く処理はnode.js以外で使えない。
Cordovaで操作可能な場所のファイルを使う場合でもPermission deniedになる。
そこで基本的にCordova側で入出力してGO側で実処理と変換を行うようにします。
まずはos.Openを試してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/* test.go */ func testFunc(name string)string{ f,err:=os.Open(name) defer f.Close() if err != nil{ return err.Error() } return "ok" } func main() { js.Global.Set("testFunc",testFunc) } /* useTest.js */ let base = window.cordova.file.applicationDirectory+'www/static/media/'; window.testFunc(base+"somefile"); // => open file:///android_asset/www/static/media/somefile: Permission Denied |
gopherjsで変換後のjsを見ると何らかのsyscallを呼んでいますが、osかブラウザセキュリティかの問題で権限不足のエラーになります。
CORDOVA(javascript)→GO
GO側ではファイル操作できないのでjs.Object
を変換するコードを入れる。
1 2 3 4 |
func testFunc(jso *js.Object)(){ file :=js.Global.Get("Uint8Array").New(jso).Interface().([]byte) ... } |
ちょっととっつきにくい。キャストしてアサーションしている感じだろうか。
CordovaではFILEプラグインを導入後、resolveLocalFileSystemURL()
を使ってファイルアクセスしてArrayBuffer
を渡します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
window.resolveLocalFileSystemURL( name, (entry)=>{ entry.file( (f)=>{ let reader = new FileReader(); reader.onloadend = function(evt){ testFunc(reader.result); } reader.readAsArrayBuffer(f); }, (e)=>{alert("file err:"+e.code);} ); }, (e)=>{alert("resolve file err:"+e.code);} ); |
無事ファイルを渡せました。
GO→CORDOVA(javascript)
こちら側は比較的簡単で変換用の関数を呼んでjs.Object
型で返すだけでいい。
[]byte/[]uint8
をArrayBuffer
に変換して返すようにする。
ファイル操作はbytes.Buffer
をよく使うのでBytes()
で変換もかませる。
1 2 3 4 5 |
func testFunc()(*js.Object){ buf := new(bytes.Buffer) //バッファにファイル内容を保存したり return js.NewArrayBuffer( buf.Bytes() ) } |
Cordova側では通常の書き込みを行う。
1 2 3 4 5 6 7 8 9 10 11 12 |
file = window.testFunc(); window.resolveLocalFileSystemURL( window.cordova.file.dataDirectory, (dir)=>{ dir.getFile(name, {create: true}, function(entry) { entry.createWriter(function(writer) { writer.write(file); }); }); }, (e)=>{ alert("resolve dir err"+e.code); } ); |
こちらも無事ディレクトリに保存できました。