はじめに
Qiitaハッカソンの予選にてFrontend: React Native, Backend: Pythonという構成のアプリを開発しました。その際に画像をフロントエンドからバックエンドに正しく送信することができませんでした。解決するのに時間がかかったため共有したいと思います。
この記事での構成はReact Nativeと簡易的なNode.jsのServerです。
以下にリポジトリを作成しました。
問題
“react-native-image-picker”というライブラリを使い画像を取得します。
以下のようにformDataにappend、fetchするとサーバー側で0バイトの画像が作成されます。
let file = new File(
[blob],
fileName!,
{
type: fileType as string,
lastModified: new Date().getTime(),
}
);
formData.append('file', file);
対処法
以下のname, uriプロパティを持ったオブジェクトをappend関数の第二引数に指定する。
formData.append('file', {
name: fileName!,
uri: fileUri!,
}
React NativeのFileオブジェクトやBlobオブジェクトではuriプロパティが定義されていないので注意が必要です。
interface File extends Blob {
name: string;
lastModified: number;
}
declare var File: {
prototype: File;
new (
fileParts?: Array<Blob | string>,
name?: string,
options?: BlobOptions,
): File;
};
interface Blob {
readonly size: number;
readonly type: string;
slice(start?: number, end?: number, contentType?: string): Blob;
}
declare var Blob: {
prototype: Blob;
new (blobParts?: Array<Blob | string>, options?: BlobOptions): Blob;
};
理由
React Native 公式documentでは言及されているところを見つけられませんでした。
documentや該当するsource codeを見つけたらコメントで教えてください!
私の考えでは、セキリュティ上の理由からReact Nativeアプリではネイティブコード(Java, Objective-Cなど)を介してでしかローカルファイルシステムにアクセスできないので最低限のnameとuriを指定しネイティブコード側で変換していると思います。
終わりと宣伝
QiitaハッカソンにEngineMakerというシェアハウスのメンバー5人で出場しました。
結果は予選敗退となってしまいましたが、メンバーのほとんどが初ハッカソンでいい経験になったと思います。
EngineMakerはさまざまなエンジニアが住んでいて、イベントに参加したり開発の話をしたり日々面白いことをやっています。一度もくもく会に来てみたら雰囲気がわかるかも!
参考