Open109

日々の雑感、開発備忘録

ニューロマンサーニューロマンサー

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カタログ

カタログ化することで、チーム内で共通のコンポーネントを再利用しやすくなります。
また、より疎結合なコンポーネントを作成できるので、開発に関してもポジティブになります

ニューロマンサーニューロマンサー

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)

ニューロマンサー2ニューロマンサー2

アプリエンジニアがIOTを最初から学ぶのはハードルが高い
そこでIOT Androidデバイスというものを利用すると、アプリ開発の知識を利用しながらIOTに関与できる
https://soracom.jp/support_partners/certified_device/acty-g3/

IOT Androidデバイスと一般のAndroidデバイスの一番の違いは、
・署名鍵
・ディスプレイの有無
の気がしている

特に署名鍵は、ある場合はIMEIやインストールされているアプリから再起動、別のアプリインストールなど自由に操作できる強力なもの

ニューロマンサー2ニューロマンサー2

"@react-google-maps/api"内のDrawingManagerを使うと GoogleMap内で自由に図形を描画できる
ただし初期値としてあらかじめ円やポリゴンを書いておくことはできない
それをするためにはPolygonやCircleコンポーネントを利用することになる
つまり、Reactで使うときの状態管理はより複雑になる

ニューロマンサー2ニューロマンサー2

Nextの状態管理ライブラリを選定する場合は、他に人の意見を聞いた方が良い
reduxが大嫌いという人もいる
recoilとZustandを使ってみたが、どちらも軽量で、非常に使いやすい
両方の移行も簡単

ニューロマンサー2ニューロマンサー2

React18の、StrictModeの追加機能によ理、typescriptのstrictモードをONにした場合、useEffectが2回呼ばれるので注意する

ニューロマンサー2ニューロマンサー2

一人で開発している場合、改善点はたくさんあるので、際限なくプロダクトに時間を取られてしまう
ある程度のところでPMに渡してしまうと意外と要件を通っているかもしれない

ニューロマンサー2ニューロマンサー2

DBとつなぐ管理画面を作る際はAppSheetを使うとセキュリティに配慮しつつ、カスタマイズ性がわりかし高いシートを作成できる
ログインもGoogleログインとなるので非常に安心
10人までなら無料

ニューロマンサー2ニューロマンサー2

Cloudflare Workersを個人開発で使ってみた
非常に開発しやすくAPIが作成できた
登録にクレジットカードの登録が必要ないのも非常にポジティブ
個人サイトであればCloudflare系を利用で十分足りる気がしている
githubと連携することでCICDも手軽に準備できるので、そちらのアカウントも用意すべき
https://developers.cloudflare.com/workers/

ニューロマンサー2ニューロマンサー2

GoogleMapで図形描画する際にハマりやすいのはもちろん状態管理
一時的なstateとグローバルなrecoilを使い分けながら作成していく
とはいえ、リッチな機能にすればするほどバグや、パフォーマンスの問題が出る
特にgoogleMap...

ニューロマンサー2ニューロマンサー2

GoogleMapでサークルを追加する機能を作成中
クリックで固定された半径の円を追加していた
その後、機能修正でもっとリッチに、マウスのドラッグ&ドロップで半径を柔軟に変えてサークルを作りたいとのこと
ドラッグ&ドロップの場合、イベントを正確に伝搬するのが難しく、誤作動になりやすいと感じている
ドロップする時に反応せずにサークルが作られなかったり、離していないのに勝手に作られたり
Reactのイベントが発火しているのか?
再描画は走っていない

ニューロマンサー2ニューロマンサー2

GoogleMapの、

  • onMouseDown(円state上に作成)
  • onMouseMove(円サイズ変更)
  • onMouseUp(円をDBに追加)
    これらのイベントを利用していたが、
    ・debounceのせいで遅延して、原因になっていたかも知れない
    ・描画時にstateを設定し、その状態をチェックすることでイベント伝搬を適切に管理するよう試みる
ニューロマンサー2ニューロマンサー2

なぜnullになるのか

import { random } from 'lodash';

const newId = random(100000, 1000000000000000000);
addNewID(newId); // これはReacoilの追加するイベント

これでnewIdがnullになる場合がある
...なぜ?

ニューロマンサー2ニューロマンサー2

ただただインスタンス再作成の際に、nullを入れていただけだった
typescriptを使っていたので静的型付けですぐ修正箇所がわかった
やはり静的型付けは良い

ニューロマンサー2ニューロマンサー2

PJを複数抱えると忘れてしまう問題

久しぶりなPJのプルリクレビューは思い出す作業が長い
dockerの立ち上げにも戸惑いながらな部分がある
これの手順書も作っておいた方が良いのか

ニューロマンサー2ニューロマンサー2

GCP CSR とBitbucket Cloudを繋げるにはAdmin権限と、PJの
source.repos.create、source.repos.updateRepoConfig
が必要となる見込み

ニューロマンサー2ニューロマンサー2
const nextConfig = {
  // ...
  experimental: {
    scrollRestoration: true,
  },
}

を有効化することで、スクロール位置を保存できる
しなくても有効化になっているブラウザもある。まちまち

ニューロマンサー2ニューロマンサー2

新しく生成したFlutter Projectのiosにpod fileがない
runすれば出力されるらしいが、一応simulatorではrunはしているのでちょっと謎

ニューロマンサー2ニューロマンサー2

結局手動でpod initした
自動生成されたような気がしていたが、気のせいだったか
最後に触ったの2年前だから。。。

ニューロマンサー2ニューロマンサー2

flutter packages getをした後、エラーがある状態のままxcode runをしたところ、動かせた
エラーも消えた
が、新しいエラーは出ている状態
auto fixで解決した
GeneratedPluginRegistrant.register(withRegistry: self)

ニューロマンサー2ニューロマンサー2

フレームワークが青く表示されているのは、プロジェクト。Xcodeでは、プロジェクトは慣例的に青色で表示されることが多い。つまり、表示されているアイテムが独立したビルド対象

一方、オレンジ色はコードではないファイル、例えばアセット、ストーリーボード、plistファイルなどの設定ファイルに使われます。オレンジ色は通常、プロジェクトに含まれるが直接コンパイルされないファイルを示す

ニューロマンサー2ニューロマンサー2

自作フレームワークがsimulator用のビルドで動くが、real deviceで動かない
フレームワークインポート時に、アーキテクチャを考慮したら動いた
下はsimulator用
上は実機用

ニューロマンサー2ニューロマンサー2

こちらの許可ダイアログが表示されない

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
}
ニューロマンサー2ニューロマンサー2

アプリ起動直後はダメらしい
これは動く

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")
    }
}
ニューロマンサー2ニューロマンサー2

androidソフトウェアビーコンのdevice uuidがiosのスキャナーで表示されない
サービスUUIDは表示される
OS間の際?

ニューロマンサー2ニューロマンサー2

FlutterにSDK組み込んだサンプルアプリを作った記録-iOS

  1. Flutterのインストール(vscode)
  2. Flutterの新規PJ作成
  3. Bundle identifierの変更
  4. auto signingの設定
  5. iOS div 直下pod init
  6. pod install
  7. firebase core, messagingの記載, pod install
  8. フレームワークdivにSDKのフレームワーク追加
  9. プッシュ通知送信のための、Googleserviceinfo.jsonをルートに追加
  10. AppDelegate内でfirebase initialize、各種delegateを設定
  11. SDKの読み込み、各種delegateを設定
  12. SDKのinitializeを実装
  13. 特にFCMトークンの払いだしを実装
  14. 特に利用規約画面の呼び出しを実装
  15. edit schemaで、ビルドをreleaseに設定
  16. Push通知受信テスト
  17. 管理画面でテスト結果確認
ニューロマンサー2ニューロマンサー2

FlutterにSDK組み込んだサンプルアプリを作った記録-Android

  1. Flutterのインストール(vscode)
  2. Flutterの新規PJ作成
  3. app直下にlibsフォルダを作成、SDKを設置
    1. pj直下のbuild.gradleのapplicationIdを既存のものに変更
  4. app直下のbuild.gradleにてAndroid API Levelを設定、SDKの依存関係を記載
  5. プッシュ通知送信のための、google-services.jsonをルートに追加
  6. FIrebaseのライブラリの依存関係を記載
  7. FIrebaseのライブラリinitialize
  8. 特にFCMトークンの払いだしを実装
  9. SDKの読み込み、各種delegateを設定
  10. SDKのinitializeを実装
  11. 通知チャンネルを作成, SDKに結果をコールバックする

Android studio

  • kotlinをinstall
  • vim
  • gradle sync
ニューロマンサー2ニューロマンサー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.

ニューロマンサー2ニューロマンサー2
repositories {
    flatDir {
        dirs 'libs'
    }
}

dependencies {
    // libsディレクトリのaarファイルを読み込む
    implementation(name: 'my-framework', ext: 'aar')

これapp直下のbuild.gradle入れないとライブラリ読み込めない(でしょうね)
初心者殺し

ニューロマンサー2ニューロマンサー2

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" />

ニューロマンサー2ニューロマンサー2

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を指定するのか...

ニューロマンサー2ニューロマンサー2


Android studioでiOS同様リリースビルドするには、build variantをreleaseに変更する
あとはプルダウンからrunを選択する

ニューロマンサー2ニューロマンサー2

AndroidでリモートPUSHを受け取るには

Implement

  • createNotificationChannel("サンプルアプリ");
  • setNotificationSmallIconResId(R.drawable.ic_notification)

Manifest

  • FirebaseMessagingService with override methods

  • Google-service-info.json

  • build.gradle -> 読み込み

ニューロマンサー2ニューロマンサー2

clear blade iot codeでproject後に、registryを作ろうとしたら、billingアカウントが設定エラーになった
結局インフラ担当に相談してなんとかしてもらう
\

ニューロマンサー2ニューロマンサー2

アプリのバッテリーへの負荷を調べるときに、実際に放置するパターンと、ツールを使って瞬間的な負荷を測るパターンがあるが、日本だと前者が強そう

ニューロマンサーニューロマンサー

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
    の状態を考慮する
ニューロマンサー2ニューロマンサー2

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.

ニューロマンサーニューロマンサー

firestoreへの接続方で、AIのハルシネーションのせいでdefaultに繋ごうとして、別のに繋げなくて困ってた
ググったら普通に繋げた
geminiもchatgptも同様だったから、なんか間違ったデータがあるのか

ニューロマンサー2ニューロマンサー2

firestoreからbigqueryへの手動エクスポートは簡単
exntesionも使えば自動もできそう、ただ、functionとか関連するものが全て作られるので掃除するのが手間

ニューロマンサー2ニューロマンサー2

firestoreからbigqueryへの拡張機能を使ったエクスポートにdefaultしか対応されていないので、実質gcp プロジェクトで1つしかエクスポートできない、不便...

ニューロマンサー2ニューロマンサー2

細かいnextjsのtips

  • ArtifactRegistryへのビルドスクリプトを作る
  • Firestoreは便利
  • .envファイルを作る
  • middlewareでbasic auth
ニューロマンサーニューロマンサー

新しいandroid studioでエラーが発生
やったこと
ライブラリのインポートでエラーが発生するので、下記を追加
implementation("androidx.work:work-runtime-ktx:2.7.3")

ニューロマンサー2ニューロマンサー2

ビルドいけました、結局android studioのjavaのバージョンを11に指定して、他そのままでした
以前まではjava 17系でもなんとなく動いたんですが...

ニューロマンサーニューロマンサー

DrawingManagerの描画アイコンがクリックできず、悩んでいた
どう無限re-renderが裏であり、それがgoogleMapを描画しまくっていたようだった
それを修正したところ、再度アイコンが効くようになった

ニューロマンサー2ニューロマンサー2

ジオフェンスは、2004年に米国のミズーリ大学で開発された、実際の地理的領域に仮想境界を作る技術及び考え方です。ジオフェンスという名前は、geo(地球や大地という意味の接頭語)とfence(柵)を組み合わせた造語です。実際のジオフェンスは特定エリアに仮想的な柵を作る仕組みで、ジオフェンスを使ったさまざまな施策をジオフェンシングと表記することもあります。

ジオフェンスはGPSやWi-Fiなどの位置情報データを使用し、対象がそのエリア内に入った、もしくは出たことを検知し、特定のアクションを起こします。この技術を使えば、顧客行動の調査をすることが可能になります。

事例
・顧客へのキャンペーン通知
・観光地での情報提供
・店舗内でのジオフェンス活用事例
・トラックの出入りや物流を管理

ニューロマンサー2ニューロマンサー2

"IDで指定したビーコンの電波をiOS端末が検知できる範囲を「リージョン」と定義し、ユーザによるリージョンへの出入りやある時点でユーザがリージョン内外のどちらにいるのかを通知する。
リージョンの内か外かでしか判定ができないため、ユーザとビーコンとの距離の変化をモニタリングできない。"

ニューロマンサー2ニューロマンサー2

iBeacon
"Apple社が発表したBLE(Bluetooth Low Energy)を用いたビーコンの規格です。
GPS(Global Positioning System)が屋内や地下などGPS衛星からの電波が届かない場所では測位が難しいのに対して、iBeaconは、屋内や地下でも問題なく利用でき、数cm~数十cmレベルで位置を特定できるために、通路や店舗のような狭い範囲で情報をピンポイントに発信できる利点があります。
また、通常のBluetoothではすぐに電力を使い果たしてしまうのに対して、BLEは極力電力を使わない規格で、屋外や電源から遠い場所での利用に適しています"

ニューロマンサー2ニューロマンサー2

"同じワイルドカードビーコンUUIDを監視している際に、実はエリアが変わっても、iOSが違うビーコンを同一と検知し、リージョン監視イベントが発火しないこと
同じUUIDと同じUUID/Major/Minorを設定しても同様で、OSが違うビーコンを同一と検知し、リージョン監視イベントが発火しないこと
特に施設内で多くのビーコンがある場合に発生しやすい"

ニューロマンサー2ニューロマンサー2

MAX20
それ以上をstartMonitoringForRegionで行おうとすると、didDetermineStateが21個以降、発火されなくなる
エラーは出ないみたい

ニューロマンサー2ニューロマンサー2

// バックグラウンドでのロケーション更新を許可しておく(①)
myLocationManager.allowsBackgroundLocationUpdates = true
// ロケーション更新の自動中断をオフにしておく(②)
myLocationManager.pausesLocationUpdatesAutomatically = false
することと、alwaysで許可をもらうことでbackgroundでも動く様子

ニューロマンサー2ニューロマンサー2

"iBeaconの情報取得方法①

リージョンの内か外かでしか判定ができないため、ユーザとビーコンとの距離の変化をモニタリングできない。
リージョン監視はアプリがフォアグラウンドでない場合も継続的に動作する"

ニューロマンサー2ニューロマンサー2

"iBeaconの情報取得方法②

意味
・発信側のBeacon端末と受信側のスマートフォンとの距離を測ること。
・ユーザーが中に入った場合には、スマートフォンとの距離を検出しています。

挙動
・IDで指定したビーコンの電波強度等の情報を1秒ごとに取得する。
・レンジングを活用することで、ユーザとビーコンとのおよその距離に応じて処理を変えるなど、柔軟なアプリ設計が可能になる。
・複数のビーコンを設置し、継続的に電波強度をモニタリングできれば、屋内移動ログの取得といったユースケースに応用できる。"

ニューロマンサー2ニューロマンサー2

"Appleのポリシーに適合する実装であるか
Appleがバックグラウンドでのビーコンレンジングをどの程度許容する姿勢であるかは不明。直近でもiOS13でアプリのバックグラウンド実行が強制終了される事象が報告され、その後のアップデートで修正されていた(iOS13.2.2公開、データ通信不具合、バックグラウンドアプリ強制終了など修正)。今後のOSアップデートで仕様が変わる可能性がある。
WWDC19での発表を参照すると、iOSでのバックグラウンド処理は必要性の高い特定のユースケースに限定して用いられるべきというAppleの意図が読み取れる。また、バックグラウンド処理の実装に当たってはパフォーマンス・バッテリー消費・プライバシーの3点に留意すべきことも強調されている。バックグラウンドでのレンジングがこうしたAppleの意図にどこまで適合的かは不明確であるため、ストア申請時は注意が必要である。
App Store Reviewガイドラインでは下記の記述がみられる。"

ニューロマンサー2ニューロマンサー2

"AirTagを用いてAppleの「さがす」アプリを調査した結果、アプリが主にジオフェンシングと呼ばれる地図上の円からの出入りを監視する手法を用いてユーザーの位置情報を低い消費電力でトラッキングしていることがわかりました。

具体的には以下のように、位置情報を取得した際に地図上にジオフェンスを貼り、その領域を出た際にその位置を中心に新たなジオフェンスを貼り...ということを繰り返すことで細かい移動の追跡に電力を費やさずに大まかな軌跡を把握し、紛失中のiPhoneとのすれ違い時やAirTagから離れた際にのみBluetoothでアプリを起動し位置情報を取得することで低消費電力とサービスを両立させているようです。"

ニューロマンサー2ニューロマンサー2

BIgqueryのDataSetはリージョンを跨ぐと連携ができない(コピーなども面倒になる)
のでリージョンは非常に重要

ニューロマンサー2ニューロマンサー2

どうするか
・リークを見つける → ツールを使う
・リークを解消する → weak, closureで気をつける
・Webを彷徨うと、それでも発生するらしい

ニューロマンサー2ニューロマンサー2

UnsafeMutablePointerを使い、手動でメモリを解放しようとしたとしても、Closure内でselfがキャプチャされていれば強参照として保持され、メモリが解放されないARCの仕様がある

ニューロマンサー2ニューロマンサー2

iOSのURLSessionでAPIリクエストを送るとUserAgentは空となる
UserAgentを取るにはブラウザから取得する必要がある

ニューロマンサー2ニューロマンサー2

Android Studioでプロファイラーを使うとログが膨大で動作が不安定になる
その場合はメモリ割り当てを増やすと安定する