- 投稿日:2020-04-21T21:43:04+09:00
[iOS] Firebase + fastlaneでdSYMアップロード
始めに
最近、dSYMのアップロードがFirebaseのコンソールからはできなくなっており、コマンドラインからしか受け付けなくなっていた。
なので、AppStoreからダウンロード・Firebaseにアップロードをfastlaneで自動化した。目次
- 前提
- fastlaneをインストールと初期化
- Appfileをセットアップ
- Fastfileを編集
- 実行してみる
前提
- 基本的なXcodeとiOSの知識がある
- Terminalの操作ができる
- FirebaseでCrashlyticsの設定まで完了している
- BitcodeをOnにする
- AppStoreConnectにアプリをアップロードしたことがある
- アップロードできる権限がある
fastlaneのインストールと初期化
Homebrewインストールがおすすめです。
$ brew install fastlaneその後、プロジェクトの場所まで移動し、以下のコマンドを実行する
$ fastlane initfastlaneの初期化方法を選択する
1. ? Automate screenshots 2. ?✈️ Automate beta distribution to TestFlight 3. ? Automate App Store distribution 4. ? Manual setup - manually setup your project to automate your tasks自分の場合は、dSYMアップロードだけだったので、「4」を選択。
以下の2つのファイルが生成される。fastlane/Appfile fastlane/FastfileAppfileをセットアップ
Appfileでプロジェクトやアカウントの設定を行う。
Appfileapp_identifier("[bundle identifier]") # アプリのバンドルID apple_id("sample@example.com") # Apple ID team_id("[team ID]") itc_team_id("[appstoreconnect ID]")team_id
Developer Portalから取得
itc_team_id
AppStoreConnectにログイン後、以下のURLからJSONを確認する。
https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/ra/user/detail
この中のcontentProviderId
の値。
取得方法はこちらを参照した。Fastfileを編集
最小限の実装は以下のとおり
default_platform(:ios) platform :ios do desc "Description of what the lane does" lane :dsym do download_dsyms(version: 'latest') upload_symbols_to_crashlytics(gsp_path: "[path to GoogleService-Info.plist]") clean_build_artifacts end endgsp_path
GoogleService-Info.plistへのパス
実行してみる
$ fastlane dsymAppStoreConnectにログインするので、最初はパスワードを聞かれる。セッションが保存されるので、次回からはパスワードは聞かれない。
参考
https://qiita.com/giiiita/items/333af46cade134883c83
https://docs.fastlane.tools/getting-started/ios/setup/
https://docs.fastlane.tools/advanced/Appfile/
https://docs.fastlane.tools/actions/download_dsyms/
https://docs.fastlane.tools/actions/upload_symbols_to_crashlytics/
https://github.com/fastlane/fastlane/issues/4301#issuecomment-253461017
https://firebase.google.com/docs/crashlytics/get-started?hl=ja
- 投稿日:2020-04-21T11:59:56+09:00
Flutter環境構築 - 4(VSCodeセットアップ編)
はじめに
今回はFlutter環境構築第4弾 「VSCodeセットアップ編」です!
Flutter SDKのインストール・Flutterコマンドのセットアップがお済みでない方は、
先に「Flutter SDKインストール編」をご覧ください。Flutter環境構築シリーズ
・Flutter環境構築 - 1(Flutter SDKインストール編)
・Flutter環境構築 - 2(Xcode・iOSシミュレーターセットアップ編)
・Flutter環境構築 - 3(Android Studio・Androidエミュレータセットアップ編)「VSCodeセットアップ編」でやること
本編では以下の項目を行います
- VSCodeのインストール
- VSCodeのセットアップ
VSCodeのインストール
1.VSCodeをインストールする
VSCode公式サイトへ行き、今すぐ無料でダウンロードするをクリックします。
ダウンロードが完了したら解凍し、VSCodeを起動します。
VSCodeのセットアップ
1.Flutterプラグインをインストールする
VSCodeが起動できたら、左タブのExtensionsをクリックします。
検索欄でFlutterと入力し、Flutterプラグインをインストールします。
2.Androidライセンスを承諾する
ターミナルにて以下を実行します。
flutter doctor —android-licensesyを複数回入力していき、ライセンス条項を承諾していきます。
3.flutter doctorを実行
ターミナルにて以下を実行します。
flutter doctor実行すると以下のように表示されます。
ここで、Connected device以外のものに全て✔︎(チェックマーク)が入っていたらセットアップ完了となります。
もし!(ビックリマーク)がついているものがありましたら、そこに記述されている内容通りに行い、再度flutter doctorを実行してください。
最後に
以上で「VSCodeセットアップ編」は終了となります。お疲れ様でした。
また、これにてFlutter環境構築シリーズは終了となります。
最後までご覧くださりありがとうございました。
Flutter環境構築シリーズ
・Flutter環境構築 - 1(Flutter SDKインストール編)
・Flutter環境構築 - 2(Xcode・iOSシミュレーターセットアップ編)
・Flutter環境構築 - 3(Android Studio・Androidエミュレータセットアップ編)参考サイト[Flutter公式サイト]
- 投稿日:2020-04-21T11:39:01+09:00
AppleWatchでログが出ないことがあるので、iPhoneに投げつけて無理やり表示
困ったこと
- AppleWatchアプリを開発している
- なんかAppleWatchのログがでない
- ログが出る人もいれば出ない人もいる現象??
もういいやiPhoneに投げつけよう
- WatchConnectivityのメッセージ送信でログ送信を作る
Watch側.swiftWCSession.default.sendMessage(["show_log": log], replyHandler: { _ in }) { _ in }iOS側.swiftfunc session(_ session: WCSession, didReceiveMessage message: [String: Any], replyHandler: @escaping ([String: Any]) -> Void) { guard let key = message.keys.first else { return } switch key { case "show_log": print(message[key]) case "その他いろいろ受け取るでしょうきっと"あわせてどうぞ
- 投稿日:2020-04-21T11:30:19+09:00
AppleWatchアプリをXcodeGenで構築した
AppleWatchアプリをXcodeGenで構築したので、project.ymlを大雑把に置いておきます
困ったこと
- AppleWatchでのXcodeGenの文献が少なかった
開発環境と構成
- Xcode11.X~
- 構成
- iOSAppTarget
- WatchKit App
- WatchKit Extension
- iOS13.X
- WatchOS6.X
- ツール系
- Mint: 0.13.0(Mintfile)
- XcodeGen: 2.15.1(project.yml)
- SwiftPM
- SwiftPMに対応しているライブラリがあれば優先的に
- SwiftLint: 0.39.2
- Carthage: 0.34.0(Cartfile)
- SwiftPMに対応してないが、Carthageに対応しているライブラリがあれば優先的に
- Bundler: 2.1.3(Gemfile)
- Cocoapods: 1.9.1(Podfile)
- SwiftPMにもCarthageにも対応してないライブラリ(Firebaseとか)
- Fastlane: 2.144.0(Fastfile)
- いろいろ
XcodeGenはMintで管理
- Mintを使って XcodeGen / SwiftLint / Carthage のバージョンを管理しました
- ライブラリはなるべくSwiftPMに対応していればそれを優先的に利用し、Carthage->CocoaPodsの順で優先度を割り振りました
XcodeGenのproject.yml
project.ymlattributes: LastSwiftUpdateCheck: 1130 LastUpgradeCheck: 1130 ORGANIZATIONNAME: inc.noplan settings: base: CURRENT_PROJECT_VERSION: 1 MARKETING_VERSION: "0.0.26" configs: Debug: debug Release: release name: [アプリ名] packages: Nuke: url: https://github.com/kean/Nuke.git from: 8.4.1 [SwiftPMで使用するライブラリたち] options: groupSortPosition: bottom transitivelyLinkDependencies: false settingGroups: Debug: ALWAYS_SEARCH_USER_PATHS: NO CLANG_ANALYZER_NONNULL: YES CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION: YES_AGGRESSIVE CLANG_CXX_LANGUAGE_STANDARD: gnu++14 CLANG_CXX_LIBRARY: libc++ CLANG_ENABLE_MODULES: YES CLANG_ENABLE_OBJC_ARC: YES CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING: YES CLANG_WARN_BOOL_CONVERSION: YES CLANG_WARN_COMMA: YES CLANG_WARN_CONSTANT_CONVERSION: YES CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS: YES CLANG_WARN_DIRECT_OBJC_ISA_USAGE: YES_ERROR CLANG_WARN_DOCUMENTATION_COMMENTS: YES CLANG_WARN_EMPTY_BODY: YES CLANG_WARN_ENUM_CONVERSION: YES CLANG_WARN_INFINITE_RECURSION: YES CLANG_WARN_INT_CONVERSION: YES CLANG_WARN_NON_LITERAL_NULL_CONVERSION: YES CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF: YES CLANG_WARN_OBJC_LITERAL_CONVERSION: YES CLANG_WARN_OBJC_ROOT_CLASS: YES_ERROR CLANG_WARN_RANGE_LOOP_ANALYSIS: YES CLANG_WARN_STRICT_PROTOTYPES: YES CLANG_WARN_SUSPICIOUS_MOVE: YES CLANG_WARN_UNGUARDED_AVAILABILITY: YES_AGGRESSIVE CLANG_WARN_UNREACHABLE_CODE: YES CLANG_WARN__DUPLICATE_METHOD_MATCH: YES COPY_PHASE_STRIP: NO DEBUG_INFORMATION_FORMAT: dwarf ENABLE_STRICT_OBJC_MSGSEND: YES ENABLE_TESTABILITY: YES GCC_C_LANGUAGE_STANDARD: gnu11 GCC_DYNAMIC_NO_PIC: NO GCC_NO_COMMON_BLOCKS: YES GCC_OPTIMIZATION_LEVEL: 0 GCC_PREPROCESSOR_DEFINITIONS: - $(inherited) - DEBUG=1 GCC_WARN_64_TO_32_BIT_CONVERSION: YES GCC_WARN_ABOUT_RETURN_TYPE: YES_ERROR GCC_WARN_UNDECLARED_SELECTOR: YES GCC_WARN_UNINITIALIZED_AUTOS: YES_AGGRESSIVE GCC_WARN_UNUSED_FUNCTION: YES GCC_WARN_UNUSED_VARIABLE: YES MTL_ENABLE_DEBUG_INFO: YES ONLY_ACTIVE_ARCH: YES PRODUCT_NAME: $(TARGET_NAME) SDKROOT: iphoneos SWIFT_ACTIVE_COMPILATION_CONDITIONS: DEBUG SWIFT_OPTIMIZATION_LEVEL: -Onone SWIFT_VERSION: 5.0 Staging: [割愛] Release: [割愛] schemes: \[scheme名]: build: targets: [iOSのターゲット名]: all run: config: Debug test: config: Debug profile: config: Debug analyze: config: Debug archive: config: Release \[いろいろiOSのscheme]: \[WatchOSのscheme名 WatchKit App]: build: targets: [WatchOSのターゲット名 WatchKit App]: all run: config: Debug test: config: Debug profile: config: Debug analyze: config: Debug archive: config: Release \[WatchOSのscheme名 WatchKit Extension]: build: targets: [WatchOSのターゲット名 WatchKit Extension]: all run: config: Debug test: config: Debug profile: config: Debug analyze: config: Debug archive: config: Release targets: \[iOSのターゲット名]: dependencies: - target: [WatchOSのターゲット WatchKit App] - {embed: false, framework: Pods_[iOSのターゲット].framework} - {embed: false, framework: StoreKit.framework} - package: SDWebImageSwiftUI - package: SwiftUIX - carthage: SwiftyStoreKit - carthage: SwiftDate - carthage: ObjectMapper platform: iOS postbuildScripts: - inputFiles: - ${PODS_PODFILE_DIR_PATH}/Podfile.lock - ${PODS_ROOT}/Manifest.lock name: '[CP] Check Pods Manifest.lock' outputFiles: - $(DERIVED_FILE_DIR)/Pods-[プロジェクト]-checkManifestLockResult.txt runOnlyWhenInstalling: false script: "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n" shell: /bin/sh showEnvVars: false - inputFileLists: - ${PODS_ROOT}/Target Support Files/Pods-{iOSのターゲット}/Pods-{iOSのターゲット}-frameworks-${CONFIGURATION}-input-files.xcfilelist name: '[CP] Embed Pods Frameworks' outputFileLists: - ${PODS_ROOT}/Target Support Files/Pods-{iOSのターゲット}/Pods-{iOSのターゲット}-frameworks-${CONFIGURATION}-output-files.xcfilelist runOnlyWhenInstalling: false script: '"${PODS_ROOT}/Target Support Files/Pods-{iOSのターゲット}/Pods-{iOSのターゲット}-frameworks.sh"' shell: /bin/sh showEnvVars: false prebuildScripts: - name: run swiftlint script: | if mint which swiftlint >/dev/null; then mint run swiftlint autocorrect --format mint run swiftlint else echo "warning: mint install swiftlint" fi - name: linence plist script: | ${PODS_ROOT}/LicensePlist/license-plist --output-path $PRODUCT_NAME/Settings.bundle --config-path $PRODUCT_NAME/license_plist.yml /usr/libexec/PlistBuddy -c "Set :PreferenceSpecifiers:2:DefaultValue ${MARKETING_VERSION}" "$PRODUCT_NAME/Settings.bundle/Root.plist" /usr/libexec/PlistBuddy -c "Set :PreferenceSpecifiers:3:DefaultValue ${CURRENT_PROJECT_VERSION}" "$PRODUCT_NAME/Settings.bundle/Root.plist" settings: configs: Debug: ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon CLANG_ENABLE_MODULES: YES CODE_SIGN_ENTITLEMENTS: [ENTITLEMENTSのpath].entitlements CODE_SIGN_IDENTITY: iPhone Developer CODE_SIGN_STYLE: Automatic DEVELOPMENT_ASSET_PATHS: '"[DEVELOPMENT_ASSETのpath]/Preview Content"' DEVELOPMENT_TEAM: [TEAMをどうぞ] ENABLE_PREVIEWS: YES FRAMEWORK_SEARCH_PATHS: - $(inherited) - '"."' INFOPLIST_FILE: [plistのpath]/Info.plist LD_RUNPATH_SEARCH_PATHS: - $(inherited) - '@executable_path/Frameworks' PRODUCT_BUNDLE_IDENTIFIER: [PRODUCTのBUNDLE_IDENTIFIER] PRODUCT_NAME: $(TARGET_NAME) SDKROOT: iphoneos SWIFT_OBJC_BRIDGING_HEADER: [Bridging-Headerのpath/Bridging-Header.h] SWIFT_OPTIMIZATION_LEVEL: -Onone SWIFT_VERSION: 5.0 TARGETED_DEVICE_FAMILY: 1,2 Staging: [割愛] Release: [割愛] sources: - [デフォルトだとtarget名がフォルダ名と同じになってる] - name: GoogleService-Info.plist path: GoogleService-Info.plist group: [ファイルはrootにあるけどまとめたいのでフォルダを指定する] type: application deploymentTarget: "13.0" attributes: SystemCapabilities: com.apple.Push: enabled: 1 com.apple.InAppPurchase: enabled: 1 \[WatchOSのプロジェクト WatchKit App]: dependencies: - target: [WatchOSのtarget名 WatchKit Extension] - {embed: false, framework: Pods_[プロジェクト]_WatchKit_App.framework} platform: watchOS postbuildScripts: - inputFiles: - ${PODS_PODFILE_DIR_PATH}/Podfile.lock - ${PODS_ROOT}/Manifest.lock name: '[CP] Check Pods Manifest.lock' outputFiles: - $(DERIVED_FILE_DIR)/Pods-[プロジェクト] WatchKit App-checkManifestLockResult.txt runOnlyWhenInstalling: false script: "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n" shell: /bin/sh showEnvVars: false settings: configs: Debug: ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES: YES ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon CODE_SIGN_STYLE: Automatic DEVELOPMENT_TEAM: [チーム] FRAMEWORK_SEARCH_PATHS: - $(inherited) - '"."' IBSC_MODULE: [IBSC_MODULE]_WatchKit_Extension INFOPLIST_FILE: [プロジェクト] WatchKit App/Info.plist LD_RUNPATH_SEARCH_PATHS: - $(inherited) - '@executable_path/Frameworks' PRODUCT_BUNDLE_IDENTIFIER: [アプリのBUNDLE_IDENTIFIER].watchkitapp PRODUCT_NAME: $(TARGET_NAME) SDKROOT: watchos SKIP_INSTALL: YES SWIFT_VERSION: 5.0 TARGETED_DEVICE_FAMILY: 4 WATCHOS_DEPLOYMENT_TARGET: 6.1 Stating: [割愛] Release: [割愛] sources: - name: [デフォルトだとtarget名がフォルダ名と同じになってるやつ] WatchKit App type: application.watchapp2 deploymentTarget: "6.0" \[WatchOSのプロジェクト] WatchKit Extension: dependencies: - {embed: false, framework: Pods_[プロジェクト]_WatchKit_Extension.framework} - carthage: ObjectMapper - package: Nuke platform: watchOS postbuildScripts: - inputFiles: - ${PODS_PODFILE_DIR_PATH}/Podfile.lock - ${PODS_ROOT}/Manifest.lock name: '[CP] Check Pods Manifest.lock' outputFiles: - $(DERIVED_FILE_DIR)/Pods-[プロジェクト] WatchKit Extension-checkManifestLockResult.txt runOnlyWhenInstalling: false script: "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n" shell: /bin/sh showEnvVars: false settings: configs: Debug: ASSETCATALOG_COMPILER_COMPLICATION_NAME: Complication CODE_SIGN_STYLE: Automatic DEVELOPMENT_ASSET_PATHS: '"[プロジェクト] WatchKit Extension/Preview Content"' DEVELOPMENT_TEAM: 83GH78U9V5 ENABLE_PREVIEWS: YES FRAMEWORK_SEARCH_PATHS: - $(inherited) - '"."' INFOPLIST_FILE: [プロジェクト] WatchKit Extension/Info.plist LD_RUNPATH_SEARCH_PATHS: - $(inherited) - '@executable_path/Frameworks' - '@executable_path/../../Frameworks' PRODUCT_BUNDLE_IDENTIFIER: [アプリのBUNDLE_IDENTIFIER].watchkitapp.watchkitextension PRODUCT_NAME: ${TARGET_NAME} SDKROOT: watchos SKIP_INSTALL: YES SWIFT_VERSION: 5.0 TARGETED_DEVICE_FAMILY: 4 WATCHOS_DEPLOYMENT_TARGET: 6.1 Staging: [割愛] Release: [割愛] sources: - [デフォルトだとtarget名がフォルダ名と同じになってるやつ] WatchKit Extension - name: [iOSでもWatchOSでも使いたいファイル].swift path: [path/to/ファイルの所在地].swift group: [置いておきたいpath/to/DataModel] type: watchkit2-extension deploymentTarget: "6.0"あわせてどうぞ
- 投稿日:2020-04-21T10:25:31+09:00
AppleWatchアプリが更新されないかもしれない
- 投稿日:2020-04-21T05:54:19+09:00
Flutter未経験者が二週間でナイキラン系のアプリを開発してみて思ったこと
こちらの記事では、ざくっと未経験からFlutterをやっていく人に向けたメリット・デメリットを伝えられたらなと思います。
開発環境構築
以下を参考にさせて頂きました。(iosアプリのみの場合、android環境を構築せず制作できます)
・Flutter開発環境構築用いたライブラリ
・geolocator 5.1.3
・cloud_firestore: ^0.9.5つくったもの
タイムを測りながらGPSで距離測定をするストップウォッチ機能とfirebaseのデータベース(firestore)で記録をランキング化する機能があるアプリ
未経験でも、ある程度のアプリは開発できるのか?
結論から言いますと可能だと思います。
ゲームアプリを制作したいとかだと難しいと思いますが、ToDoアプリやSNS、タスク管理系のツールであればフロントエンド部分で細かい修正に時間がかかるかもしれませんが大方できると思います。バックエンド部分は、firebaseで開発すると学習コストは然程かかりませんし、flutterには何と言ってもホットリロードがあります。ホットリロードとは、コードを書き直せば即確認できる機能です(web制作に似た感じです)メリット
・簡単な個人開発アプリを制作する時には学習コストが少なくすむ。(仮にAndroidでも公開したいとなっても対応がしやすい)
・ホットリロード機能があるので、ビルドして毎回確認する必要性がない。(ネイティブと比べると、この点が嬉しい限りだと思います)
・割とライブラリが豊富(ネイティブ程ではないですが、こんなライブラリあるかなーと検索してみるとみつかるので、私はあまり困らなかった)デメリット
・日本語記事の少なさ(エラーがでたり、ライブラリの使い方を調べるときに英語記事を読む必要性があります)
・ARkitなど、ネイティブしかないライブラリを使いたい場合、諦めるしかないです。(なので、つくりたいアプリに必要な機能をflutterは満たしているのか確認する必要があります)
・xcodeのアップデートによってflutterのバージョンを上げる必要があった(ビルドができなくなったので焦りました汗)まとめ
個人開発をしたい方にはお勧めです。プログラマー実務未経験から就職・転職となると案件が少ないのでネイティブ上がりのプログラマーと競争する必要があるのかなと思いました。(実体験)
ざくっとFlutterについて書きましたが、あくまで個人的見解なので参考までに。
技術的なことやコードについては違う記事で詳しく書いておくとおもいますので、気になった方はチェックしてみてください。アプリ使ってくださると嬉しいです。