20200421のiOSに関する記事は6件です。

[iOS] Firebase + fastlaneでdSYMアップロード

始めに

最近、dSYMのアップロードがFirebaseのコンソールからはできなくなっており、コマンドラインからしか受け付けなくなっていた。
なので、AppStoreからダウンロード・Firebaseにアップロードをfastlaneで自動化した。

目次

  1. 前提
  2. fastlaneをインストールと初期化
  3. Appfileをセットアップ
  4. Fastfileを編集
  5. 実行してみる

前提

fastlaneのインストールと初期化

公式

Homebrewインストールがおすすめです。

$ brew install fastlane

その後、プロジェクトの場所まで移動し、以下のコマンドを実行する

$ fastlane init

fastlaneの初期化方法を選択する

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

Appfileをセットアップ

Appfileでプロジェクトやアカウントの設定を行う。

Appfile
app_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
end

gsp_path

GoogleService-Info.plistへのパス

実行してみる

$ fastlane dsym

AppStoreConnectにログインするので、最初はパスワードを聞かれる。セッションが保存されるので、次回からはパスワードは聞かれない。

参考

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

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

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公式サイトへ行き、今すぐ無料でダウンロードするをクリックします。
スクリーンショット 2020-04-21 11.13.15.jpg

各自使用しているOSのものをダウンロードします。
スクリーンショット 2020-04-21 11.18.38.png

ダウンロードが完了したら解凍し、VSCodeを起動します。

VSCodeのセットアップ

1.Flutterプラグインをインストールする

VSCodeが起動できたら、左タブのExtensionsをクリックします。
スクリーンショット 2020-04-21 11.31.51.jpg

検索欄でFlutterと入力し、Flutterプラグインをインストールします。
スクリーンショット 2020-04-21 11.30.59.png

2.Androidライセンスを承諾する

ターミナルにて以下を実行します。

flutter doctor —android-licenses

yを複数回入力していき、ライセンス条項を承諾していきます。

3.flutter doctorを実行

ターミナルにて以下を実行します。

flutter doctor

実行すると以下のように表示されます。
ここで、Connected device以外のものに全て✔︎(チェックマーク)が入っていたらセットアップ完了となります。
もし!(ビックリマーク)がついているものがありましたら、そこに記述されている内容通りに行い、再度flutter doctorを実行してください。
スクリーンショット 2020-04-21 11.46.48.png

最後に

以上で「VSCodeセットアップ編」は終了となります。お疲れ様でした。

また、これにてFlutter環境構築シリーズは終了となります。

最後までご覧くださりありがとうございました。

Flutter環境構築シリーズ
Flutter環境構築 - 1(Flutter SDKインストール編)
Flutter環境構築 - 2(Xcode・iOSシミュレーターセットアップ編)
Flutter環境構築 - 3(Android Studio・Androidエミュレータセットアップ編)

参考サイト[Flutter公式サイト]

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

AppleWatchでログが出ないことがあるので、iPhoneに投げつけて無理やり表示

困ったこと

  • AppleWatchアプリを開発している
  • なんかAppleWatchのログがでない
  • ログが出る人もいれば出ない人もいる現象??

もういいやiPhoneに投げつけよう

  • WatchConnectivityのメッセージ送信でログ送信を作る
Watch側.swift
WCSession.default.sendMessage(["show_log": log], replyHandler: { _ in }) { _ in }
iOS側.swift
func 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 "その他いろいろ受け取るでしょうきっと"

あわせてどうぞ

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

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.yml
attributes:
  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"


あわせてどうぞ

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

AppleWatchアプリが更新されないかもしれない

困ったこと

  • XcodeでWatchOSアプリを開発していて、Runし直すけどなぜかWatchにコードが反映されないときがある
  • iPhoneアプリは更新されてるっぽいが、AppleWatchのアプリはアプリのインストールぐるぐるにならない

解決策

  • WatchKit AppのInterface.storyboardなどどこかUIを一部変更すると、AppleWatchアプリが更新される

再現環境

  • Xcode11.X~
  • 構成
    • iOSAppTarget
    • WatchKit App
    • WatchKit Extension
  • iOS13.X
  • WatchOS6.X

あわせてどうぞ

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

Flutter未経験者が二週間でナイキラン系のアプリを開発してみて思ったこと

こちらの記事では、ざくっと未経験からFlutterをやっていく人に向けたメリット・デメリットを伝えられたらなと思います。

開発環境構築

以下を参考にさせて頂きました。(iosアプリのみの場合、android環境を構築せず制作できます)
Flutter開発環境構築

用いたライブラリ

・geolocator 5.1.3
・cloud_firestore: ^0.9.5

つくったもの

スクリーンショット 2020-04-13 午後5.13.34 2.png スクリーンショット 2020-04-13 午後5.13.52 2.png

タイムを測りながらGPSで距離測定をするストップウォッチ機能とfirebaseのデータベース(firestore)で記録をランキング化する機能があるアプリ

未経験でも、ある程度のアプリは開発できるのか?

結論から言いますと可能だと思います。
ゲームアプリを制作したいとかだと難しいと思いますが、ToDoアプリやSNS、タスク管理系のツールであればフロントエンド部分で細かい修正に時間がかかるかもしれませんが大方できると思います。バックエンド部分は、firebaseで開発すると学習コストは然程かかりませんし、flutterには何と言ってもホットリロードがあります。ホットリロードとは、コードを書き直せば即確認できる機能です(web制作に似た感じです)

メリット

・簡単な個人開発アプリを制作する時には学習コストが少なくすむ。(仮にAndroidでも公開したいとなっても対応がしやすい)
・ホットリロード機能があるので、ビルドして毎回確認する必要性がない。(ネイティブと比べると、この点が嬉しい限りだと思います)
・割とライブラリが豊富(ネイティブ程ではないですが、こんなライブラリあるかなーと検索してみるとみつかるので、私はあまり困らなかった)

デメリット

・日本語記事の少なさ(エラーがでたり、ライブラリの使い方を調べるときに英語記事を読む必要性があります)
・ARkitなど、ネイティブしかないライブラリを使いたい場合、諦めるしかないです。(なので、つくりたいアプリに必要な機能をflutterは満たしているのか確認する必要があります)
・xcodeのアップデートによってflutterのバージョンを上げる必要があった(ビルドができなくなったので焦りました汗)

まとめ

個人開発をしたい方にはお勧めです。プログラマー実務未経験から就職・転職となると案件が少ないのでネイティブ上がりのプログラマーと競争する必要があるのかなと思いました。(実体験)
ざくっとFlutterについて書きましたが、あくまで個人的見解なので参考までに。
技術的なことやコードについては違う記事で詳しく書いておくとおもいますので、気になった方はチェックしてみてください。

アプリ使ってくださると嬉しいです。

競い合いランニングアプリ RUNKING

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