1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[iOS]FlutterでHTTPレスポンスのバイトデータをUTF-8にdecodeできない問題の解決方法

Last updated at Posted at 2021-01-24

趣味でFlutterを使ってアプリを作っている際にHTTPレスポンスのバイトデータをUTF-8にデコードする際に詰まったので解決方法を共有します。

問題

WebViewで指定したURL(以下targetURL)を表示する前にページの内容を確認する場合、以下のようにHTTPレスポンスのバイトデータをUTF-8でdecodeし文字列に変換したい場面がありました。
response.bodyをそのまま扱おうと思いましたが、後述同様に詰まりました。
下記はこの記事を参考にしています

issue
var response = await http.Client().get(Uri.parse(targetURL), headers: {'User-Agent': userAgent});
String decoded_body_byte = await CharsetConverter.decode("UTF-8", response.bodyBytes); // charset_converter: ^1.0.3
print("decoded_body_byte: ${decoded_body_byte }"); // decoded_body_byte: nullとなる

上記をiOS Deployment Target=9.0でPhone12 Pro Maxのエミュレータで実行した結果、3行目のコメントにあるようにUTF-8でdecodeされたHTML文字列が格納されている想定のdecoded_body_byteはnullとなってしまいました。
AndroidのPixel 2のエミュレータでは問題なくdecodeできていたのでiOS特有の問題かと思います。
2行目を以下1.2.に置き換えてもしてもこの行以降にプログラムが進まなくなってしまいました。

試行1
var decoded_body_byte = utf8.decode(response.bodyBytes); // この行以降進まない
試行2
var decoded_body_byte = Utf8Decoder().convert(response.bodyBytes); // この行以降進まない

解決方法

原因はdecode対象のHTTPレスポンスボディにUTF-8にとって不正な文字列が含まれていたことのようです。
bodyBytesにsublist(start, end)メソッドを用いて一部分のdecodeを試みたところ成功した及び以下のコードで成功したことが上記推測の根拠です。

solution
var decoded_body_byte = Utf8Decoder(allowMalformed: true).convert(response.bodyBytes);

Utf8DecoderallowMalformed: trueとする事により、UTF8の不正文字置換オプションを有効化できたことが効いたようです。

皆様の参考になれば幸いです。

もしよろしければ以下アプリを使ってみていただければ幸いです。
評価いただければ更に嬉しく思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?