リバース・エンジニアリング

Flultterとテックブログと時々iOS

WWDC 2020のKeynoteをリアルタイムで見た感想

WWDC 2020 日程について

今年の WWDC 2020 の日程は日本時刻6/23(火) 2.am - 6/27(土)までです。

https://jp.ubergizmo.com/wp-content/uploads/2020/03/wwdc-2019.jpg

日本時刻の6/23(火)深夜2時から WWDCKeynote が始まったので気合と根性で睡魔と戦いながらリアルタイムで見てました。

Keynote のビデオ

https://developer.apple.com/videos/play/wwdc2020/101/

iOS アプリエンジニアだったらだいたいの人がこのビデオを現地かネットで観ます。
今年の WWDCコロナウイルスの影響でオンラインになって、さらに Apple Developer Program に参加していれば無料で視聴できます。
そのため今週の日本時刻の深夜はずっと WWDC のセッション動画を観るために寝不足が続きます。

今回の発表ではソフトウェアがメインだったのでハードの発売などの情報は全くありませんでした。
期待していたハードは新型MBPです。僕のマイマシンはMBP2017年モデルでそろそろ買い替え時なので。

気になった機能について

Keynoteを2時間観た感想でめちゃくちゃ気になった機能は

  • WidgetKit
  • PencilKit
  • App clips
  • SwiftUI
  • translate

App clips はまだどこまで使えるかは分かりませんが、新しい概念なので入れておきました。
WidgetKit の登場でこれからは各社・各デベロッパーでホーム画面のウィジェットの取り合いが始まることが確定です。
WidgetKit 自体は Android と同じで Android の丸パクリ機能ですね。

超個人的に PencilKit の機能が気になりました。
これは以前に早速記事で書きました。

tamappe.hatenadiary.com

WWDC のセッション動画で PencilKit の関連動画はまだまだありますので情報を追っていきます。
iPad アプリで YouTube で配信できるようなお絵かきアプリを作ってみたいです。

その他の印象は SwiftUI がパワーアップしていたこと。
去年は SwiftUI で一覧を表示するデモで List が登場していました。
今年は UICollectionView に取って代わる LazyVGrid と LazyHGrid が登場しました。

Flutter の GridView と同じ発想であれば、

LazyVGrid: Grid を縦に並べるもの
LazyHGrid: Grid を横に並べるもの

と考えればほとんど Flutter の置き方と同じです。
そもそも SwiftUI のアプローチが Flutter や React を意識してる感じです。

僕の考えは Flutter の考え方を身につけば、 SwiftUI の学習コストは低いと思ってます。
そして WidgetKit が SwiftUI を前提にしているところが本当に Apple らしい。
ウィジェットを使いたいなら SwiftUI を使ってね、としか聞こえないから。

そんな本音が聞こえてきた動画でした。
まあ WWDC は始まったばかりなので今週は1日2時間ぐらいの時間を確保してセッション動画を視聴していきたい。

それでは、バイバイ。

WWDC 2020の What's new in PencilKitを見た感想

【目次】

What's new in PencilKitを見た感想

日本時刻の6月23日2時からWWDC 2020 が始まった。

WWDC 2020 オープニング動画の感想はまた別の記事で書きますが、今日はオープニング動画で気になったPencilKit について感想を書きます。

What's new in PencilKit

https://developer.apple.com/videos/play/wwdc2020/10107/

PencilKit は iOS 13 で初めて登場したSDKです。
ドキュメントはこちらです。

https://developer.apple.com/documentation/pencilkit

当初、Apple Pencil がiPad専用機みたいな位置付けみたいな印象があったので気にも止めていませんでしたが、 今年はさらにパワーアップしてとうとうiPhoneでも使えるようになったそうです。

新しい機能

iOS14 では新しい機能として

  • Global setting: pencil or finger
  • New API

の2つがメインテーマでした。

f:id:qed805:20200624130701p:plain:w300
new color picker

もしかしてこのカラーピッカーのUI使えるの?って思いました。
ペンシルのカラーを変更する時にこのカラーピッカーが使えるのはとても便利という印象。

またPencilKit はCatalyst support らしくmacOS でも使えるそうな。(マジかって思った。)

指の認識が可能かどうか

ペンシルと指の認識自体は

UIPencilInteraction.prefersPencilOnlyDrawing

でBool型で取得できるらしくtrueならペンシル、falseなら指と判定される仕様だそう。

  • var allowsFingerDrawing: Bool が非推奨
  • var drawingPolicy: PKCanvasViewDrawingPolicy が推奨

に変更されました。
1年でdeprecated になるとかAppleはメチャクチャな事をアッサリするなぁって感じ。
またPencilKit を使いながら、スクロールしたり文字と文字の間にスペースを入れられるようになるらしいです。
ワンタップでスペース入れられたり削除できるのは割とUX的にGood。

PKToolPickerAPIも変更されるそうで

  • public func shared(for: UIWindow) -> PKToolPicker? が非推奨
  • public func init() が推奨

と変更される。

その他感想

セッション動画ではiPhoneでも使えると説明されていました。
iPhone で指を感知できるみたいでこれでiOS版でお絵かきアプリのアイデアが出てきます。
それとScribble の機能が追加されたことでiPadアプリがより便利になる未来しか見えなくなった。

あとで確認したらiOS 13で使えるみたいだからiPhoneアプリに対応しているらしい。
すぐに作りたいアプリはiPad版の動画作成補助アプリ。

動画の編集でApple Pencil でお絵描きできたら地味に便利な感じがする。
それぐらいPencilKit に未来を感じた。

それでは、バイバイ。

65. FlutterでListの要素をランダムにシャッフルするには

開発しているアプリでListの要素をランダムシャッフルして格納し直す必要が出てきたので ランダムにシャッフル出来ないのかを調べてみました。

List _shuffle(List items) {
    var random = new Random();
    for (var i = items.length - 1; i > 0; i--) {
      var n = random.nextInt(i + 1);
      var temp = items[i];
      items[i] = items[n];
      items[n] = temp;
    }
    return items;
  }

これでListに入っている要素をランダムに並び替えることができる。

final list = List<int>.generate(25, (i) => i + 1);
print("list: $list" );
final randomList = _shuffle(list);
print("randomList: $randomList" );

# 結果
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
# [12, 3, 18, 8, 23, 20, 7, 10, 9, 1, 19, 5, 6, 4, 17, 24, 21, 11, 16, 13, 22, 15, 25, 14, 2]

参考にしたページを貼ります。

stackoverflow.com

iPhoneのワイヤレス充電器がマジで使えたのでレビューしてみる

【目次】

ワイヤレス充電器Anker PowerWave 10 Stand を購入した

何を購入したのかというとアマゾンでワイヤレス充電器を購入しました。

開封 開封
f:id:qed805:20200614123739j:plain:w300
商品未開封時のイメージ
f:id:qed805:20200614123926j:plain:w300
蓋を開けた時

Anker PowerWave 10 Stand ってやつです。

なんで購入したのかというと今使っている機種がiPhoneSE(第2世代)で、この機種が自分の中で神機判定しているのであと4年は使い続けたいと思った。

これまでもiPhoneを購入すると2年以上は使ってきた実績があるが、2年以上使うとバッテリーが消耗してすぐに電池が切れたり、充電ケーブルをつなげるのだけど、iPhone側の差込口が消耗してケーブルを受け付けなくなって充電ができなくなったりした。

今回はそれが嫌なのとiPhoneSE2はワイヤレス充電対応機種ということなので、試しにワイヤレス充電器を使ってみることにした。

ちなみにワイヤレス充電器は過去に一度失敗している。

ワイヤレス充電の対応機種

レビューを行うのだが、そもそもワイヤレス充電器に対応している機種はiPhone 8以降の機種です。

iPhone 7より前の機種は非対応のため、そもそもワイヤレス充電器が使えません。

また、Androidで対応しているシリーズは下記になります。 機種によっては非対応の場合があります。

ちなみに今回購入したワイヤレス充電器で今持っているPixel 3 の充電ができました。

ワイヤレス充電のイケてるところ

・ iPhoneSE の充電ケーブル差込口が汚れないこと。

iPhone の差込口が本当に汚れなさそうでいいです。

今まで差込口が汚れて充電を認識してくれなかったりしたのですが、このスタンドを使うことでケーブルの差込口が汚れなさそうだし壊れなさそうなので長く持ちそうです。

・スタンドに置くだけで充電できる手頃さ

割と手頃にスタンドに置けてます。縦置きはもちろんOKだし、横向きで置くこともできてます。 基本、寝る前に充電を始めているので目覚ましアプリを起動しながら充電しているのですが、 横向きでおいても使えるので横向きで置くことで時計側にもなりました。

縦向き 横向き
f:id:qed805:20200614130106p:plain:w300
縦においた時
f:id:qed805:20200614130153p:plain:w300
横においた時

ワイヤレス充電のイケてないところ

充電速度がケーブル充電よりもちょっと遅いかも

1週間ぐらい使ってみての感想ですが、USBケーブルよりも充電速度が遅いのはありました。

今はリモートワークで外出することが少ないですが、自粛モードが解除されオフィス出社が全面的に開放された時、自宅に帰宅後スマホをワイヤレス充電器で充電しようと思ってすぐに10%とか回復しない気がします。

僕はお風呂に入るときにスマホを充電するのですが、20分ぐらいの入浴したあとにバッテリーの残りを見たら5%ぐらいしか回復していませんでした。 (もしかしてこれぐらいが標準なのかもしれないが)

寝る前はほぼ1桁%ですが、これはもうワイヤレス充電器を使っても5分で1%ぐらいしか回復しません。

この時はケーブルに繋げながらスマホを使う方が快適そう。

ワイヤレス充電器の寿命問題

これは心配している方。僕は面倒なので常にワイヤレス充電器をコンセントにつなげたまま使っています。

これでどれくらい充電器のパフォーマンスが落ちないかこれから検討していこうと思います。

これが1年ぐらい持つのであれば値段分のクオリティがある気がしてます。

なんせ、スマホの充電差込口が汚れないのでiOSアプリ開発者としては非常に助かりますから。

iOSアプリ開発の時、Macスマホを接続しながらアプリをインストールする必要があるのでケーブルの認識が効かなくなったら実機に作っているアプリをインストールできなくなります。

過去に何度かスマホをケーブルで繋げてもMacが認識しないことがあったのでその時はUSBケーブルを新しくしたりして凌いでいました。

Appleの公式USBケーブルって高いですからね。

ワイヤレス充電器で必要なときだけケーブルを使うようにしたらこの問題が解消しそうなのでこの効果に期待しています。

これは1年後ぐらいに結果を報告するかもしれません。

それでは、バイバイ!

接触確認アプリをiOS版でダウンロードしたので早速レビューしてみる

【目次】

接触確認アプリをiOS版でダウンロードしたので早速レビューしてみる

6/19の金曜日15時に厚生労働省接触確認アプリをリリースしたらしいので仕事の終わりぐらいに早速ダウンロード「しようとした」。

あえてダウンロード「しようとした」と書いた理由が、昨日次点は私の iPhone の OS バージョンが 13.4.1 で接触確認アプリの要求水準のiOS 13.5 に達していなかったので最初はダウンロードできなかった。

昨日の15-18時頃はそのリリースでお祭りだったみたいだが、そもそも昨日にリリースとは知らなかったのでそのお祭り騒ぎに参加できなかったのはちょっと悔しい。

それでも仕事中にわざわざ iPhone をアップグレードするのもなんか嫌だなぁ、とかいいながら結局は夕方頃に OS をアップグレードしてインストールしてみました。 Android 版は確か夕方の18時頃にアナウンスが有った記憶があります。

金曜日の18時にリリースするって結構勇気が必要な気がします。

接触確認アプリのインストールページ

iOS 版は App Store のページでこちらになります。

アプリ名の公式は「新型コロナウイルス接触確認アプリ」となっています。

新型コロナウイルス接触確認アプリ

新型コロナウイルス接触確認アプリ

  • Ministry of Health, Labour and Welfare - Japan
  • メディカル
  • 無料
apps.apple.com

Android 版は Google Play Store になります。

play.google.com

ダウンロードするためには iOS 13.5 、 Android 6 以上である必要がありますので事前に端末の OS をアップグレードする必要があります。

接触確認アプリのスペックについて

それでインストールして改めて接触確認アプリのスペックを確認してみたんだけど、やっぱり色々違う意味でとても驚かされることばかりだった。驚いた点を箇条書きしてみると

  • iOS 13.5 以上でしかダウンロードできない
  • Xamarin で作られているらしい
  • アプリの容量が 140MB でゲームアプリと同じか、標準アプリよりも容量を使う
  • 金曜日にアプリをリリースしているということ
  • アプリに関するお問い合わせに載っているリンクが存在しないページのリンクであること
  • ブルートゥース(Blurtooth)を使っていること
  • アプリを削除したら接触履歴が消えてしまう
  • サイドメニューがドロワーと懐かしいUI を採用している
  • 使い方画面のUITableView の区切り線が見えたまま
  • iOS 13.5 以上でしかダウンロードできない (あえて2回書く)

あとなんか 6/19 にインストールしてアプリの初期設定を終えたはずなんだけど、 アプリの履歴では 6/20 から使用中となっている。

接触確認アプリをちょっと使ってみての感想

この接触確認アプリはおそらく2年後を見据えてるんだと感じました。本番は来年夏の2021年8月のオリンピックだろうと思います。

今年 AppleiOS 14 をリリースすると思うんですが、2年後の最低スペックが iOS 13 になることを考えると要求スペックを iOS 13.5 にしておくと iOS 15 が出てくる頃くらいまでは全くアップグレードしなくてもこのアプリが使えるのです。

3年後の iOS 16 が出る頃ぐらいにこのアプリも OS アップグレードのメンテナンスが必要になってくるだろうと思いますが、3年もすればおそらくコロナ騒動は一段落している気がします。

そう考えると今の時期から全くメンテナンスをしないという要件をクリアするとなると iOS13 の最新バージョンを要求するのはある意味理にかなっているかもしれないと思いました。

開発者視点の感想

開発者からしたらこのタイミングで iPhone を使っているユーザーが皆最新バージョンにアップグレードしてくれるのは有り難みしかないです。

厚生労働省名義のこのアプリの要求スペックが iOS 13.5 以上と線を引いてくれると、例えば受託開発でもクライアントからどこまでのOSをサポートすればいいのかを尋ねられた時に、厚生労働省のアプリが iOS 13.5 以上だから iOS 13 からをサポートすればいいと思いますよ、という回答を用意できます。新規アプリ開発だとiOS 13 からサポートにすればいいということ。

これは開発者からしたら非常に嬉しい話しですね。逆に iOS 11や iOS 12 までのアプリの挙動を確認する必要がなくなるから。今後のスマホアプリの要求水準が iOS 13からでいいということだから。

Android の要求水準も6で良いわけですから、Android 5 を切ることができますね。

iOS 13 からで良いのなら、新規アプリ開発だと SwiftUI を使って開発できるので最新技術で開発できるわけです。 嬉しみしかないですね。

それはともあれ開発者様、アプリのリリースお疲れ様でした。 本当にリリース前の諸所の調整とか大変だったと思います。

こんな感じでアプリのレビューを終わりにします。

それでは、バイバイ!

PythonでFireStoreにデータを保存するスクリプトをまとめてみた

PythonでFireStoreにデータを保存するスクリプトをまとめてみた

APIを作成するためにPythonでFireStoreにデータを保存するスクリプトを作りました。
スクリプトがあればサクッとFireStoreにデータを保存できてAPIとして活用できます。

参考ページ

Firebaseの公式ページ

firebase.google.com

firebase.google.com

必要なもの

  • FirebaseのJSONファイル

FirebaseのJSONファイルの取得方法

「プロジェクトを設定」を選択します。

f:id:qed805:20200609192140p:plain:w300

Settingページで「サービスアカウント」を選択します。

f:id:qed805:20200609192259p:plain:w300

「新しい秘密鍵の生成」をクリックします。

f:id:qed805:20200609192354p:plain:w300
新しい秘密鍵の生成

するとJSON ファイルをダウンロードできます。
これをpythonファイルと同じディレクトリに配置させます。

Pythonスクリプト

こちらがPythonスクリプトになります。

index.py

from firebase_admin import firestore
import firebase_admin
from firebase_admin import credentials
from firebase_admin import db

# JSONのパス (XXXXX, YYYYY は任意の文字列)
JSON_PATH = 'XXXXX-YYYYY-firebase-adminsdk-g0x5k-d7b6d8c3ac.json'

# 初期化
cred = credentials.Certificate(JSON_PATH)
firebase_admin.initialize_app(cred)

db = firestore.client()

# データの保存
doc_ref = db.collection(u'users').document(u'user1')
doc_ref.set({
    u'first': u'Alan',
    u'last': u'Turing',
    u'born': 1912
})

doc_ref = db.collection(u'users').document(u'user2')
doc_ref.set({
    u'first': u'Hanako',
    u'last': u'Yamada',
    u'born': 1987
})

doc_ref = db.collection(u'users').document(u'user3')
doc_ref.set({
    u'first': u'Taro',
    u'last': u'Tanaka',
    u'born': 2000
})

これでPythonファイルを叩くとFireStoreにデータが保存されます。

PythonでYoutube Data APIを使ってYoutubeのチャンネル動画一覧を取得する

PythonYoutube Data APIを使ってYoutubeのチャンネル動画一覧を取得する

Youtubeの特定チャンネルの動画一覧が欲しかったのでPythonスクリプトを作ってみました。
自分へのメモ用です。

使うためにはGoogle developer Console から APIキーを取得する必要があります。

必要なもの

  • Google Developer Console のAPIキー (YouTubeが使えるもの)
  • 取得したい動画のチャンネルID

APIキーは次の動画を参考にすると作り方が分かります。


Python YouTube API Tutorial: Getting Started - Creating an API Key and Querying the API

スクリプト

こちらがPython スクリプトになります。

import pandas as pd
import requests
import time
import os

####################
# API_KEY ('xxxyyyzzz'のようにAPIキーを挿入します)
API_KEY = ''

# 検索したいチャンネルのID ('aaabbbcccddd'のようにチャンネルIDを挿入します)
CHANNEL_ID = ''

# 作成するファイル名 (ディレクトリに保存するファイル名)
VIDEO_CSV_NAME = 'videos.csv'
####################

base_url = 'https://www.googleapis.com/youtube/v3'
url = base_url + '/search?key=%s&channelId=%s&part=snippet,id&order=date&maxResults=50'
infos = []

while True:
    time.sleep(30)
    response = requests.get(url % (API_KEY, CHANNEL_ID))
    if response.status_code != 200:
        print('エラーが発生しました')
        break
    result = response.json()
    infos.extend([
        [item['id']['videoId'],
        item['snippet']['title'],
        item['snippet']['description'],
        item['snippet']['publishedAt']]
        for item in result['items'] if item['id']['kind'] == 'youtube#video'
    ])

    if 'nextPageToken' in result.keys():
        if 'pageToken' in url:
            url = url.split('&pageToken')[0]
        url += f'&pageToken={result["nextPageToken"]}'
    else:
        print('正常終了です')
        break

videos = pd.DataFrame(
    infos, columns=[
        'videoId',
        'title',
        'description',
        'publishedAt'
        ])
videos.to_csv(VIDEO_CSV_NAME, index=None)

これでターミナルなどから叩くとcsvファイルで特定チャンネルの動画一覧をcsvファイル形式で取得できます。

videos で取得できるパラメータ群

developers.google.com

パラメータ 内容
snippet.title 動画のタイトル。
snippet.description 動画の説明。
snippet.thumbnails 動画に関連付けられているサムネイル画像のマップ。
snippet.publishedAt 動画のアップロード日時。

動画のサムネイル画像の取得

上記のAPIからでもサムネイルを取得できますが、videoIdがわかっていれば別の方法でも取得できます。

www.it-swarm.dev

この記事を参考にすると

https://img.youtube.com/vi/<insert-youtube-video-id-here>/default.jpg

これで<insert-youtube-video-id-here>にvideoIdを挿入すればサムネイル画像にアクセスできます。

取得できたデータをFirebase などのDBに保存するとYoutube関連のアプリが作れそうですね。