日々の雑感、開発備忘録
daisyUI
daisyUIはTailwind CSSベースのCSSライブラリです。
jsを使っていない、上に導入が楽
管理画面などでは積極的に使っていきたい
react-google-mapsを使っている時に注意したいこと
・APIKeyを読み込むときにGoogleMapコンポーネントが存在しない場合にエラーが発生する
・GoogleMapコンポーネントを読み込むときにAPI Keyがロードされていないとエラーが発生する
setStateが無限発火する場合は、setStateをするタイミングで以下のことを検討する
・if文で条件を厳しくする
・debounceなどを使い、発火回数とタイミングを調節する
・なるべくコンポーネントを細かくわけ依存関係を簡潔にする、パフォーマンスを意識する
Nextjsとそのライブラリを使って良かったこと、辛かったこと
良かったこと
バグがなく、フレームワークとしての完成度が高い- Storybookを使うことで、コンポーネントの再利用性を意識した開発が強制的にできた
- daisyUIを使うことで、classNameの記載量が削減できた(className="btn")
辛かったこと
- Reactあるあるですが、イベントの中でSetStateを呼び、それが再度イベントを呼び、SetStateを呼び、無限レンダリング地獄になる。解決するのに1日かかった。多分一度はみんななると思います
- nextjsの過去のバージョンと最新のバージョンの情報混在しており、正しい情報を見つけるのに若干時間がかかる
Storybook - UIカタログ
カタログ化することで、チーム内で共通のコンポーネントを再利用しやすくなります。
また、より疎結合なコンポーネントを作成できるので、開発に関してもポジティブになります
NextJsを使ったインフラ構成例
GCPメインの環境であったため、CloudRunとした
Cloud RunからSQLに接続する際の注意点
- 構成する際にconnectionを設定しておく
- unixで接続するか、ipで接続するかによって違う
- パスワードに記号が入っている場合はURLエスケープする必要がある
Webブラウザでできること
Graphical Display
3D and 2D graphics, Virtual Reality (VR), Augmented Reality (AR)
Video and Audio Playback, Storage, and Processing
Video & picture capture, streaming playback, media stream storage, floating. Picture in Picture, audio processing, MIDI device connection, speech synthesis, speech recognition, picture conferencing, subtitle & caption display
Utilization of Devices and Sensors
Bluetooth connection, game controller connection, location information acquisition, external display connection, proximity sensor use, distance sensor, lock prevention, sensor directive access, vibration control, power management
User Interface Control
Mouse cursor control (locking on specific elements, hiding from view, etc.), multi-touch & gesture support, use of the operating system's share functions, connection of unique interface devices (Human Interface Devices, HID)
アプリエンジニアがIOTを最初から学ぶのはハードルが高い
そこでIOT Androidデバイスというものを利用すると、アプリ開発の知識を利用しながらIOTに関与できる
IOT Androidデバイスと一般のAndroidデバイスの一番の違いは、
・署名鍵
・ディスプレイの有無
の気がしている
特に署名鍵は、ある場合はIMEIやインストールされているアプリから再起動、別のアプリインストールなど自由に操作できる強力なもの
"@react-google-maps/api"内のDrawingManagerを使うと GoogleMap内で自由に図形を描画できる
ただし初期値としてあらかじめ円やポリゴンを書いておくことはできない
それをするためにはPolygonやCircleコンポーネントを利用することになる
つまり、Reactで使うときの状態管理はより複雑になる
Nextの状態管理ライブラリを選定する場合は、他に人の意見を聞いた方が良い
reduxが大嫌いという人もいる
recoilとZustandを使ってみたが、どちらも軽量で、非常に使いやすい
両方の移行も簡単
React18の、StrictModeの追加機能によ理、typescriptのstrictモードをONにした場合、useEffectが2回呼ばれるので注意する
一人で開発している場合、改善点はたくさんあるので、際限なくプロダクトに時間を取られてしまう
ある程度のところでPMに渡してしまうと意外と要件を通っているかもしれない
DBとつなぐ管理画面を作る際はAppSheetを使うとセキュリティに配慮しつつ、カスタマイズ性がわりかし高いシートを作成できる
ログインもGoogleログインとなるので非常に安心
10人までなら無料
Cloudflare Workersを個人開発で使ってみた
非常に開発しやすくAPIが作成できた
登録にクレジットカードの登録が必要ないのも非常にポジティブ
個人サイトであればCloudflare系を利用で十分足りる気がしている
githubと連携することでCICDも手軽に準備できるので、そちらのアカウントも用意すべき
GoogleMapで図形描画する際にハマりやすいのはもちろん状態管理
一時的なstateとグローバルなrecoilを使い分けながら作成していく
とはいえ、リッチな機能にすればするほどバグや、パフォーマンスの問題が出る
特にgoogleMap...
GoogleMapでサークルを追加する機能を作成中
クリックで固定された半径の円を追加していた
その後、機能修正でもっとリッチに、マウスのドラッグ&ドロップで半径を柔軟に変えてサークルを作りたいとのこと
ドラッグ&ドロップの場合、イベントを正確に伝搬するのが難しく、誤作動になりやすいと感じている
ドロップする時に反応せずにサークルが作られなかったり、離していないのに勝手に作られたり
Reactのイベントが発火しているのか?
再描画は走っていない
GoogleMapの、
- onMouseDown(円state上に作成)
- onMouseMove(円サイズ変更)
- onMouseUp(円をDBに追加)
これらのイベントを利用していたが、
・debounceのせいで遅延して、原因になっていたかも知れない
・描画時にstateを設定し、その状態をチェックすることでイベント伝搬を適切に管理するよう試みる
なぜnullになるのか
import { random } from 'lodash';
const newId = random(100000, 1000000000000000000);
addNewID(newId); // これはReacoilの追加するイベント
これでnewIdがnullになる場合がある
...なぜ?
ただただインスタンス再作成の際に、nullを入れていただけだった
typescriptを使っていたので静的型付けですぐ修正箇所がわかった
やはり静的型付けは良い
PJを複数抱えると忘れてしまう問題
久しぶりなPJのプルリクレビューは思い出す作業が長い
dockerの立ち上げにも戸惑いながらな部分がある
これの手順書も作っておいた方が良いのか
GCP CSR とBitbucket Cloudを繋げるにはAdmin権限と、PJの
source.repos.create、source.repos.updateRepoConfig
が必要となる見込み
const nextConfig = {
// ...
experimental: {
scrollRestoration: true,
},
}
を有効化することで、スクロール位置を保存できる
しなくても有効化になっているブラウザもある。まちまち
PostmanはCloud buildなどのCIにも接続できる
まずはローカルで使ってみる
Flutterがvscodeのextensionで使えるようになっててびっくり
競合だからやらないと思っていた
新しく生成したFlutter Projectのiosにpod fileがない
runすれば出力されるらしいが、一応simulatorではrunはしているのでちょっと謎
flutter run -d device_idでrunできる
やはりそれでもpodfileは生成されない
結局手動でpod initした
自動生成されたような気がしていたが、気のせいだったか
最後に触ったの2年前だから。。。
次のエラー
No such module 'Flutter'
flutter packages getをした後、エラーがある状態のままxcode runをしたところ、動かせた
エラーも消えた
が、新しいエラーは出ている状態
auto fixで解決した
GeneratedPluginRegistrant.register(withRegistry: self)
フレームワークが青く表示されているのは、プロジェクト。Xcodeでは、プロジェクトは慣例的に青色で表示されることが多い。つまり、表示されているアイテムが独立したビルド対象
一方、オレンジ色はコードではないファイル、例えばアセット、ストーリーボード、plistファイルなどの設定ファイルに使われます。オレンジ色は通常、プロジェクトに含まれるが直接コンパイルされないファイルを示す
自作フレームワークがsimulator用のビルドで動くが、real deviceで動かない
フレームワークインポート時に、アーキテクチャを考慮したら動いた
下はsimulator用
上は実機用
こちらの許可ダイアログが表示されない
if #available(iOS 14, *) {
ATTrackingManager.requestTrackingAuthorization { status in
switch status {
case .authorized:
// Tracking authorization dialog was shown and we are authorized
print("Authorized")
// Now that we are authorized we can get the IDFA
print(ASIdentifierManager.shared().advertisingIdentifier)
case .denied:
// Tracking authorization dialog was shown and permission is denied
print("Denied")
case .notDetermined:
// Tracking authorization dialog has not been shown
print("Not Determined")
case .restricted:
print("Restricted")
@unknown default:
print("Unknown")
}
}
} else {
// Fallback on earlier versions
}
アプリ起動直後はダメらしい
これは動く
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
if #available(iOS 14, *) {
ATTrackingManager.requestTrackingAuthorization { status in
switch status {
case .authorized:
// Tracking authorization dialog was shown and we are authorized
print("Authorized")
// Now that we are authorized we can get the IDFA
print(ASIdentifierManager.shared().advertisingIdentifier)
case .denied:
// Tracking authorization dialog was shown and permission is denied
print("Denied")
case .notDetermined:
// Tracking authorization dialog has not been shown
print("Not Determined")
case .restricted:
// Tracking authorization is restricted
print("Restricted")
@unknown default:
// Future cases not known by the current version of the code
print("Unknown")
}
}
} else {
// Fallback on earlier versions
print("iOS 14 not available")
}
}
androidソフトウェアビーコンのdevice uuidがiosのスキャナーで表示されない
サービスUUIDは表示される
OS間の際?
Xcode's debug navigatorを使うことで、バッテリー消費量などをゲージで計測できる
automatic signingを有効にしているとbundle identifierを変更できない罠
push通知のcapabilityをつけ忘れる
FlutterにSDK組み込んだサンプルアプリを作った記録-iOS
- Flutterのインストール(vscode)
- Flutterの新規PJ作成
- Bundle identifierの変更
- auto signingの設定
- iOS div 直下pod init
- pod install
- firebase core, messagingの記載, pod install
- フレームワークdivにSDKのフレームワーク追加
- プッシュ通知送信のための、Googleserviceinfo.jsonをルートに追加
- AppDelegate内でfirebase initialize、各種delegateを設定
- SDKの読み込み、各種delegateを設定
- SDKのinitializeを実装
- 特にFCMトークンの払いだしを実装
- 特に利用規約画面の呼び出しを実装
- edit schemaで、ビルドをreleaseに設定
- Push通知受信テスト
- 管理画面でテスト結果確認
FlutterにSDK組み込んだサンプルアプリを作った記録-Android
- Flutterのインストール(vscode)
- Flutterの新規PJ作成
- app直下にlibsフォルダを作成、SDKを設置
-
- pj直下のbuild.gradleのapplicationIdを既存のものに変更
- app直下のbuild.gradleにてAndroid API Levelを設定、SDKの依存関係を記載
- プッシュ通知送信のための、google-services.jsonをルートに追加
- FIrebaseのライブラリの依存関係を記載
- FIrebaseのライブラリinitialize
- 特にFCMトークンの払いだしを実装
- SDKの読み込み、各種delegateを設定
- SDKのinitializeを実装
- 通知チャンネルを作成, SDKに結果をコールバックする
Android studio
- kotlinをinstall
- vim
- gradle sync
androidの通知チャンネル。。。?
Android 8.0 以上で通知を配信するにはアプリの通知チャネルをシステムに登録しておく必要がある
Androidはbuild.gradleが2つあるのがきつい
In a typical Android (and Flutter) project setup, there are two build.gradle files:
Top-Level build.gradle (Project-level): This file is located in the root project directory. It defines build configurations that apply to all modules in the project. It includes configurations like the Gradle version, repositories for dependencies, and classpath dependencies for the Android Gradle plugin.
Module-Level build.gradle (App/module-level): This file is located in the module folder, such as the app module. It defines configurations specific to that module/app, like plugin application (apply plugin), Android-specific configurations (compileSdkVersion, targetSdkVersion, etc.), dependencies for the module, and more.
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
// libsディレクトリのaarファイルを読み込む
implementation(name: 'my-framework', ext: 'aar')
これapp直下のbuild.gradle入れないとライブラリ読み込めない(でしょうね)
初心者殺し
If you need access to FINE location, you must request both ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
android:theme="@style/Theme.AppCompat"
or
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
をつけない場合、methodChannelでクラッシュした
The error message indicates that there's a theme-related issue with an activity in your Android application. Specifically, TermsActivity is trying to use AppCompat features, but the current theme applied to this activity doesn't inherit from
Android Themeでfeatureを指定するのか...
Android studioでiOS同様リリースビルドするには、build variantをreleaseに変更する
あとはプルダウンからrunを選択する
AndroidでリモートPUSHを受け取るには
Implement
- createNotificationChannel("サンプルアプリ");
- setNotificationSmallIconResId(R.drawable.ic_notification)
Manifest
-
FirebaseMessagingService with override methods
-
Google-service-info.json
-
build.gradle -> 読み込み
clear blade iot codeでproject後に、registryを作ろうとしたら、billingアカウントが設定エラーになった
結局インフラ担当に相談してなんとかしてもらう
\
onCreateとonNewIntentは別で実装する必要がある
seleniumよりもPlaywrightが良いらしい
- GoogleMap上での円をプロットするWebアプリ
- NextJsでのフロントエンド構築
- 短納期の案件
Androidのバッテリー最適化で挙動がまた変わりそう
アプリのバッテリーへの負荷を調べるときに、実際に放置するパターンと、ツールを使って瞬間的な負荷を測るパターンがあるが、日本だと前者が強そう
BLEとビーコンがごっちゃになっていた
BLE -> CoreBluetooth
Beacon -> CoreLocation
ここら辺の違いを調査していこう
Core Bluetooth vs. Core Location
The main difference between using Core Bluetooth and Core Location in the context of BLE (Bluetooth Low Energy) devices and beacons (like iBeacons) lies in the kind of data and interaction they are designed for.
Core Bluetooth
Purpose: Designed for any form of Bluetooth Low Energy (BLE) communication that doesn't involve beacon region monitoring and ranging. It's used for discovering, connecting to, and exchanging data with BLE devices.
Capabilities: Allows for scanning for devices, connecting/disconnecting, service discovery, reading/writing characteristics, and subscribing to notifications from BLE devices.
Use Cases: Suitable for applications where two-way communication with a BLE device is required, such as interacting with smart home devices, fitness trackers, or medical devices.
Access Level: Provides lower-level access to BLE devices, offering extensive customization capabilities for Bluetooth interactions.
Core Location
Purpose: Used for geolocation features within iOS, including region monitoring and ranging of beacons. Designed specifically for use with beacon protocols like iBeacon.
Capabilities: Supports monitoring and ranging of beacon regions, notifying apps about entry/exit of regions and providing proximity information of beacons.
Use Cases: Ideal for location-based services within an app, like sending notifications when entering a store or providing indoor navigation.
Access Level: Abstracts away the Bluetooth communication details, focusing on geographic location and proximity to beacons.
Key Differences in Context:
BLE vs. Beacon: BLE communication (via Core Bluetooth) involves two-way data exchange with BLE devices, while beacon interaction (via Core Location) focuses on detecting presence and estimating proximity without data exchange.
API and Framework: Core Bluetooth provides APIs for BLE device management, whereas Core Location offers APIs for geolocation and proximity sensing.
Privacy and Permissions: Both frameworks require user permissions, but for different reasons. Core Bluetooth needs permission to use Bluetooth, and Core Location requires permission for location services due to privacy implications.
Regionで利用できるのは、デバイス全体で20個となる
これを超えると利用できないので、発火できない場合も検討した方が良い
電波が混雑しているとビーコンを検知できない場合がある
その場合はビーコンのパワーを上げる
常に、foreground, backgroundで動作が違うということを理解すること
この上で、
- enter
- exit
- ranging
の状態を考慮する
locationManager
- startRangingBeacons
- startMonitoring
CLBeaconRegion
- beaconRegion.notifyEntryStateOnDisplay
- beaconRegion.notifyOnEntry
Delegate
- didEnterRegion
- didDetermineState
- didStartMonitoringFor
- didExitRegion
- didRangeBeacons
Status
- background mode
- foreground mode
iBeacon
- UUID
- Major
- Minor
startRangingBeaconsをbackgroudで動かすのは微妙
enter/exitをcallしてバックグラウンドから復帰させるのが良い
The difference between locationManager.requestWhenInUseAuthorization() and locationManager.requestAlwaysAuthorization() in iOS pertains to the level of access your app has to the user's location data and how it operates in the background.
requestWhenInUseAuthorization(): This method requests permission to use the device's location services while the app is in use, meaning it can access location data only when the app is running in the foreground. If your app needs to track the user's location only when it's actively being used (e.g., for displaying location-specific information or services), this is the appropriate level of access. Users will see a location usage indicator in the status bar when the app is using their location in the foreground.
requestAlwaysAuthorization(): This method requests permission for your app to access the user's location at all times, including when the app is in the background or not running. This level of access is necessary for features that require location updates regardless of whether the app is currently being used, such as geofencing or continuous location tracking for fitness apps. It's important to note that using this permission requires a clear justification and user understanding, as it has more significant privacy implications.
Both methods require you to include specific keys (NSLocationWhenInUseUsageDescription and NSLocationAlwaysAndWhenInUseUsageDescription, respectively) in your app's Info.plist file with descriptions explaining why your app needs these permissions. These descriptions are shown to the user in the permission dialog.
Handling location permissions also involves checking the current authorization status via CLLocationManager.authorizationStatus() and responding to changes in authorization status by implementing the CLLocationManagerDelegate methods.
It's crucial to choose the appropriate level of location access for your app's functionality, balancing the need for location data with respecting user privacy and battery life. Always use the least invasive level of access necessary for your app's functionality.
For more detailed guidance and examples, refer to documentation and resources such as the Notificare guide on iOS location permissions and Apple's developer documentation.
The key differences between foreground and background execution in iOS revolve around the app's ability to execute code and the system's management of resources to balance performance, battery life, and user experience.
In the foreground, an app is actively running and visible to the user. It has priority access to system resources and can execute code in real-time. This mode is suitable for interactive tasks, real-time data processing, and ensuring the app responds promptly to user inputs.
In contrast, background execution allows an app to perform tasks even when it's not the active app on the screen. However, iOS imposes strict limitations on background tasks to preserve battery life and system performance. Background tasks are generally limited to specific use cases, like playing audio, location updates, performing finite-length tasks, fetching content in the background, and handling push notifications. The system heavily regulates these tasks, often pausing or terminating them if they use too much power or take too long to complete.
iOS uses a variety of measures to manage apps in the background, including system budgets for energy and data, and rate-limiting to space out app launches. Developers have tools like Background App Refresh, which allows apps to wake up periodically to update content in the background, but the timing and frequency are managed by the system to balance efficiency and freshness.
Moreover, the system prioritizes apps based on various factors, including user habits and explicit user actions like removing apps from the App Switcher. Settings for background modes and system features like Low Power Mode can also influence how and when an app runs in the background.
For more detailed insights into managing your app's lifecycle and configuring background execution modes, you can refer to Apple's official documentation on background execution sequence and configuring background execution modes. Additionally, the WWDC20 video on background execution demystifies how iOS manages apps running in the background, providing valuable tips for developers to ensure their apps perform optimally while being mindful of system resources.
didEnterRegion will call by OS, even app is killed?
Yes, iOS does allow for didEnterRegion and didExitRegion methods to be called even when an app is not running or has been killed. This functionality is part of the Region Monitoring feature provided by Core Location, which is designed to launch apps into the background (or start them if they're not running) when a region boundary is crossed. This enables apps to react to region changes by scheduling local notifications or performing other tasks for a brief period.
When an app that uses Region Monitoring is terminated by the user or the system, iOS continues to monitor the regions that were registered by the app. If a region boundary is crossed, iOS automatically relaunches the app into the background and calls the relevant delegate methods (didEnterRegion or didExitRegion) with the region that was triggered. It's important for the app to reinitialize its location manager and set its delegate in the application:didFinishLaunchingWithOptions: method if it was launched because of a location event, which can be checked using the UIApplicationLaunchOptionsLocationKey in the launch options dictionary.
The Estimote Community Portal also highlights that after an exit/enter event, the app is woken up and remains active for 10 seconds, allowing it to handle the region event even if the app was previously killed.
Moreover, discussions on GitHub confirm that monitoring for beacons works in background and when the app is killed/closed, with the app being woken up for a few seconds to handle enter/exit region events, ensuring consistent behavior across different app states.
For more detailed guidance, you can refer to the Apple Developer Documentation on locationManager(_:didEnterRegion:) and community discussions like those found on the Estimote Community Portal and GitHub issues related to beacon monitoring with the app closed.
what will be happen if i register over 20 regions in iOS app?
firestoreへの接続方で、AIのハルシネーションのせいでdefaultに繋ごうとして、別のに繋げなくて困ってた
ググったら普通に繋げた
geminiもchatgptも同様だったから、なんか間違ったデータがあるのか
firestoreからbigqueryへの手動エクスポートは簡単
exntesionも使えば自動もできそう、ただ、functionとか関連するものが全て作られるので掃除するのが手間
firestoreからbigqueryへの拡張機能を使ったエクスポートにdefaultしか対応されていないので、実質gcp プロジェクトで1つしかエクスポートできない、不便...
あと拡張機能のインストールは簡単だが、消すのが大変
細かいnextjsのtips
- ArtifactRegistryへのビルドスクリプトを作る
- Firestoreは便利
- .envファイルを作る
- middlewareでbasic auth
searchBoxを使うのは、googleMap apiを使えば簡単だった
新しいandroid studioでエラーが発生
やったこと
ライブラリのインポートでエラーが発生するので、下記を追加
implementation("androidx.work:work-runtime-ktx:2.7.3")
distributionUrl=https://services.gradle.org/distributions/gradle-7.5-all.zip
に変更
要は使っているgradleが6系だけどmacのjavaが高いから問題になっているkigasu
android studioのjava versionを変更
ビルドいけました、結局android studioのjavaのバージョンを11に指定して、他そのままでした
以前まではjava 17系でもなんとなく動いたんですが...
targetSDKとminimumSDKと、compileSDKのそれぞれの意味を調べる
DrawingManagerの描画アイコンがクリックできず、悩んでいた
どう無限re-renderが裏であり、それがgoogleMapを描画しまくっていたようだった
それを修正したところ、再度アイコンが効くようになった
ジオフェンスは、2004年に米国のミズーリ大学で開発された、実際の地理的領域に仮想境界を作る技術及び考え方です。ジオフェンスという名前は、geo(地球や大地という意味の接頭語)とfence(柵)を組み合わせた造語です。実際のジオフェンスは特定エリアに仮想的な柵を作る仕組みで、ジオフェンスを使ったさまざまな施策をジオフェンシングと表記することもあります。
ジオフェンスはGPSやWi-Fiなどの位置情報データを使用し、対象がそのエリア内に入った、もしくは出たことを検知し、特定のアクションを起こします。この技術を使えば、顧客行動の調査をすることが可能になります。
事例
・顧客へのキャンペーン通知
・観光地での情報提供
・店舗内でのジオフェンス活用事例
・トラックの出入りや物流を管理
"IDで指定したビーコンの電波をiOS端末が検知できる範囲を「リージョン」と定義し、ユーザによるリージョンへの出入りやある時点でユーザがリージョン内外のどちらにいるのかを通知する。
リージョンの内か外かでしか判定ができないため、ユーザとビーコンとの距離の変化をモニタリングできない。"
iBeacon
"Apple社が発表したBLE(Bluetooth Low Energy)を用いたビーコンの規格です。
GPS(Global Positioning System)が屋内や地下などGPS衛星からの電波が届かない場所では測位が難しいのに対して、iBeaconは、屋内や地下でも問題なく利用でき、数cm~数十cmレベルで位置を特定できるために、通路や店舗のような狭い範囲で情報をピンポイントに発信できる利点があります。
また、通常のBluetoothではすぐに電力を使い果たしてしまうのに対して、BLEは極力電力を使わない規格で、屋外や電源から遠い場所での利用に適しています"
"同じワイルドカードビーコンUUIDを監視している際に、実はエリアが変わっても、iOSが違うビーコンを同一と検知し、リージョン監視イベントが発火しないこと
同じUUIDと同じUUID/Major/Minorを設定しても同様で、OSが違うビーコンを同一と検知し、リージョン監視イベントが発火しないこと
特に施設内で多くのビーコンがある場合に発生しやすい"
MAX20
それ以上をstartMonitoringForRegionで行おうとすると、didDetermineStateが21個以降、発火されなくなる
エラーは出ないみたい
// バックグラウンドでのロケーション更新を許可しておく(①)
myLocationManager.allowsBackgroundLocationUpdates = true
// ロケーション更新の自動中断をオフにしておく(②)
myLocationManager.pausesLocationUpdatesAutomatically = false
することと、alwaysで許可をもらうことでbackgroundでも動く様子
"iBeaconの情報取得方法①
リージョンの内か外かでしか判定ができないため、ユーザとビーコンとの距離の変化をモニタリングできない。
リージョン監視はアプリがフォアグラウンドでない場合も継続的に動作する"
"iBeaconの情報取得方法②
意味
・発信側のBeacon端末と受信側のスマートフォンとの距離を測ること。
・ユーザーが中に入った場合には、スマートフォンとの距離を検出しています。
挙動
・IDで指定したビーコンの電波強度等の情報を1秒ごとに取得する。
・レンジングを活用することで、ユーザとビーコンとのおよその距離に応じて処理を変えるなど、柔軟なアプリ設計が可能になる。
・複数のビーコンを設置し、継続的に電波強度をモニタリングできれば、屋内移動ログの取得といったユースケースに応用できる。"
"Appleのポリシーに適合する実装であるか
Appleがバックグラウンドでのビーコンレンジングをどの程度許容する姿勢であるかは不明。直近でもiOS13でアプリのバックグラウンド実行が強制終了される事象が報告され、その後のアップデートで修正されていた(iOS13.2.2公開、データ通信不具合、バックグラウンドアプリ強制終了など修正)。今後のOSアップデートで仕様が変わる可能性がある。
WWDC19での発表を参照すると、iOSでのバックグラウンド処理は必要性の高い特定のユースケースに限定して用いられるべきというAppleの意図が読み取れる。また、バックグラウンド処理の実装に当たってはパフォーマンス・バッテリー消費・プライバシーの3点に留意すべきことも強調されている。バックグラウンドでのレンジングがこうしたAppleの意図にどこまで適合的かは不明確であるため、ストア申請時は注意が必要である。
App Store Reviewガイドラインでは下記の記述がみられる。"
"AirTagを用いてAppleの「さがす」アプリを調査した結果、アプリが主にジオフェンシングと呼ばれる地図上の円からの出入りを監視する手法を用いてユーザーの位置情報を低い消費電力でトラッキングしていることがわかりました。
具体的には以下のように、位置情報を取得した際に地図上にジオフェンスを貼り、その領域を出た際にその位置を中心に新たなジオフェンスを貼り...ということを繰り返すことで細かい移動の追跡に電力を費やさずに大まかな軌跡を把握し、紛失中のiPhoneとのすれ違い時やAirTagから離れた際にのみBluetoothでアプリを起動し位置情報を取得することで低消費電力とサービスを両立させているようです。"
"1. notDetermined
2. restricted
3. denied
4. authorizedAlways
5. authorizedWhenInUse"
ジオフェンス、ビーコン、アプリ
ここら辺の図を整備する必要がある
github copilot enterprise のファインチューニングが優秀そう
github copilot enterpriseはまだ不透明なところが多い
焦らず他の選択肢も考えつつ、待つ
firestoreにGoogleMap SDKのjavascriptのオブジェクトをそのまま投げるとエラーになる
BIgqueryのDataSetはリージョンを跨ぐと連携ができない(コピーなども面倒になる)
のでリージョンは非常に重要
XCUITestでジオフェンスの発火テストできるかも
XCUITestがかけるコストに対してリターンがあるか微妙
iOS
メモリーリークがなぜ悪いか
メモリが圧迫され、killされるから
どうするか
・リークを見つける → ツールを使う
・リークを解消する → weak, closureで気をつける
・Webを彷徨うと、それでも発生するらしい
UnsafeMutablePointerを使い、手動でメモリを解放しようとしたとしても、Closure内でselfがキャプチャされていれば強参照として保持され、メモリが解放されないARCの仕様がある
Androidのpower profileを使うとバッテリー消費を計測できる
profilerで6分以上を計測するとログのパースが失敗しやすくなってしまう
iOSのURLSessionでAPIリクエストを送るとUserAgentは空となる
UserAgentを取るにはブラウザから取得する必要がある
Android Studioでプロファイラーを使うとログが膨大で動作が不安定になる
その場合はメモリ割り当てを増やすと安定する
ローカル デバイスのデバイス ミラーリング
Android studioで実機の画面を見れるようになってて感動
録画もできる
Power profilerはandroid 10以降
wlanの消費が多いがなぜ?