20191115のiOSに関する記事は5件です。

XCTestCaseで作ったテストをxcodebuildで実行する方法

CIにテストを実行するためにXcodeの場合、xcodebuildを用いて処理するように設定していくと思います。
その際、端末別やOS別のテストを1つのクラス内に作っているケースがあるとして、テストケースを改修するコストよりもコマンド側で個別に呼び出す方針を取ったとき、どう設定すれば良いのかまとめておく。

目的

  1. CIに端末別とOS別にテストを行うジョブを構築
  2. 特定のXCTestCaseのテストをxcodebuildで実行させる (←本題)

環境

  • Mac
    • macOS Mojave - version 10.14.6
  • Xcode
    • version 11.2
  • CI
    • Jenkins

準備

CI機となる共有PC(Mac miniなど)にXcodeをダウンロードし、1度Xcodeを起動させて初回の設定を済ませておく。
また今回は、CIに関することは割愛とする。

次のように$ instruments -s devicesまたは$ xcrun simctl listからどのシミュレータを扱うか確認しておく。
もし扱いたい機種やOSがdevicesに無い場合は、Xcodeからデバイスを作成すること。

$ instruments -s devices
CoreData: annotation:  Failed to load optimized model at path '/Applications/Xcode.app/Contents/Applications/Instruments.app/Contents/Frameworks/InstrumentsPackaging.framework/Versions/A/Resources/XRPackageModel.momd/XRPackageModel 9.0.omo'
Known Devices:
gremitoのMacBook Pro [664E45D8-39FF-5D37-A42C-26FE51F10A9B]
Apple TV (13.2) [ADD78466-F544-4D33-9321-C81D4D0FC150] (Simulator)
Apple TV 4K (13.2) [C132945D-C5E9-40A6-915D-879E1B82BF2D] (Simulator)
Apple TV 4K (at 1080p) (13.2) [CF8827A4-3A31-48C9-9418-C31C8C9866EA] (Simulator)
Apple Watch Series 4 - 40mm (6.1) [2D3C75B6-07A6-4702-94C5-14A3CA12A818] (Simulator)
Apple Watch Series 4 - 44mm (6.1) [91BADC1D-4E20-44D3-A2A7-51E73693BC29] (Simulator)
iPad (7th generation) (13.2) [32489E3C-0348-477D-980A-11F0A0C27445] (Simulator)
iPad Air (3rd generation) (13.2) [53AA791E-5D2A-4989-8AAB-0564A1B10491] (Simulator)
iPad Pro (11-inch) (13.2) [7D8E1B5E-2286-475A-9406-17613AEC5998] (Simulator)
iPad Pro (12.9-inch) (3rd generation) (13.2) [602C1998-075C-4F53-8E9D-9D4233F26747] (Simulator)
iPad Pro (9.7-inch) (13.2) [C2B230EE-A01D-4E76-BA91-2214812D5047] (Simulator)
iPhone 11 (13.2) [E451C70D-4AA3-4C4B-A88C-E7A5EB1126A2] (Simulator)
iPhone 11 Pro (13.2) [B042F66E-2277-482D-97AE-9F2884EEDAE0] (Simulator)
iPhone 11 Pro (13.2) + Apple Watch Series 5 - 40mm (6.1) [32D82CF1-770B-4839-8F31-90C4CCCADCE7] (Simulator)
iPhone 11 Pro Max (13.2) [BF1E7BC6-A927-4C43-ADA7-8FEB2A658881] (Simulator)
iPhone 11 Pro Max (13.2) + Apple Watch Series 5 - 44mm (6.1) [26D86766-3435-42E9-B0D0-1F9F62DA7681] (Simulator)
iPhone 8 (13.2) [BDDE5F62-2721-41D5-ACA9-1EF6394627BC] (Simulator)
iPhone 8 Plus (13.2) [BD3AFEE1-975A-41DE-BE91-776D7E37F270] (Simulator)

$ xcrun simctl list
== Device Types ==
iPhone 4s (com.apple.CoreSimulator.SimDeviceType.iPhone-4s)
iPhone 5 (com.apple.CoreSimulator.SimDeviceType.iPhone-5)
iPhone 5s (com.apple.CoreSimulator.SimDeviceType.iPhone-5s)
iPhone 6 Plus (com.apple.CoreSimulator.SimDeviceType.iPhone-6-Plus)
iPhone 6 (com.apple.CoreSimulator.SimDeviceType.iPhone-6)
iPhone 6s (com.apple.CoreSimulator.SimDeviceType.iPhone-6s)
iPhone 6s Plus (com.apple.CoreSimulator.SimDeviceType.iPhone-6s-Plus)
iPhone SE (com.apple.CoreSimulator.SimDeviceType.iPhone-SE)
iPhone 7 (com.apple.CoreSimulator.SimDeviceType.iPhone-7)
iPhone 7 Plus (com.apple.CoreSimulator.SimDeviceType.iPhone-7-Plus)
iPhone 8 (com.apple.CoreSimulator.SimDeviceType.iPhone-8)
iPhone 8 Plus (com.apple.CoreSimulator.SimDeviceType.iPhone-8-Plus)
iPhone X (com.apple.CoreSimulator.SimDeviceType.iPhone-X)
iPhone Xs (com.apple.CoreSimulator.SimDeviceType.iPhone-XS)
iPhone Xs Max (com.apple.CoreSimulator.SimDeviceType.iPhone-XS-Max)
iPhone Xʀ (com.apple.CoreSimulator.SimDeviceType.iPhone-XR)
iPhone 11 (com.apple.CoreSimulator.SimDeviceType.iPhone-11)
iPhone 11 Pro (com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro)
iPhone 11 Pro Max (com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro-Max)
iPad 2 (com.apple.CoreSimulator.SimDeviceType.iPad-2)
iPad Retina (com.apple.CoreSimulator.SimDeviceType.iPad-Retina)
iPad Air (com.apple.CoreSimulator.SimDeviceType.iPad-Air)
iPad mini 2 (com.apple.CoreSimulator.SimDeviceType.iPad-mini-2)
iPad mini 3 (com.apple.CoreSimulator.SimDeviceType.iPad-mini-3)
iPad mini 4 (com.apple.CoreSimulator.SimDeviceType.iPad-mini-4)
iPad Air 2 (com.apple.CoreSimulator.SimDeviceType.iPad-Air-2)
iPad Pro (9.7-inch) (com.apple.CoreSimulator.SimDeviceType.iPad-Pro--9-7-inch-)
iPad Pro (12.9-inch) (com.apple.CoreSimulator.SimDeviceType.iPad-Pro)
iPad (5th generation) (com.apple.CoreSimulator.SimDeviceType.iPad--5th-generation-)
iPad Pro (12.9-inch) (2nd generation) (com.apple.CoreSimulator.SimDeviceType.iPad-Pro--12-9-inch---2nd-generation-)
iPad Pro (10.5-inch) (com.apple.CoreSimulator.SimDeviceType.iPad-Pro--10-5-inch-)
iPad (6th generation) (com.apple.CoreSimulator.SimDeviceType.iPad--6th-generation-)
iPad (7th generation) (com.apple.CoreSimulator.SimDeviceType.iPad--7th-generation-)
iPad Pro (11-inch) (com.apple.CoreSimulator.SimDeviceType.iPad-Pro--11-inch-)
iPad Pro (12.9-inch) (3rd generation) (com.apple.CoreSimulator.SimDeviceType.iPad-Pro--12-9-inch---3rd-generation-)
iPad mini (5th generation) (com.apple.CoreSimulator.SimDeviceType.iPad-mini--5th-generation-)
iPad Air (3rd generation) (com.apple.CoreSimulator.SimDeviceType.iPad-Air--3rd-generation-)
Apple TV (com.apple.CoreSimulator.SimDeviceType.Apple-TV-1080p)
Apple TV 4K (com.apple.CoreSimulator.SimDeviceType.Apple-TV-4K-4K)
Apple TV 4K (at 1080p) (com.apple.CoreSimulator.SimDeviceType.Apple-TV-4K-1080p)
Apple Watch - 38mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-38mm)
Apple Watch - 42mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-42mm)
Apple Watch Series 2 - 38mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-2-38mm)
Apple Watch Series 2 - 42mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-2-42mm)
Apple Watch Series 3 - 38mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-3-38mm)
Apple Watch Series 3 - 42mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-3-42mm)
Apple Watch Series 4 - 40mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-4-40mm)
Apple Watch Series 4 - 44mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-4-44mm)
Apple Watch Series 5 - 40mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-5-40mm)
Apple Watch Series 5 - 44mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-5-44mm)
== Runtimes ==
iOS 13.2 (13.2 - 17B84) - com.apple.CoreSimulator.SimRuntime.iOS-13-2 
tvOS 13.2 (13.2 - 17K81) - com.apple.CoreSimulator.SimRuntime.tvOS-13-2 
watchOS 6.1 (6.1 - 17S83) - com.apple.CoreSimulator.SimRuntime.watchOS-6-1 
== Devices ==
-- iOS 13.2 --
    iPhone 8 (BDDE5F62-2721-41D5-ACA9-1EF6394627BC) (Shutdown) 
    iPhone 8 Plus (BD3AFEE1-975A-41DE-BE91-776D7E37F270) (Shutdown) 
    iPhone 11 (E451C70D-4AA3-4C4B-A88C-E7A5EB1126A2) (Shutdown) 
    iPhone 11 Pro (B042F66E-2277-482D-97AE-9F2884EEDAE0) (Shutdown) 
    iPhone 11 Pro Max (BF1E7BC6-A927-4C43-ADA7-8FEB2A658881) (Shutdown) 
    iPad Pro (9.7-inch) (C2B230EE-A01D-4E76-BA91-2214812D5047) (Shutdown) 
    iPad (7th generation) (32489E3C-0348-477D-980A-11F0A0C27445) (Shutdown) 
    iPad Pro (11-inch) (7D8E1B5E-2286-475A-9406-17613AEC5998) (Shutdown) 
    iPad Pro (12.9-inch) (3rd generation) (602C1998-075C-4F53-8E9D-9D4233F26747) (Shutdown) 
    iPad Air (3rd generation) (53AA791E-5D2A-4989-8AAB-0564A1B10491) (Shutdown) 
-- tvOS 13.2 --
    Apple TV (ADD78466-F544-4D33-9321-C81D4D0FC150) (Shutdown) 
    Apple TV 4K (C132945D-C5E9-40A6-915D-879E1B82BF2D) (Shutdown) 
    Apple TV 4K (at 1080p) (CF8827A4-3A31-48C9-9418-C31C8C9866EA) (Shutdown) 
-- watchOS 6.1 --
    Apple Watch Series 4 - 40mm (2D3C75B6-07A6-4702-94C5-14A3CA12A818) (Shutdown) 
    Apple Watch Series 4 - 44mm (91BADC1D-4E20-44D3-A2A7-51E73693BC29) (Shutdown) 
    Apple Watch Series 5 - 40mm (32D82CF1-770B-4839-8F31-90C4CCCADCE7) (Shutdown) 
    Apple Watch Series 5 - 44mm (26D86766-3435-42E9-B0D0-1F9F62DA7681) (Shutdown) 
== Device Pairs ==
8266A1DA-60F1-443E-A9C3-FBED1C9E94F7 (active, disconnected)
    Watch: Apple Watch Series 5 - 40mm (32D82CF1-770B-4839-8F31-90C4CCCADCE7) (Shutdown)
    Phone: iPhone 11 Pro (B042F66E-2277-482D-97AE-9F2884EEDAE0) (Shutdown)
9EA20D9C-4745-4A3B-A89A-22237520ADD1 (active, disconnected)
    Watch: Apple Watch Series 5 - 44mm (26D86766-3435-42E9-B0D0-1F9F62DA7681) (Shutdown)
    Phone: iPhone 11 Pro Max (BF1E7BC6-A927-4C43-ADA7-8FEB2A658881) (Shutdown)

設定

以下のようにCIに設定することで特定のテストが処理させるようになる。
念のためCIで動作して確認する前にターミナルで問題なく動作するか確認しておくこと。

# iPhone 11(iOS 13.2)のテスト
xcodebuild \
 -workspace iOSAppProject/iOSAppProject.xcodeproj/project.xcworkspace \
 -scheme iOSAppProject \
 -destination OS=13.2,name="iPhone 11" \
 -only-testing:iOSAppProjectTests/iPhoneTests/iOS12OrBelowTest \
 -configuration Debug build test

# iPhone X(iOS 12.1)のテスト
xcodebuild \
 -workspace iOSAppProject/iOSAppProject.xcodeproj/project.xcworkspace \
 -scheme iOSAppProject \
 -destination OS=12.1,name="iPhone 10" \
 -only-testing:iOSAppProjectTests/iPhoneTests/iOS13OrHigherTest \
 -configuration Debug build test

# iPad Pro (12.9-inch)(iOS 13.2)のテスト
xcodebuild \
 -workspace iOSAppProject/iOSAppProject.xcodeproj/project.xcworkspace \
 -scheme iOSAppProject \
 -destination OS=13.2,name="iPad Pro (12.9-inch)" \
 -only-testing:iOSAppProjectTests/iPadTests/iPadProTest \
 -configuration Debug build test

# iPad mini 2(iOS 12.4.3)のテスト
xcodebuild \
 -workspace iOSAppProject/iOSAppProject.xcodeproj/project.xcworkspace \
 -scheme iOSAppProject \
 -destination OS=12.4.3,name="iPad mini 2" \
 -only-testing:iOSAppProjectTests/iPadTests/iPadMiniTest \
 -configuration Debug build test

上記のように特定のオプションの設定を変えるだけなので、シェル対応で変数化すると良いでしょう。
端末やOSはシミュレータの確認で表示された内容を指定できます。

参考記事

 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[iOS] Firebase AuthenticationでSign in with Apple

こんにちは、株式会社実験のエンジニアのmogamingです。

今朝、firebase-ios-sdkにSign in with Apple対応がマージされてリリースされました???中の方々本当にありがとうございます。感謝しかない!

ちょうど新しいアプリでSNSログインが必要で、FirebaseのSDKに対応が入るのを待ちつつ別の機能を作ってました。せっかくリリースされたので早速対応してみたので、やったことを書きます。iOSアプリでの対応の話しかしません。

参考リンク

基本的にはドキュメントを読めばなんとかなります。読みましょう。

手順

Capabilityの設定

  • Certificates, Identifiers & Profilesで設定
    • メールを送りたい人はリレーの設定が必要ですが僕は不要なので割愛。ドメイン設定するだけ。 スクリーンショット 2019-11-15 16.17.24.png
  • Xcodeでも設定

Firebase側の設定

有効にするだけ

スクリーンショット 2019-11-15 16.20.42.png

コードを書く

Firebaseのドキュメントに書いてあるやつをそのまま持ってきます。ちょっと長いのでポイントを書いておくと

  • import AuthenticationServices が必須
  • SHA256import CryptKit が必要
  • authorizationController.presentationContextProvider = selfpresentationContextProviderASAuthorizationControllerPresentationContextProviding に準拠している必要がありますが、これは func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor をメソッドとして持っていればよく、この返り値の ASPresentationAnchorUIWindow のtypealiasとして定義されているようです。よって、このメソッドではSign in with Appleのモーダル表示を行いたい UIWindow を返せばよいです。僕はめんどくさかったので、AppDelegateに ASAuthorizationControllerPresentationContextProviding を準拠させて window を返すようにしてます。

以下関数はそのまま持ってきて、適当なUIViewControllerにおいたやつ。たぶん動くでしょう。

import UIKit
import AuthenticationServices
import CryptoKit

class ViewController: UIViewController {
    // Adapted from https://auth0.com/docs/api-auth/tutorials/nonce#generate-a-cryptographically-random-nonce
    private func randomNonceString(length: Int = 32) -> String {
      precondition(length > 0)
      let charset: Array<Character> =
          Array("0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._")
      var result = ""
      var remainingLength = length

      while remainingLength > 0 {
        let randoms: [UInt8] = (0 ..< 16).map { _ in
          var random: UInt8 = 0
          let errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random)
          if errorCode != errSecSuccess {
            fatalError("Unable to generate nonce. SecRandomCopyBytes failed with OSStatus \(errorCode)")
          }
          return random
        }

        randoms.forEach { random in
          if length == 0 {
            return
          }

          if random < charset.count {
            result.append(charset[Int(random)])
            remainingLength -= 1
          }
        }
      }

      return result
    }

    // Unhashed nonce.
    fileprivate var currentNonce: String?

    @available(iOS 13, *)
    func startSignInWithAppleFlow() {
      let nonce = randomNonceString()
      currentNonce = nonce
      let appleIDProvider = ASAuthorizationAppleIDProvider()
      let request = appleIDProvider.createRequest()
      request.requestedScopes = [.fullName, .email]
      request.nonce = sha256(nonce)

      let authorizationController = ASAuthorizationController(authorizationRequests: [request])
      authorizationController.delegate = self
      authorizationController.presentationContextProvider = self
      authorizationController.performRequests()
    }

    @available(iOS 13, *)
    private func sha256(_ input: String) -> String {
      let inputData = Data(input.utf8)
      let hashedData = SHA256.hash(data: inputData)
      let hashString = hashedData.compactMap {
        return String(format: "%02x", $0)
      }.joined()

      return hashString
    }
}

@available(iOS 13.0, *)
extension ViewController: ASAuthorizationControllerDelegate {
  func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
    if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
      guard let nonce = currentNonce else {
        fatalError("Invalid state: A login callback was received, but no login request was sent.")
      }
      guard let appleIDToken = appleIDCredential.identityToken else {
        print("Unable to fetch identity token")
        return
      }
      guard let idTokenString = String(data: appleIDToken, encoding: .utf8) else {
        print("Unable to serialize token string from data: \(appleIDToken.debugDescription)")
        return
      }
      // Initialize a Firebase credential.
      let credential = OAuthProvider.credential(withProviderID: "apple.com",
                                                idToken: idTokenString,
                                                rawNonce: nonce)
      // Sign in with Firebase.
      Auth.auth().signIn(with: credential) { (authResult, error) in
        if error {
          // Error. If error.code == .MissingOrInvalidNonce, make sure
          // you're sending the SHA256-hashed nonce as a hex string with
          // your request to Apple.
          print(error.localizedDescription)
          return
        }
        // User is signed in to Firebase with Apple.
        // ...
      }
    }
  }

  func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
    // Handle error.
    print("Sign in with Apple errored: \(error)")
  }
}

@available(iOS 13.0, *)
extension ViewController: ASAuthorizationControllerPresentationContextProviding {
    func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
        return self.view.window!
    }
}

ボタンの配置

Human Interface Guideline に従っておけばよいでしょう。ASAuthorizationAppleIDButton を使えば見た目は全部やってくれますが、ボタンの文言は予め用意されているものしか使えず、文字の大きさはボタンの大きさによって勝手に変わるようになっています。cornerRadiusは設定できます。自前で作っちゃだめとは書いてないように思うので、自分で作っても良いと思います。

iOS12の対応

iOS12では CrypoKit がバンドルされていないため、ランタイムでクラッシュしてしまいます。 BuildSettingsOther Linker Flags-weak_framework CryptoKitを追加設定しましょう。

挙動メモ

UI

  • requestedScopes に指定したものが提供されないと 続ける が有効にならない
  • 名前の部分はこの画面上で編集できるし、編集後のものがアプリには渡される
  • ログインの体験としては個人的には最高だった…

発行されるIDTokenのPayload

IDTokenにはFullNameが入っていなかったように思う。

{
  "iss": "https://appleid.apple.com",
  "aud": "アプリのBundleID",
  "exp": 1573797591,
  "iat": 1573796991,
  "sub": "Apple側で管理しているUserIDかな?Sign in with Appleの仕様にそこまで詳しくないがグローバルなものではないと思う。アプリごととか開発者アカウントごとな気がしている。",
  "nonce": "2ca34ffa6c2c5379d7454f457ba3b6eb53c419ccff0cffd801ed340bf24e1751",
  "c_hash": "OBuSAYvYURTfMqOzMWgWaA",
  "email": "vd9xrua52z@privaterelay.appleid.com(僕の非公開メアド。ここには許可したドメインからしかメールが送れない)",
  "email_verified": "true",
  "is_private_email": "true",
  "auth_time": 1573796991
}

Firebase.User.displayName

firebase側のUserクラスにはdisplayNameという変数があり、例えばTwitterログインするとTwitterの名前が入っている。Sign in with AppleでfullName指定してログインしたら入ってるかなーと気軽にやってみたら入っていなかった。下記ツイート以下を見てもらえればよいが、そういうものっぽい。

https://twitter.com/_mogaming/status/1195218616657952768

fullNameのフォーマット

ASAuthorizationAppleIDCredential から fullName が取れる。こいつの型は PersonNameComponentsFormatter でこの中にgivenNameとかfamilyNameがあるんだけど、いい感じに組み立ててほしかったので調べたらフォーマッターが用意されていた。PersonNameComponentsFormatter というやつで、style を適宜変えるといい感じになって返ってくる。ドキュメントに例が載っていてめちゃくちゃわかりやすいのでぜひ見てみて。

おわりに

iOSアプリのみとかの場合はとってもいい認証方法だと思うが、一般の方々がどれくらいAppleIDに対して抵抗があるかよくわからないのでなんだかんだこれ1本にはし難いかもしれない。僕はこれ1本にしたい。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

iOSのアクティビティアプリが動かない場合の対処法

Qiitaで書くか微妙な話ですが、地味に困っていた事が解決出来たので書いておきます。

タイトルに対する結論

iPhoneを暗号化せずバックアップ→そのバックアップで復元する
ヘルスケアデータは初期化されてしまいますが、アプリは起動できるようになります。

iOSの復元をしたらアクティビティアプリが沈黙

何がきっかけだったのか忘れてしまいましたが、iPhoneをバックアップ→復元したら
アクティビティアプリを起動するとローディングのぐるぐるマークが出たまま動かなくなってしまいました。
アクティビティアプリと連携しているヘルスケアアプリも歩数等のデータを取り込めていないようです。
Apple Watchで測定していた日々のカロリー消費等のデータも見られなくなってしまいました。

推測するに、復元の過程でヘルスケアに関わるデータが破損してしまったのかもしれません。

対処法を考える

データが破損してしまったなら対処法として考えられるのは二つ。

  1. 破損データを修復
  2. データを初期化

破損データを修復出来れば過去のデータも残せる可能性がありますが、そもそもどこにデータがあるのかよく分かりません…。
今回はデータを初期化する方法を紹介します。

ヘルスケアデータを初期化する

Appleのサポートページによると、ヘルスケアのデータはバックアップを暗号化する事で、バックアップ出来るようです。
逆に言えば、暗号化しなければヘルスケアデータはバックアップされない=初期化されます。

暗号化せずにバックアップをしたら、そのバックアップでiPhoneを復元しましょう。
すると、ヘルスケアデータはリセットされていますがアプリは起動するはずです。

ちなみに、Apple Watchのストレージにある程度の期間のヘルスケアデータは残っているので、復元後に同期させるとApple Watchのデータが反映されます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

iPhoneのSafariで横向きにしたときに文字が一部拡大してしまう

【CSS3】iOSのサファリで縦画面から横画面にすると文字が大きくなるのを防ぐ設定

iPhone Safari 横
24007581-BA54-4D6D-BB66-639D5167D9E0.jpeg
iPhone Safari 縦
853E5CD4-3F1A-441B-B4A4-3BE7FFE7EEC6.jpeg

横にすると、※1が拡大されてしまう。
おそらくiPhoneのSafariのみ。
なので、
text-size-adjust
これでテキストの自動拡大アルゴリズムを制御する。

    body {
        //iPhoneのSafariでで横向きにした際に一部文字が拡大されてしまうための対応
      -webkit-text-size-adjust: 100%;
    }

これで出来る。
Can I use... Support tables for HTML5, CSS3, etc
iOSのSafariではprefixが必要なので、-webkit-をつける。

ただnoneは指定してはいけない。
[備忘録]「-webkit-text-size-adjust」は指定しておこう、今のところは! | ultimate-ez.com

PCでのユーザビリティに影響するらしい。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Flutter】'initialCameraPosition != null' : is not true.が起こった時の解決策

なりゆき

以下のページを参照しながらコピペをしていると途中で画像のエラーが起きた。
Google公式Flutter用Google Mapsプラグインを一通り使ってみた

image.png

解決方法

initialCameraPositionがnullということなのでカメラの初期座標を設定する。

lib/main.dart
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        height: MediaQuery.of(context).size.height,
        width: MediaQuery.of(context).size.width,
        child: GoogleMap(
          onMapCreated: _onMapCreated,
          //以下に座標を追記
          initialCameraPosition: CameraPosition(
            target: LatLng(35.692558, 139.699530),
          ),
        ),
      ),
    );
  }

結果

最低限表示はされた。
image.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む