react-native-mmkvを導入したら Undefined symbols for architecture x86_64 が出た
react-native0.68.4
どうやら react-native-firebase を導入した時にPodfileに加えた use_frameworks!
が原因っぽい。
結論としては、react-native-mmkvを静的ライブラリとして読み込んであげると解決した。
pre_install do |installer| installer.pod_targets.each do |pod| if pod.name.eql?('react-native-mmkv') def pod.build_type; Pod::BuildType.static_library end end end end
pre_install
はpodをインストールする前に何らかの変更を加えてくれる。
BuildType.static_library
により静的ライブラリとして登録。
ExpoでiOSのスキーマ加えてビルドしたら error: filename "ExpoModulesProvider.swift" used twice: が出た
TARGETS -> Build Phases -> Compile Sources
に ExpoModulesProvider.swift
が2つ登録されてしまっていたのでいらない方消す。
Swiftでマップや位置情報を使う
Swift初心者のメモです。
iOS15で検証
マップ
基本となるインスタンス
import MapKit let mapView = MKMapView()
ユーザーの現在地表示(青ポチのあれ)
mapView.showsUserLocation = true
トラッキングモード(青ポチが自動で移動するあれ)
mapView.userTrackingMode = MKUserTrackingMode.follow // 方向を表示する場合 // mapView.userTrackingMode = MKUserTrackingMode.followWithHeading
MKUserTrackingMode.followまたは .followWithHeading を指定していると、初回表示で縮尺や中心を指定してなくても現在地が中心になる。
中心となる緯度経度の設定
let lat = CLLocationDegrees(<緯度>) let lng = CLLocationDegrees(<経度>) let loc: CLLocationCoordinate2D = CLLocationCoordinate2DMake(lat, lng) mapView.setCenter(loc, animated: true)
縮尺の設定
var region: MKCoordinateRegion = mapView.region region.span.latitudeDelta = 0.1 region.span.longitudeDelta = 0.1 region.center = loc // locは上記で定義 mapView.setRegion(region, animated: true)
setRegionを使う場合には region.center で中心地も指定できるので setCenter を使用する必要はない
タップした位置の緯度経度を取得する
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(mapTapped(_:))) mapView.addGestureRecognizer(tapGesture) ... @objc func mapTapped(_ sender: UITapGestureRecognizer) { if sender.state == .ended { let tapPoint = sender.location(in: mapView) let coordinate = mapView.convert(tapPoint, toCoordinateFrom: mapView) print(coordinate.latitude) print(coordinate.longitude) } }
アノテーションを加える(ピンみたいなマークのあれ)
let annotation = MKPointAnnotation() annotation.coordinate = coordinate // CLLocationCoordinate2D mapView.addAnnotation(annotation)
緯度経度から住所などの追加情報を取得
逆ジオコーディングと言われるやつ。
let cla = coordinate.latitude // CLLocationCoordinate2D let clo = coordinate.longitude // CLLocationCoordinate2D let location = CLLocation(latitude: cla, longitude: clo) CLGeocoder().reverseGeocodeLocation(location, completionHandler: { placemarks, error in if error != nil { return } let placemark = placemarks.first })
位置情報
基本となるインスタンス
import CoreLocation let locationManager = CLLocationManager()
受け取りたい位置情報の正確さ
locationManager.desiredAccuracy = kCLLocationAccuracyBest // 最も精度が高い
iOSアプリの場合は kCLLocationAccuracyBest がデフォルト
デバイスで位置情報が使用可能かどうか
CLLocationManager.locationServicesEnabled()
これはアプリレベルで位置情報の使用が許可されているかどうかではなく、デバイスレベルで使用可能かどうか。
設定の プライバシー > 位置情報サービス がオフになっているとfalseが返る。
使用許可のステータス
let status = locationManager.authorizationStatus
位置情報使用のリクエスト
// バックグラウンドでも許可使用したい場合 locationManager.requestAlwaysAuthorization() // アプリ使用中の許可を取りたい場合 locationManager.requestWhenInUseAuthorization()
どちらを実行しても「アプリ使用中の位置情報の取得の許可」のためのダイアログが表示される。
文言も NSLocationWhenInUseUsageDescription で指定したものが表示される。
このメソッドを実行した時点で CLLocationManager.locationServicesEnabled() がfalseだった場合、「位置情報サービスをオンにしてください」というアラートが自動で表示される。
requestAlwaysAuthorization()を実行した場合
初回ダイアログ
「Appの使用中は許可」を押すとコード上のステータスは authorizedAlways
になる。
「一度だけ許可」を押すとコード上のステータスは authorizedWhenInUse
になる。
「許可しない」だと denied
になる。
authorizedWhenInUse
の場合はバックグラウンドでは位置情報が更新できない。なのでバックグラウンドでも位置情報の更新を取得する必要があるアプリはアラートなので設定を authorizedAlways
にするように誘導する必要がありそう。
This authorization allows you to use all location services and receive location events only when your app is in use. To continue using location services in the background, enable Continuous Background Location Updates and start the services while the app is in use.
denied
の場合は位置情報が使用できないので、必須のアプリではアラートを出すなどしてアプリの機能を使えないことの通知が必要になりそう。
Appの使用中は許可を選択した場合
アプリの設定画面では「このAppの使用中のみ許可」になる。
コード状は authorizedAlways
なので位置情報はバックグラウンドでも更新される。
しばらくして表示されるダイアログの 「”常に許可”に変更 」を押した時点でアプリ側の設定も変わる。
ここで「”使用中のみ許可”のままにする」にすると authorizedWhenInUse
になる。
位置情報の許可ステータス変更によって実行されるdelegate
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { let status = locationManager.authorizationStatus switch status { } }
位置情報の変更を検知させる
// 位置情報の更新を検知した場合、locationManagerを実行させる locationManager.startUpdatingLocation() ... // .startUpdatingLocation()が呼ばれている場合、位置情報の更新を受け取り実行される func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { }
PrismaからCloud SQLに接続するための DATABASE_URL のhost以降
host=/cloudsql/PROJECT_id:REGION:NAME
terraformからIAMを作成する時に Error retrieving IAM policy for project ~ googleapi: Error 403: The caller does not have permission
terraformからIAMを作成するために以下のようなコードを書いた。
resource "google_service_account" "scheduler_invoker" { display_name = "Schedler Invoker" account_id = "scheduler-invoker" } resource "google_project_iam_member" "run_invoker" { role = "roles/run.invoker" member = "serviceAccount:${google_service_account.scraping_scheduler_invoker.email}" project = var.project }
これで apply すると以下のようなエラーが出た。
Request `Create IAM Members roles/run.invoker serviceAccount:~"` returned error: Error retrieving IAM policy for project "~": googleapi: Error 403: The caller does not have permission, forbidden
IAMポリシーをいじるためのロールが terraform の credentials に渡したIAMに存在しない。
IAMに「Project IAM 管理者」を付与すると解決する。
ReactNativeでデバッグ用apkファイルを作成する
プロジェクトルートで
react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res
cd android
./gradlew assembleDebug
yourProject/android/app/build/outputs/apk/debug/app-debug.apk
にapkファイルが作成される。
TerraformでGCPのCloud SQL(postgres)のtierを指定するときのポイント
TerraformでGCPのCloud SQLをpostgresで立てようと思った。
CPUやメモリなどを含んだマシンタイプを指定する必要があるが、今までは db-f1-micro のようにGCPがデフォルトで提供しているタイプを使用していた。
tier = "db-f1-micro"
これを db-lightweight-1 に変えてapplyしたのだが、変更することができなかった。
これによると、
Postgres supports only shared-core machine types, and custom machine types such as db-custom-2-13312.
とのことで、共有コアのマシンタイプのものしか指定できず、それ以外の場合はカスタムマシンタイプにする必要がある。
「db-custom-CPU数-メモリ量」で表すことはできるが、なんでも数値を入れることができるわけではなく、
CPU の数とメモリの量を選択する際、選択する構成にはいくつかの制限があります。
vCPU は 1 または 2~96 の間の偶数にする必要があります。
メモリは次の条件を満たす必要があります。
vCPU あたり 0.9~6.5 GB 256 MB の倍数 3.75 GB(3,840 MB)以上
この条件を満たしていなければならない。
インスタンスの設定について | Cloud SQL for MySQL | Google Cloud
なのでカスタムマシンタイプを指定する場合の最小構成は db-custom-1-3840 ということになる。