- 投稿日:2020-11-29T23:24:35+09:00
閉じられたネットワーク内のiPadを自動で時刻調整できるように設定する
概要
インターネット接続のないLAN内にいるiPadの時刻が徐々にずれてきたので、時刻設定を自動でできるようにしてみた。
MacやiOSで使用するNTPサーバのFQDNはエンタープライズネットワークで Apple 製品を使う - Apple サポートで確認できるので、LAN内にDNSサーバとNTPサーバを設置し、LAN内に設置したNTPサーバを指すようにDNSレコードを設定する。
設定
閉じられたネットワークとインターネットの両方に接続できるマシンを準備。
今回は下記の設定。
- OS: Ubuntu 20.04.1 LTS
- IP:
- (閉じられたネットワーク側)192.168.20.199/24
- (インターネットに接続できる側)DHCP
unboundのインストールと設定
今回はDNSサーバとしてunboundを仕様(bindだと設定が面倒すぎた)。
sudo apt install unbound -y設定ファイルは下記のように設定。
/etc/unbound/unbound.conf.d/unbound.confserver: verbosity: 1 interface: 192.168.20.199 access-control: 192.168.20.0/24 allow use-syslog: yes # DNSクエリの監視用 log-queries: yes # local-data: "time.apple.com IN A 192.168.20.199" local-data: "time-ios.apple.com IN A 192.168.20.199" local-data: "time-macos.apple.com IN A 192.168.20.199" python: remote-control: forward-zone: name: "." forward-addr: 8.8.8.8 forward-addr: 8.8.4.4
time.apple.com
、time-ios.apple.com
、time-macos.apple.com
のAレコードはNTPサーバのIPアドレスを指定する(iPadならtime-macos
は不要のはずだけど、とりあえず)。
今回は同一マシンにDNSサーバとNTPサーバを立てるのでinterface
と同じアドレスを指定しているが、すでに他のNTPサーバがあるならそちらのIPアドレスを指定する。
use-syslog: yes
とlog-queries: yes
はiPadからのDNSクエリを確認するために設定。
上手くいったあとは削除して良い。設定ファイルの編集が済んだらサービスを再起動。
sudo systemctl restart unboundNTPサーバのインストールと設定
次にNTPサーバをインストールして設定。
sudo apt install ntp -y完全に好みだが、基準とするNTPサーバはUbuntuのデフォルトで用意されているものをすべてコメントアウトしてINTERNET MULTIFEED CO.で用意されているものを利用した。
/etc/ntp.conf#pool 0.ubuntu.pool.ntp.org iburst #pool 1.ubuntu.pool.ntp.org iburst #pool 2.ubuntu.pool.ntp.org iburst #pool 3.ubuntu.pool.ntp.org iburst server ntp1.jst.mfeed.ad.jp iburst server ntp2.jst.mfeed.ad.jp iburst server ntp3.jst.mfeed.ad.jp iburst # Use Ubuntu's ntp server as a fallback. #pool ntp.ubuntu.comこちらも設定後にサービス再起動。
sudo systemctl restart ntpNTPサーバの動作確認のため、
ntpdate
をインストールして確認。sudo apt install ntpdate$ sudo ntpdate -q 192.168.20.199 server 192.168.20.199, stratum 3, offset -0.000027, delay 0.02574 27 Nov 06:08:09 ntpdate[5915]: adjust time server 192.168.20.199 offset -0.000027 seciPadの設定
iPadのWi-Fi設定で、DNSサーバを「手動」で「
192.168.20.199
」(今回の例では)に設定。あとはしばらく待てば
time-ios.apple.com
へのDNSクエリが来て、自動で時刻が調整されているはず。
- 投稿日:2020-11-29T20:16:48+09:00
【iOS】自社プロダクトを守る。不適切レビューへの対処
リリースしたプロダクトには、ユーザーのレビューが付けられます。
プラットフォーム上に公開するiOSアプリで、悪いレビューがついてしまった際には、
新規ダウンロード数減少への影響を最小限にするため、早めに対応したいものです。本記事では、PM、PO、ディレクター向けに、
削除できるレビュー
、削除できないレビュー
の違いを、
実経験に基づき気づいたことをまとめます。※最終的な判断は、Apple側に委ねられるため、明確な基準は不明であると認識しております。
※<2020年11月29日地点>のApple利用規約を踏まえ記載しております。なお、レビューの削除依頼を送る方法に関しては、
@RIwaiさんの、App Storeレビュー返信機能を試して見るをご参照ください。三行で
1.プラットフォームの特性を理解する
2.削除依頼が認められるレビューとは(申請後〇〇日以内に削除される)
3.消せないレビューへの対応方法
1.プラットフォームの特性を理解する
手塩にかけて制作したアプリに低評価が付くと、なんとかして対応(削除)できないものか、と考えます。
しかし、プラットフォームにおけるユーザーレビューは、公平性
が担保されていることが大前提です。
(Amazonや、食べログなどのニュースが話題になりました。公平性が命です。)よって、 削除対象のレビューは
問題がある
ことが前提です。Apple Depeloperの評価、レビュー、返答では以下の箇所が該当します。
ここでは、不快な内容、スパム、またはAppleの利用規約に違反するその他のコンテンツ
と表現されています。
では、例えば次のレビューは問題のある
内容でしょうか。
★☆☆☆☆
タイトル:使えない
本 文 :広告多すぎ。動かないし落ちる。
結果、問題のあるレビューとはみなされません。
(悪意のあるユーザーかもしれませんし、そんなにクラッシュすることはないはず、、、と思っていても)
プラットフォーマーのAppleとしては、アプリに対しての意見はAppleユーザーに対しての有益な情報とみなします。
どんな内容であろうが、個人が感じたことや意見は、尊重されるということです。
2.削除依頼が認められるレビューとは (申請後〇〇日以内に削除される)
前項記載の通り、正当なレビューに認定される範囲は広いです。
では、削除対象となるレビューとはどんなものでしょうか。App Store Connectで、特定のレビューを削除しようとした際には、
以下のカテゴライズがなされています。
※日本語に翻訳されて語義が曖昧に感じられる、場合は正確に把握したいところです。以下の4種にカテゴライズされます。
・スパムの可能性があります
・その他
・趣旨がずれています
・不快感を与える内容が含まれています簡単に内容に触れます。
① 最初の
スパム
に関しては、意味通り無差別かつ大量にばら撒かれるものであると認識できます。
②その他
に関しても文字通り、他3項目に分類されない場合に用いる項目ですね。
③趣旨がずれています
に関しては、
当該アプリへの意見ではないことが基本で、派生して以下のようなことにも適応されます。
・アプリに掲載されているコンテンツへの意見(運営元が提供するものではなく、他ユーザーの著作)
ex)〇〇のアップしている動画、くだらない
・そのアプリのジャンル(カテゴリ)への意見
ex)こういうタイプのアプリってやらせが多いよね、うんざり。あくまで所感ですが、全レビューの中でもこれに分類されるものは多く、レビューで削除対象になる場合が一番多いと感じます。
以下のようなレビューは削除されました。(実際のレビューの意図を汲み、言葉を変更して記載)
★☆☆☆☆
タイトル: 動作に難あり
本 文: オフショアで開発しているんじゃないですか。国内では最近そのような風潮があり残念。
④
不快感を与える内容が含まれています
は、誹謗中傷が該当すると考えられます。
誹謗中傷とは、一般的には他者の権利を侵害している(名誉毀損や侮辱)かどうかがポイントです。
権利侵害 概要 名誉毀損 公然の場で具体的事実を挙げて、第三者の評判を落とす行為 (例:あいつは不倫している、あいつは前科持ちだ) 侮辱 公然の場で具体的事実を挙げないで第三者の評判を落とす行為(例:性格悪い、落ちこぼれ、気持ち悪い) 低評価のレビューは言葉が暴力的になりがちで、公然の場で具体的事実を挙げて、第三者の評判を落とす行為との線引きが非常に難しいのが実情です。
よってApple側も、不快感を与える内容
という表現をされているのだと感じました。
誰に不快感を与えるのかその主語を考ると、他のAppleユーザー
が該当するかと考えられます。結論、客観的な事実(アプリの仕様)に言及していても、言葉から受け取るイメージによっては削除対象になる。
と推察されます。
Apple側からすると、そんな内容のレビューを残していて良いのかとユーザーから思われるからでしょう。このカテゴリで申請をして、削除されたケースもあります。
そして、上記に該当する疑いがあるレビューを報告した場合、
30分〜1時間以内に削除されるケース(当日)が多くありました。また、カテゴリを変えての申請が削除と認められるケースもありましたので、2回までのトライは有用と考えられます。
3.消せないレビューへの対応方法
当然ながら、高い品質で、ユーザーが真に求める良いアプリを作ることが一番大事ですが、
レビュー者への真摯な対応
も効果的です。具体的には、レビューへの返信をすることです。
実例として、アプリの機能に関して「ここは改善した方が良い」といった、
星2つの真っ当なレビュー頂いたことがありました。社内で協議し、その通りに機能改善を行った後、
そのユーザー様に機能改善した旨と、感謝述べる形で返信をしました。翌日、その方のレビューが消えていて、変わりに★5のレビューが1つ増えていました。
これには、社内の開発メンバーのモチベーション向上に大きく繋がりました。
他にも、良いレビューに良い評価をする、などといった小技もありますが、
公平性を担保するプラットフォームの特性を考えても、良質なプロダクト開発が何より大事なことと感じております。まとめ
■Apple側の削除基準が完全にわかるわけでは無いので、低評価レビューに関しては以下を行う。
・真摯に対応し、レビュー者に返信
・グレーなレビュー内容には、問題を報告する
で、リポートを行ってみる。■バージョンごとのレビューを更新(消すこと)もできるが、良質のプロダクト、高いレベルの顧客体験を提供できるよう努力し、
低評価レビューへの対応自体をなくす
ことが一番!
- 投稿日:2020-11-29T12:57:04+09:00
Xcode12でArchiveビルドがとても長くなった時の調査方法
起こったこと
- Xcode11.7 -> Xcode12(12.1や12.2でも同様だった)にアップデートしたら、アーカイブビルドがとても長くなった。
- 具体的には、Xcode11.7で15分程度だったのが、Xcode12.2で3時間程度かかるようになった。
- bitriseだと60分でタイムアウトするし、これだと運用が厳しいので対策するべく原因調査した。
原因、対策
後述する通りいろいろと調べたところ、原因は下記の通りだった。
- Xcode12にバンドルされているSwift5.3のコンパイラの
Optimization Level
がOptimize for Speed
やOptimize for Size
のとき(アーカイブビルドのときに指定されている)のswift コンパイルの挙動が変わっていたため- 上記Optimization Levelのときに、コンパイルが特に遅いSwiftファイルが1ファイルあった。
- 対策としては、このSwiftファイルをコンパイルが速くなるように書き換えた。
この記事のメインテーマは、どうやって上記の原因までたどり着いたかのところで、それを下記します。
もしかしたら、当たり前なことなのかもしれないが、わたしはとても苦戦しました。調べたこと
アーカイブ時のビルド時のログ出力確認
最初、普通にビルドログ見てたが、それだと、Build Phaseの Compile Source(swiftファイルをコンパイルするフェーズ)の直前のshell script実行のところで止まっていて、そのscript自体は単体ではすぐ終わる処理(単体で実行して確認済み)だったので、ログがちゃんと出ていないように思った。
SwiftコンパイラのOptimization Level
デバッグビルドでは問題なかったのと、以前の問題があったので、Archive時のSwiftコンパイラのOptimization Level(
Optimize for Speed
)が問題なのではと思って、デバッグビルドのOptimization LevelをOptimize for Speed
にしたらビルドが遅くなったので、SwiftコンパイラのOptimization Levelが問題であることに気付いた。
※デバッグビルドの方がビルドログが細かく出力されるので、これ以降はデバッグビルドのOptimization LevelをOptimize for Speed
にして調査しています。また、compiler optimization level =
Optimize for Size
にしたらビルド速くなったら嬉しいなーと思ってやってみたけど、変わらなかった。。。Swift Other Flag追加してログ出力確認
結果的に今回の調査では役立ったわけではないが、もうちょっとちゃんとビルドログ出力させたいと思って
Other Swift Flags
に下記を追加。これでビルドログが詳細に出るようになった。
- -Xfrontend -warn-long-expression-type-checking=300
- 型推論に300ms以上かかったらwarning
- -Xfrontend -warn-long-function-bodies=300
- コンパイルに100ms以上かかるメソッドをwarning
この辺りは下記の記事を見ながら色々やってみていた。
https://dev.classmethod.jp/articles/investigated_compiletime_swift/
https://techlife.cookpad.com/entry/2017/12/08/124532ビルドが遅くなっているところを確認
何度やっても下記の赤枠のswiftファイルのコンパイルが遅いので、多分swiftファイルの書き方の問題なんじゃ無いかと思ってきた。
試しに、簡単に直せそうなswiftファイル(10行未満のswiftファイルが含まれた)を全部コメントアウトしても、速くならなかったので、多分この中でも特定のどれかが遅いのだと思ってきた。
※このとき、遅くなっているswift ファイルのコンパイル直後に各frameworkのlinkが走っていたので、実はそこが遅いんじゃ無いかと思った(具体的にはBridging-Header.hに
@import
をいくつか書いてたのでそれが問題なのかもと思った)が、違った。。。コンパイルが遅くなっているswift ファイルがどれかを特定
上記の赤枠のファイルを選択して、コピペすると、下記のようなテキストがペーストされた。
Showing Recent Messages CompileSwift normal arm64 /プロジェクトのパス/〜〜〜〜〜/〜〜〜〜〜〜〜.swift (in target '〜〜〜〜〜' from project '〜〜〜〜〜') cd /プロジェクトのパス /Applications/Xcode12_2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -c -filelist /var/folders/5t/〜〜〜〜〜〜〜〜〜〜〜〜〜〜/T/sources-4f43a5 -primary-file /プロジェクトのパス/〜〜〜〜〜/〜〜〜〜〜〜〜.swift -emit-module-path /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Intermediates.noindex/〜〜〜〜〜.build/Debug-iphoneos/〜〜〜〜〜.build/Objects-normal/arm64/swiftファイル名\~partial.swiftmodule -emit-module-doc-path /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Intermediates.noindex/〜〜〜〜〜.build/Debug-iphoneos/〜〜〜〜〜.build/Objects-normal/arm64/swiftファイル名\~partial.swiftdoc -emit-module-source-info-path /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Intermediates.noindex/〜〜〜〜〜.build/Debug-iphoneos/〜〜〜〜〜.build/Objects-normal/arm64/swiftファイル名\~partial.swiftsourceinfo -serialize-diagnostics-path /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Intermediates.noindex/〜〜〜〜〜.build/Debug-iphoneos/〜〜〜〜〜.build/Objects-normal/arm64/swiftファイル名.dia -emit-dependencies-path /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Intermediates.noindex/〜〜〜〜〜.build/Debug-iphoneos/〜〜〜〜〜.build/Objects-normal/arm64/swiftファイル名.d -emit-reference-dependencies-path /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Intermediates.noindex/〜〜〜〜〜.build/Debug-iphoneos/〜〜〜〜〜.build/Objects-normal/arm64/swiftファイル名.swiftdeps -target arm64-apple-ios11.0 -Xllvm -aarch64-use-tbi -enable-objc-interop -sdk /Applications/Xcode12_2.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.2.sdk -I /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/APIKit -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/Alamofire -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/AlamofireImage -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/AppAuth -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/BoringSSL-GRPC -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/Cartography -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/Differ -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/GoogleDataTransport -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/JWTDecode -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/MBProgressHUD -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/RxCocoa -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/SwiftGifOrigin -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/YoutubePlayer-in-WKWebView -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜 -F /プロジェクトのパス/Pods/AppsFlyerFramework/iOS -F /プロジェクトのパス/Pods/FirebaseAnalytics/Frameworks -F /プロジェクトのパス/Pods/〜〜〜〜〜/Frameworks -F /プロジェクトのパス/Pods/〜〜〜〜〜/Frameworks -F /プロジェクトのパス/Pods/〜〜〜〜〜/Frameworks -F /プロジェクトのパス/Pods/〜〜〜〜〜/〜〜〜〜〜.embeddedframework -F /プロジェクトのパス/Pods/〜〜〜〜〜 -F /プロジェクトのパス/Pods/〜〜〜〜〜/Build/iOS -F /プロジェクトのパス/Pods/〜〜〜〜〜/Build/iOS -F /プロジェクトのパス -F /プロジェクトのパス/〜〜〜〜〜 -F /プロジェクトのパス/ライブラリ/Frameworks-build -enable-testing -g -module-cache-path /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/ModuleCache.noindex -swift-version 5 -enforce-exclusivity\=checked -O -D DEBUG -D COCOAPODS -D COCOAPODS -enable-swift3-objc-inference -warn-swift3-objc-inference-minimal -warn-long-function-bodies\=300 -warn-long-expression-type-checking\=300 -serialize-debugging-options -Xcc -working-directory -Xcc /プロジェクトのパス -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Intermediates.noindex/〜〜〜〜〜.build/Debug-iphoneos/〜〜〜〜〜.build/swift-overrides.hmap -Xcc -iquote -Xcc /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Intermediates.noindex/〜〜〜〜〜.build/Debug-iphoneos/〜〜〜〜〜.build/〜〜〜〜〜-generated-files.hmap -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Intermediates.noindex/〜〜〜〜〜.build/Debug-iphoneos/〜〜〜〜〜.build/〜〜〜〜〜-own-target-headers.hmap -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Intermediates.noindex/〜〜〜〜〜.build/Debug-iphoneos/〜〜〜〜〜.build/〜〜〜〜〜-all-non-framework-target-headers.hmap -Xcc -ivfsoverlay -Xcc /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Intermediates.noindex/〜〜〜〜〜.build/Debug-iphoneos/〜〜〜〜〜.build/all-product-headers.yaml -Xcc -iquote -Xcc /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Intermediates.noindex/〜〜〜〜〜.build/Debug-iphoneos/〜〜〜〜〜.build/〜〜〜〜〜-project-headers.hmap -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/include -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜/〜〜〜〜〜.framework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜/〜〜〜〜〜.framework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜/〜〜〜〜〜.framework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/BoringSSL-GRPC/openssl_grpc.framework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/〜〜〜〜〜/〜〜〜〜〜.framework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/MK2Router/MK2Router.framework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/YoutubePlayer-in-WKWebView/YoutubePlayer_in_WKWebView.framework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/gRPC-Core/grpc.framework/Headers -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Products/Debug-iphoneos/swiftライブラリframework/Headers -Xcc -I/プロジェクトのパス/Pods/Headers/Public -Xcc -I/プロジェクトのパス/Pods/Headers/Public/ライブラリ -Xcc -I/プロジェクトのパス/Pods/Headers/Public/ライブラリ -Xcc -I/プロジェクトのパス/Pods/Firebase/CoreOnly/Sources -Xcc -I/Sources/FBLPromises/include -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Intermediates.noindex/〜〜〜〜〜.build/Debug-iphoneos/〜〜〜〜〜.build/DerivedSources-normal/arm64 -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Intermediates.noindex/〜〜〜〜〜.build/Debug-iphoneos/〜〜〜〜〜.build/DerivedSources/arm64 -Xcc -I/ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Intermediates.noindex/〜〜〜〜〜.build/Debug-iphoneos/〜〜〜〜〜.build/DerivedSources -Xcc -DDEBUG\=1 -Xcc -DCOCOAPODS\=1 -Xcc -DDEBUG\=1 -Xcc -DGPB_USE_PROTOBUF_FRAMEWORK_IMPORTS\=1 -Xcc -DDEBUG\=1 -Xcc -DPB_FIELD_32BIT\=1 -Xcc -DPB_NO_PACKED_STRUCTS\=1 -Xcc -DPB_ENABLE_MALLOC\=1 -target-sdk-version 14.2 -import-objc-header /プロジェクトのパス/〜〜〜〜〜/Bridging-Header.h -pch-output-dir /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Intermediates.noindex/PrecompiledHeaders -pch-disable-validation -module-name 〜〜〜〜〜 -o /ユーザーフォルダのパス/Library/Developer/Xcode/DerivedData/〜〜〜〜〜-ejcjafpdqhgmythgozbispsdrwky/Build/Intermediates.noindex/〜〜〜〜〜.build/Debug-iphoneos/〜〜〜〜〜.build/Objects-normal/arm64/swiftファイル名.o -embed-bitcode-marker CompileSwift normal arm64 〜〜〜〜が選択したswiftファイル分続く。上記の、
cd /プロジェクトのパス /Applications/Xcode12_2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend ~~~~~のところをそのままshell(ターミナル)で実行したら普通に実行できた(1ファイルのswiftコンパイルができる)ので、それで赤枠の各swiftファイルのコンパイルを試したところ、ある1ファイルだけ、すごく時間がかかったのでそれでどのファイルがコンパイルが遅いのかがわかった。
swiftファイル内のどの処理が遅いか特定
やり方は色々ありそうだがそれほど苦労しなかった。
実際にやったやり方は、一旦問題のswiftファイルを全部コメントアウトしてみてから、上記のshell上でのswiftコンパイルを実行し、少しずつコメントアウトを復活させながら、shell上でのswiftコンパイルの実行繰り返して特定した。
その結果、あるenum(かなり大きめでいろいろなViewControllerを参照したAssociated Values を持つenum。このswiftファイルとは別のswiffファイル内で定義)を引数で参照している箇所が遅いことが発覚したので、それのenumを参照しないようにすることで問題解決した。最後に
上記対応後、結果的に多分、2分程度はXcode12にしてからアーカイブが速くなったような気がします。
最初、この問題に遭遇した時は、解決できるのだろうか(できればXcode12がアップデートされたら勝手に解決されないかなとおもった)、、、と思ったが、諦めずに1つ1つの問題の原因に向き合っていけば、解決に近づいていける、、、そう信じたいと思った。解決できてよかった。
- 投稿日:2020-11-29T09:19:22+09:00
guard文まとめてみた
guard文の役割
想定外の状況が起こった時にその処理から抜け出す役割をします。
書き方
guard 条件 else {
条件を満たさなかったときの処理
break //returnでも良い
} 条件を満たした時の処理使ってみた
number2を割る数として割る数に0が入った時、{}内の処理が行われます。
条件式 number2 != 0の時{}外の処理
number2 == 0の時{}内の処理です。guard number2 != 0 else{ answerLabel.text = "割る数には0以外の数字を入れてください" return } kekka = number1 / number2参考文献
詳解Swift 第5版
- 投稿日:2020-11-29T08:50:18+09:00
Flutter入門メモ:開発環境構築編
経緯
久々に新規でモバイルアプリでも作ろうかと思い、
一人で趣味で作るレベルだと、Swift・Kotlinでそれぞれ構築するのは掛けられる工数的に現実感が無いので、
1ソース系を試してみようかと。1ソース系は他にも選択肢がありますが、
React Nativeはなんか好みではないのと、Apache Cordovaは嫌な思い出しかないので、
流行ってるFlutterでやれないかなと、公式を見ながら少し試してみる事にしました。
今回は開発環境までのメモ。確認環境
- macOS Catalina
- Essential Essential Phone PH-1 (Android 10)
前提
- Homebrewがインストールされている。
※今回確認を実施したMacでは、XcodeやIntelliJ、VS Codeが予めインストールされています。
手順
Flutterのインストール。
$ brew install flutter$ flutter --version Flutter 1.22.4 • channel stable • https://github.com/flutter/flutter.git Framework • revision 1aafb3a8b9 (2 weeks ago) • 2020-11-13 09:59:28 -0800 Engine • revision 2c956a31c0 Tools • Dart 2.10.4設定の確認と解消
設定の確認をすると色々と怒られるので、一つ一つ確認。
$ flutter doctor Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel stable, 1.22.4, on Mac OS X 10.15.7 19H15 darwin-x64, locale en-JP) [!] Android toolchain - develop for Android devices (Android SDK version 27.0.3) ✗ Flutter requires Android SDK 29 and the Android BuildTools 28.0.3 To update the Android SDK visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions. ✗ Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses [!] Xcode - develop for iOS and macOS (Xcode 12.1) ✗ CocoaPods not installed. CocoaPods is used to retrieve the iOS and macOS platform side's plugin code that responds to your plugin usage on the Dart side. Without CocoaPods, plugins will not work on iOS or macOS. For more info, see https://flutter.dev/platform-plugins To install: sudo gem install cocoapods [!] Android Studio (not installed) [!] IntelliJ IDEA Ultimate Edition (version 2020.2.4) ✗ Flutter plugin not installed; this adds Flutter specific functionality. ✗ Dart plugin not installed; this adds Dart specific functionality. [!] VS Code (version 1.51.1) ✗ Flutter extension not installed; install from https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter [!] Connected device ! No devices available ! Doctor found issues in 6 categories.Android Studio (not installed)
Android Studioのインストール。
$ brew install android-studio設定の確認をすると下記も必要な様子。
[!] Android Studio (version 4.1) ✗ Flutter plugin not installed; this adds Flutter specific functionality. ✗ Dart plugin not installed; this adds Dart specific functionality.
- Android Studioを起動し、Preferences->Pluginsを選択する。
- FlutterとDartをインストールする。
IntelliJ IDEA Ultimate Edition (version 2020.2.4)
- IntelliJを起動し、Preferences->Pluginsを選択する。
- FlutterとDartをインストールする。
VS Code (version 1.51.1)
extensionからFlutterをインストールする。
Android toolchain - develop for Android devices (Android SDK version 27.0.3)
Android SDK 29及びAndroid BuildTools 28.0.3以降のインストール。
- Android Studioを起動し、Configure->SDK Managerを選択する。
- Android SDKからAndroid 10.0を選択し、Apply。
- SDK ToolsからAndroid SDK build-Toolsを選択し、Apply。
ライセンスの許可を実行し、問題なければ全てyで進める。
$ flutter doctor --android-licensesXcode - develop for iOS and macOS (Xcode 12.1)
$ gem update --system $ sudo gem install cocoapodsConnected device
- About phoneからBuild numberを連打して開発者向けオプションを開放し、
System->Advanced->Developer optionsを選択、
Developer optionsとUSB debuggingをオンにする。- 端末をつなげる。
設定の再確認
Android Studioのpluginに関してはエラーが出たままだが、
下記によると、使用上は問題なさそう。
https://github.com/flutter/flutter/issues/67986#issuecomment-715452201$ flutter doctor Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel stable, 1.22.4, on Mac OS X 10.15.7 19H15 darwin-x64, locale en-JP) [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2) [✓] Xcode - develop for iOS and macOS (Xcode 12.1) [!] Android Studio (version 4.1) ✗ Flutter plugin not installed; this adds Flutter specific functionality. ✗ Dart plugin not installed; this adds Dart specific functionality. [✓] IntelliJ IDEA Ultimate Edition (version 2020.2.4) [✓] VS Code (version 1.51.1) [✓] Connected device (1 available) ! Doctor found issues in 1 category.感想
doctorの指示に従って対応すれば良いのでだいぶ楽になりましたね。
はるか昔、Android1.6や2.1くらいの時は結構大変だった記憶があったような…。
また、環境構築時にAndroid Studio 3.1の残骸を見て、
Androidアプリの作成は何年も触ってもいないんだなという時間の流れを感じました。参考
- 投稿日:2020-11-29T08:09:17+09:00
swich文について初歩的なことをかく
swich文の書き方
let number1 = Double(number1TextField.text!) ?? 0 let number2 = Double(number2TextField.text!) ?? 0 var kekka :Double = 0 switch calculateSegmentedControl.selectedSegmentIndex{ case 0: kekka = number1 + number2 case 1: kekka = number1 - number2 case 2: kekka = number1 * number2 case 3: guard number2 != 0 else{ answerLabel.text = "割る数には0以外の数字を入れてください" return } kekka = number1 / number2 default: print("該当なし") }メモ程度なので自分が使用したコードをそのまま載せます。
swich 式 {
case ラベル1:
文...
case ラベル2:
文...
default:
文...
}
こんな感じで書く。
式にはcaseで条件分けしたい式を書きます。この場合だとsegmentedControlのIndexを式に入れることで、ラベルに0番目、1番目と指定してそれぞれの処理を書いていきます。
- 投稿日:2020-11-29T00:20:22+09:00
Xcodeを使わずUIKitのレイアウトをjsonで書いて複数の実機で同時にHotReloadするライブラリを作った
概要
タイトルの通りです。
SwiftUIが話題になってきている令和の時代にUIKitに焦点を当てたライブラリを作ってみました。
名前はUIKitHotReloadです。
Githubはこちら。概要
- レイアウトをjsonで記述します
- 複数の実機で同時にHotReloadさせることができます
- 既存のUIKitのレイアウトと組み合わせ可能です
- Firestoreのsnapshotの機能を使います
- Releaseビルド時はbundleされたjsonファイルを利用するのでHotReloadしません
- xibやstoryboardを置き換えるものなのでViewControllerは必要です
- ボタンタップ時のアクションなどもswiftで記載する必要があります
動き
こんな感じで複数のシミュレータで同時にHotReloadできます。
もちろん複数の実機でも同様にHotReloadします。
レイアウトの組み方
以下のような画面の中央に赤丸のviewを表示させるシンプルな画面の例を記します。
ViewController.swift
ViewController
から読み込みたいViewのjson
を指定します。ViewController.swiftimport UIKit import UIKitHotReload final class ViewsViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // views/sample.jsonを読み込む場合 self.view.loadHotReload(dirName: "views", jsonFileName: "sample") { result in switch result { case .failure(let error): //読み込み失敗 print(error.localizedDescription) default: //読み込み成功 break } } } }views/sample.json
基本的にUIKitのクラス名やパラメータ名と連動したkeyでjsonを記述します。
views/sample.json{ "class": "view", "background_color": [ 1, 1, 1 ], "subviews": [ { "class": "view", "background_color": [ 1, 0, 0 ], "circle": { "rad": 50 }, "layout": { "center": { "x": { "v": 0 }, "y": { "v": 0 } }, "size": { "width": { "v": 100 }, "height": { "v": 100 } } } } ] }HotReloadする仕組み
UIKitHotReloadはjsonからUIKitのViewを構築していくトランスパイラとして機能しています。
VSCodeのRun On Script
のアドオンなどでjsonを保存したらfirestoreにアップロードさせます。
firestoreのリアルタイムにローカル(スマホアプリ)とサーバーのデータを同期する機能により、即時にアプリ内の画面がリロードさせjsonからUIKitのレイアウトを再構築します。
リリースビルドの場合はbundleされたjsonを読み込むためfirestoreと連携はしません。SwiftUIと比べて
メリット
・iOS13以前でも動く
・既存のUIKitのソースコードと親和性が高い
・一度インストールしたらXcodeすら立ち上げる必要がないので中古のmacbook airでもレイアウトが組める
・複数の実機で同時にHotReloadでレイアウトを確認できるので、一度チームメンバーに配布したら、再配信することなく全員の意見を即時反映させることができるデメリット
・firestoreの機能が前提
・VSCodeのRun On Script
(保存したらスクリプト実行)が前提
・初期設定に手間がかかる
・オンライン環境でないとHotReloadは機能しない
・jsonで補完が効かない
・サポートしているviewの種類が少ないサポートしているView
UIView
UIButton
UILabel
UIImageView
UITextField
UIScrollView
UIStackView
UITableView
UITableViewCellその他の例
UIView
UIViewのパラメータを使った実装例です
ViewsViewController.swift
views.jsonUIButton
UIButtonを使った実装例です
jsonからswiftの連携をしたボタンタップ時の処理も記述していますButtonsViewController.swift
buttons.jsonTwitter風
UITableViewの例としてTwitter風のセルを表示させています。
TwitterTimelineViewController.swift
twitter_timeline.json
twitter_timeline_cell.json今後
初期設定をシンプルにする
サポートするviewの追加
複数人が同時編集できるようにする
テストコードを入れる終わり
CocoaPodsの登録も初めてでしたが意外と簡単にできるんだなと思いました。
オープンソースのライブラリの作法なんかもよく分かってもらず、ご意見などいただけると嬉しいです。