2020年8月27日木曜日

MacBook Proを買い換えたい話

Flutterの記事を書いてたりするくらいなので、Flutterでスマホアプリを作っているのだが、 
開発マシンは、何と十年来の MacBook Pro (13-inch, Mid 2009)である!  
(この、Apple製品を末永く大切に使っているということだけで表彰してくれないかな。)

OSも当初はネコ科のなんかだったが、OSバージョンアップするごとに
重くなっていったので メモリ8GBへ増設+ハードディスクをSSDに入れ替えて、
今でも現役で使えている。

 ただし、OSのサポートも対象外になってしまったので、OS X 10.11(El Capitan)が 
現在の、そして最後のOSバージョンとなっている。 

ネットを見たり、YouTubeで動画を見る分には問題ないのだが、
どうしてもバージョンの問題は越えられなくなってきた。 

Mac+Flutterでアプリ開発しているので、iOS用にも公開したいのだが、 
iOS用アプリを作るにはXCodeが必要。
そしてFlutterは XCode のバージョン11.0.0.が最低要件となっており、 
それを入れるにはOS X 10.14.4 ( Mojave ) 以上が必要であった。。。ToT  
※あと、確定申告もしているのだが、eTaxの動作環境はOS X 10.11(El Capitan)が対象外で、eTaxページもきっちりバージョンチェックしてるので動かしたくても動かせないToT
なので、VirtualBoxにWindows環境を動作させて行なっている^^(USBカードリーダがVM側で認識してカード読み取りも行えたことが何よりの救いだった。ただし動作はものすごく遅いけど。。OS起動するのに数分〜十数分、何か起動するのに数分、と言った感じ。。なんというか苦行である(さっさと買い換えなさい、という話なのだが^^)
余談ついでに書いておくと、eTaxのMacOS動作環境としてChromeも対応してほしい。プラスシステム言語を英語にしているとeTaxの初期画面で処理が止まって進めなくなる点も直して欲しい。(開発者ツールで処理を辿ってみると言語環境の問題だと分かった。)まぁこれは日本国内用ページなので聞き入れてくれる可能性は極めて低いが^^;)


よほどの細工でもしない限り、この環境は作れないので、
いよいよMacBookの 買い換えを検討し始めたわけである。 

(OS X 10.11(El Capitan)で入れられるのは、XCode 8.2まで。
 XCode 8.2 を入れて、XCodeからFlutterが生成したios用コード(プロジェクト)
 を開いてビルドできないかも試したがダメだった。
   'LaunchOptionsKey' is not a member type of 'UIApplication'
   Type 'GeneratedPluginRegistrant' has no member 'register'
 とかエラー出て、完全に基本的なクラスのバージョンが追いついてない。)
(ちなみにAndroidの開発では、デバッグ用のAVD(Androidエミュレーター)は起動できないので、
 実機をUSBでつないでデバッグしてる。AVDも昔は起動できてたが、
 Android Studioのバージョンが上がって、AVDの起動要件としてCPUの
 仮想化の機能が必要要件になってしまったらしい。)

私用で「次世代住宅ポイント」をもらうことができ、交換商品にも
MacBook Proが あったのだが、2019年モデルしかなかった。 
しかもこういうポイント制度の製品は原価相当であるということと、
せっかく新しいものが欲しいのにすでに1年分の型落ち製品という
ことで、これに飛びつくには至らなかった。

いろいろ検討しているうちにApple Siliconの話も出てきて、早ければ2020年の 
年内にも発売されるとか聞いたので、それまで待つこととした。 
(P.S. 本当に2020年末に出ましたね!情報筋の情報は確かにすごいんだな
 と思いました。)

いやぁ、それにしても長い間お世話になったものだなぁ。 

※余談だが、どこの記事でも見ないのだが、(敢えて触れないようにしてるのかも
しれないが)、 今年(2020年)のMacBook Pro新製品発表 → Apple Siliconの発表 だが、 
MacBook Pro新製品は最後のIntel CPU版Macとなり、買ってしまった人は 
「Apple Siliconがでるならもう少し待てばよかった」となるわけで、 
結構「酷」な発表順序だったと思うのだが。。。 

(むろん商売なので、逆の順番で発表したら誰も買わなくなってしまう、
という判断は 当然あるんだろうけど。 
買ってしまった人は「最後のIntel版Macという貴重なものを買ったんだ」と自分に 
言い聞かせて納得するしかない。無論納得の上で買っているのだろうけれども。 
「買い換えタイミングは古今東西いつも難しい」とよく言われるとおりである。 
ベストなどなくて、自分がいかに納得するか、なのであろう。)

P.S. (2021年10月)
ついに、M1 Pro & M1 Max搭載MacBook Pro 14-inch/16-inch が発売されました!
Touch Barが廃止されたり、各種ポートが昔のように増えたりしてます。
これは色々試すことで、なぜ物理キーが良かったり、ポートはあまり集約しすぎないほうが良いという具体的な問題点が分かり、原点に戻るというか先祖返りしたようなものでしょうか?(具体的に試して具体的な「理由」を得るという意味でAppleのしたことは無駄では無かった。)
ちょうど現在私が使っているMacBook Pro (13-inch, Mid 2009)と似た構成になっており
(さすがにCD/DVDドライブはなくなったけど…^^(いつの時代の話だと驚嘆することでしょう。))、私的には「Touch Bar?なにそれ」といった感じで、
正に私が買い換えるために作ってくれたのだと思います。(絶対違うけど。)

P.S. (2022年3月)
そしてついにMacBook Proを買い換えました!2009年モデルと比較したのでよかったらどうぞ。

2020年8月18日火曜日

Fortnite騒動について(アップルvsエピック訴訟)

 人気ゲームFortniteがAppleとGoogleのアプリストアから外されたり、
開発者アカウントを剥奪されそうだったり、何かと話題になっているが
問題の本質は「比重」なのだろう。
 つまり「アプリ市場」という大きな枠で見たときの、市場への貢献度の「比重」。
 AppleやGoogleのアプリストはものすごくよいアプリ配信プラットフォームを
提供してくれており、個人や中小企業など販路を持っていなくても、
アプリを開発するだけで、あとは勝手に全世界のユーザに提供できる
恩恵にあやかれるのである。
 片やFortniteとしては、十分大きなユーザを獲得し、開発にも膨大な
リソースを費やしているにも関わらず、無条件で3割もの利益を吸い上げ
られる仕組みに納得がいかなくなってきたのだろう。
 おそらく結果としては、最初のAppleなりGoogleなりのアプリストアに
配信する時点で、契約として上記内容も「飲んだ」上でアプリ開発しているので
Fortnite側の勝算は低く、そんなことは当のEpicも熟知した上で、
敢えて勝負を挑んで、世界にその理不尽を問いかけたという点で
意味のあるものにしようとしているのだろう。
 
 Apple、Googleとしても、Epicが本気でFortniteユーザをつれて離脱されたのでは
困るだろうから、これを機に「比重」を考慮するポリシーに変更を検討するか
どうか、が今後の注目ポイントである。
 ある意味、それだけの強力なアプリ提供者が育ったため、いよいよ
表層に出てきた問題といったところだろう。
 「アプリ市場」で見たときの貢献者は、アプリストア提供者と
実際のアプリを作ってる者であり、前者はある意味、仕組みさえできれば
あとはほっといても勝手に金が入る仕組みである。
 逆にアプリ開発者はより多くのユーザを獲得するため、恒常的にリソースを
費やしていかなければならない。
 ある規模になると、
  アプリストアで得られる恩恵 < アプリ開発者のコスト
の関係になり、こうなってくるとアプリ開発者たちは「こんなに必死こいて
アプリを作ってるのになんでこんなに利益を巻き上げられなければ
ならないのか?あちらは何もしてないのに。」ということになってくるわけである。
たしかに、自社のために働いているはずが、なぜかストア提供者を
慈善事業的に養ってあげてる感覚になるのだろう。
 または、恩恵を与えてくれた親なので、成人して養うのは良かったが、
親を遥かに凌ぐようになったのにも関わらず、最初に約束した3割負担と
いうのがどこまでも付きまとうので、「親だからって、いい加減に
してくれ!」といったほうが的を得るだろうか?
 たしかに、利益の規模を度外視して3割の巻き上げでは大きくなればなるほど
アプリ開発者側は割に合うまい。
 上記分岐点を境にして、巻き上げ比率引き下げをストア提供側が
検討してくれるかどうか、今後の展開が面白い。
 いずれにしても、これまでもそうであったように、「アプリ市場」などの
全体規模で考えた場合は、それぞれWin-Winの関係に落ち着いていくのであろう。
ーーー
 Win-Winになるかどうかは、問題解決の当事者が問題の本質を
高所から見ることができるかどうかが前提であったりするのだが。
 なにやら開発者アカウントがUnreal Engineまで影響して、サードパーティが
離れていくとか、問題を複雑化しているが大丈夫だろうか?
 過去にも問題の本質よりも、目先の自分の正当性だけ主張して
泥沼化して、結局市場も発展しなくてlose-loseになってしまった失敗事例は
むしろ彼らのほうがよりよく知っているであろうから、ちゃんと
問題の本質を理解して対応してくれるであろう。
 (lose-loseにしてしまった当事者は、社内では「よくぞ我が社の利益を
守った」と言ってもらえるであろうが、業界全体や世間としては、
「あー、はい、そうですか。それはよかったですね」と見られること。)

ーーー
追記
裁判所も想定通りの方向となった。現状では双方譲らない姿勢。
ふと思ったのだが、この「お祭り騒ぎ」も「市場全体」からみれば
多くの人の関心を引くという意味では効果抜群なわけであって、
一旦お祭りが始まったのであれば、なるべく熱を保って長引いた
ほうがよいわけである。
思ったのは、双方ともそれくらいまではわかってるはずで、
つまりそこまで「想定」されてお祭りをしているのではないだろうか?
ということ。(そうなると裁判所の見方も変わってきてしまうだろう。
どうかうまいことやってもらいたいものだ。)

ーーー
さて、AppleもGoogleも年間収益100万ドル以下のデベロッパーに対しては、
30%の手数料を15%に引き下げた。先手を打った形だろう。
「デベロッパーのことを思っていろいろやってるのですよ、文句ないでしょう」と。

しかし上記の「市場への貢献割合」の考え方からするとむしろ逆に
貢献度の低いデベロッパーへの救済策である。
これは富裕層ほど高い税率の考えなのだろうか。
しかしそんなことは行政がやることであってEpicが提唱している問題は
そうではなくて、やはり「市場への貢献割合」の問題であろう。
小規模デベロッパーの30%の手数料を15%に引き下げはむしろ火に油を注ぐ
格好になってるが、大丈夫だろうか?

最初に戻って、これこそが「先手を打った」意味なのだろう。
富裕層からはとことん取るということで、とことんやりあうというわけですね。
おそろしい。

2020年6月5日金曜日

Raspberry Pi で ROBLOX という世界的に有名なゲームを実行

  • 環境
本体:    Raspberry Pi 4B
OS:     Raspberry Pi OS → LineageOS 16.0

  • ROBLOXとは
私はハードウェアよりもソフトウェア寄りな人なので、
Raspberry Piを入手して真っ先に試したのがROBLOXを動かす事だった^^

ROBLOX とは世界的に有名なオンラインゲームプラットフォーム。
どちらかというと子供向けであるが、ゲームの内容によって
ものすごく作り込まれたゲームもあったりするので、
大人がやっても面白い。
逆にヘビーなゲーマーでなくてもお手軽にできる点が
いいのかもしれない。

最近はメニューとかも日本語化されたようなので
日本人ユーザも見かけるようになってきた。

(脱線) 
アジアで言うとフィリピンと韓国のユーザが多いように感じる。
※フィリピンはタガログ語で会話している人、韓国人はハングル文字を
使ってるユーザで観察した、あくまで私の感覚値。
フィリピン人は英語ができてしまうので、ゲーム中でも普通に英語を
使ってる人も多数いるはずで、そうするとフィリピン人の潜在ユーザは
もっと多いはず。(ご存知の通り文化的にもアメリカナイズされているので
このゲームもみんな普通にやってる。)
それ以外にはベトナム語やタイ語をたまに見かける。ごく稀に中国語を
見たが繁体字だったので台湾人だろう。
(我是變態とか言ってて笑ってしまった。誰も分かるまいとでも思っていたのだろう。)
(簡体字の国は情報統制でできない?あ、ハングルの北の方は言うまでもないですね。。)
(脱線終わり)

  • 結論
最終的にRaspberry Pi上でもROBLOXを動かす事がきた。
ただし、OSはLineageOSというものに入れ替えた。
LineageOSとはAndroidをベースとした、スマートフォンや 
タブレット用のフリーでオープンソースなオペレーティングシステムである。
LineageOS:フリー百科事典『ウィキペディア(Wikipedia)』 (2020年4月25日 (土) 09:21 (日時は個人設定で未設定ならばUTC)版より)

 LineageOSの公式版ではRaspberry Piは動作対象となってないが、有志が提供して
くれたりするのでRaspberry Pi + LineageOS で検索すればすぐに見つかる。

詳しい手順はみなさんが書いてくれているので、ここでは実際にやってみた
ときの補足説明を書いておく。

まずはLineageOSの作業としては、Raspberry Piとは別のマシン上での操作。
・LineageOSイメージをダウンロード
・新しいSDカードを用意して専用ソフトでLineageOSイメージを書き込み
・SDカードをRaspberry Pi に入れて起動
となる。

次にPlay Storeの追加。LineageOSにはデフォルトではPlay Storeが
入ってないので追加する必要がある。
これも手順(英語)があったので、それに従って実行。
流れ的には
・Play Store追加用イメージをダウンロード
・TWRP recoveryモードで再起動
・Play Store追加用イメージのインストール
・TWRP recoveryモード解除して再起動

まずPlay Store追加用イメージをダウンロードであるが、LineageOS上の
ブラウザでダウンロードできると思うが、私は別マシンでダウンロードして
Android Studio付属の「adb」コマンドでRaspberry Piに転送した。
( adb push コマンド)


次にTWRP recoveryモードで再起動であるが、LineageOS上で以下を実施。
・開発者モードをONにする。(Androidと同じ操作)
・ローカルターミナルをONにする。
・ローカルターミナルappを起動して 以下を実行。
su
rpi4-recovery.sh
・再起動
 
次にPlay Store追加用イメージのインストールであるが、 上記で再起動すると
TWRPが起動する。
そのメニューの中に「install」があるので、最初の手順でダウンロードした
ファイルを選択してインストールする。

正常に完了したら本来はTWRPメニューの Wipe → Factory Reset をするべきだが、
私はこの手順を飛ばしてしまった。しかし特に問題はなかった。

最後にTWRP recoveryモード解除して再起動は、TWRPメニューの
「Advanced」にterminal があるので起動して、以下のコマンドを実行。
rpi4-recovery.sh boot
bootが見つかりません見たいなエラーが出たら、TWRPメニューの
Mount → Boot にチェックをつけてから再実行。

これでRaspberry Piを再起動すれば Googleアカウントとか聞かれて
ログインすればPlay Storeが使えるようになる。

あとは普通にPlay StoreからROBLOXをインストールするだけ。

めでたくRaspberry Pi上でROBLOXが実行できた!
が、残念ながら実行速度はかなり遅い。

アーキテクチャ的にはRaspberry PiのARM CPU上で、ARM用の
LineageOSが動作し、その上で(当然ARM構造の)Robloxが動作
しているので、アーキテクチャ的には問題はない。
(他の試行と違ってエミュレータなどを挟んでない、という意味。) 
 
Raspberry Piのマシン的な限界なのだろう。

どれくらい遅いかというと、ROBLOXの人気ゲーム「Tower of Hell」で
最初の階段を登って、最初のブロックに飛び乗ろうとするが
ラグがひどすぎて飛び乗れずに諦めたくらいの遅さであった^^ 

  • 調査の経緯
最終的にはLineageOSで実現できたのだが、そこに行き着くまでの
経緯も簡単に書いておく。

Raspberry Pi + ROBLOXで調べ始めて最初に出てきたのは「wine」
つまりWindows用 roblox.exe を linux上で動作させましょうという発想。

しかしこれだけだとアーキテクチャの問題が出てくる。
roblox.exe は x86 だけど、Raspberry PiはARMということ。

そこで出てくるのが「ExaGear」。これはeltechsという会社が作ってた
もので、x86をARM上で動かす仕組み。
有償で、動作にはライセンスが必要。
ただしネット上の情報によれば現在はMicrosoft社に買収されたようで
現在ではExaGearは取得できなくなっていた。

他には「qemu」「box86」など。
調査の結果、どこかの記事で「エミュレータでx86をarmには変換できるが
WindowsというOSひっくるめた環境上で動くアプリケーションを
動かすのはまた別の話」みないたところに行き当たって、あぁ
確かにと思った。
そこまでクリアするとなると、かなり壮大な話になってくる。 

そこから発想を切り替えて、幸いROBLOXはWindows用、Mac用、
ios用、android用といろいろなプラットフォーム用に作られているので
Raspberry PiのARMアーキテクチャに一番近いAndroidでいけるんじゃ
ないかと行き着いたわけである。

私はゲーマーではないが、たまたま手持ちのAndroidスマホで
唯一遊んでるゲームがROBLOXだったので、Raspberry Piでもできないかな?
せっかく大画面のPCモニターもあるんだし、くらいの発想で
トライしてみた。

「WindowsのゲームもRaspberry Piで遊べないかな?」という発想では
ないので、ご注意いただければと思う。

2020.12.11 追記
「Arm用Windowsでx64エミュレータ実装版が公開」のニュースを目にした。
これって正しく ExaGearを作っててMicrosoft社に買収されたeltechs社に
よる実績だったんじゃないかと思った^^
たしかにこんなことがサードパーティでやられたら、Mirosoft社としては
何かと大切なところを削がれてしまうので買収したのだろうかな。。

2020年6月2日火曜日

Raspberry Pi 4Kモニター文字小さい

【環境】
本体:    Raspberry Pi 4B
OS:     Raspberry Pi OS
モニター:    某4K PCモニター

【症状及び解消方法】
4Kモニターに接続した場合、Raspberry Pi OSの
初期状態だと、メニューとか全体の文字が小さすぎる
ので、以下で変更可能。

※Raspberry Piに限らず、UNIX系OS全般的に同じような設定で解消可能と思います。

スタートメニュー
→設定(Settings)
→ Appearance Settings
→ Defaults
    "For large screens:" を選択

















ただし、システム周りのフォントは大きくなるが、アプリケーション
内部のフォントは個別に設定する必要がある。
(中には変更できないものもある。)

その煩わしさを考えると、4Kの恩恵はなくなってしまうが、解像度を
あえて下げるのも一案である。

解像度の設定変更は、
スタートメニュー → 設定(Settings) → Screen Configuration
スクリーンを右クリックして → 解像度(Resolution) → 目的の解像度を選択


2020年4月18日土曜日

Flutterのダークモード対応Webview

Flutterでアプリ開発してて、プライバシーポリシーとか
HTMLファイルを表示したい時がある。
(ネットまで接続させたくなく、リソース上の固定HTMLファイルでよい場合。)

また、同時にダークモードにも対応したい場合は以下のパッケージが便利。

simple_dark_mode_webview

使い方は以下の通り。
import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:simple_dark_mode_webview/simpledarkmodewebview.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Simple Dark Mode Webview Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      // ダークテーマを設定する
      darkTheme: ThemeData(
        brightness: Brightness.dark,
        primarySwatch: Colors.green,
      ),
      home: MyHomePage(title: 'Simple Dark Mode Webview Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Container(
              color: Colors.grey,
              child: Text(
                'This widget is useful specially when you want to show a static HTML file!!!',
              ),
            ),
            Expanded(
              child: FutureBuilder(
                // 固定ファイルを読み込む。
                future: rootBundle.loadString('lib/assets/sample_policy.html'),
                builder: (context, snapshot) {
                  if(!snapshot.hasData){
                    return Text('loading...');
                  } else {
                    // ダークモード対応WebViewを使用
                    return SimpleDarkModeAdaptableWebView(
                      snapshot.data,

                      // (例) HTMLファイルのテキストエンコーディングを指定
                      encoding: Encoding.getByName('utf-8'),

                      // (例) WebViewへの操作(ジェスチャー)も登録可能
                      gestureRecognizers: Set()
                        ..add(Factory(() =>
                        TapGestureRecognizer()
                          ..onTapDown = (tap) {
                            final snackBar = SnackBar(content: Text('Webivew was tapped down.'));
                            Scaffold.of(context).showSnackBar(snackBar);
                          }
                        )
                      ),
                    );
                  }
                },
              )
            )
          ],
        ),
      ),
    );
  }
}

2020年4月11日土曜日

Flutterパッケージ公開先の pub.dev で実行してくれる「pana」をローカル環境で実行する方法

【環境】
macOS 10.11 El Capitan
Android Studio 3.6.2
Flutter 1.17.0

【内容】
Flutterパッケージを https://pub.dev に公開すると、スコアリングを
自動で実行してくれるが、その仕組みが「pana」。

これをローカル環境で実行する方法。

https://pub.dev/documentation/pana/latest/

に基本的なことは書いてあるので、補足しておく。

ページには、Installationとして「pub global activate pana」とあるが、Flutterからだと、
flutter pub global activate pana
を実行。

実行結果にインストールされたパスが出力されるので、パスを通す。
(そのコマンドまで表示してくれるので、その通りに行う。
 macOS であれば、 ~/.bashrc などに export PATH=....)

panaの解析を行いたいプロジェクトのパスまで移動。
一旦コマンドを試してみる。
(path_of_the_flutterはご自身の環境のFlutterインストールパス。)
pana --flutter-sdk path_of_the_flutter -s path ./

ここで
pana: line 7: dart: command not found
と表示されたら、dartのパスも通す必要がある。
Android Studio の Android Studioメニュー → Preferences → Languages & Frameworks → Dart
に Dart SDK path が載っているので、このパスもシステムのPATHに登録する。
(先ほどの~/.bashrc などに export PATH=....と同様の手順。)

これで再度panaコマンドを実行されれば結果が出力されるはず。

2020年4月9日木曜日

Firestoreで思った通りのデータが取れない

Androidアプリでリリース版を公開したがFirestoreのデータが
思い通りに取れなかった。

慌ててデバッグし直したところ、以下のようなエラー(警告)が
発生していた。

W/Firestore(nnn): (x.x.x) [Firestore]: Listen for Query(texts where col1 == value order by col2, __name__) 
failed: Status{code=FAILED_PRECONDITION, description=The query requires an index. 
You can create it here: xxxxx

そこに表示されたURLをクリックすれば作成するべきインデックス情報を
引き継いで表示しているれるので、インデックス作成をクリックするだけで
解決。

そもそも、デバッグ版とリリース版で条件を変えていて、以前に動作してた
と勘違いしたため、テストせずにリリースしてしまっていた。