diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f1152ad2..a6494050 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,7 +21,7 @@ on: - Rambafile env: - DEVELOPER_DIR: /Applications/Xcode_12.1.app + DEVELOPER_DIR: /Applications/Xcode_12.3.app jobs: test: @@ -29,7 +29,6 @@ jobs: env: MINT_PATH: mint/lib MINT_LINK_PATH: mint/bin - XCODE_XCCONFIG_FILE: Configs/Carthage.xcconfig steps: # チェックアウト @@ -69,42 +68,72 @@ jobs: restore-keys: | ${{ runner.os }}-mint- - # Carthageで管理しているライブラリのキャッシュ - - name: Cache Carthage packages - uses: actions/cache@v2 - with: - path: Carthage - key: ${{ runner.os }}-carthage-${{ hashFiles('**/Cartfile.resolved') }} - restore-keys: | - ${{ runner.os }}-carthage- - - # Carthageで管理しているライブラリのインストール - - name: Install Carthage frameworks - run: make install-carthage - env: - GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # ライセンス情報の生成、プロジェクトファイルの生成 + - name: Generate licenses and Xcode project + run: make generate-licenses - # CocoaPodsで管理しているライブラリのキャッシュ - - name: Cache Pods + # SwiftPMで管理しているライブラリのキャッシュ + - name: Cache SwiftPM packages uses: actions/cache@v2 with: - path: Pods - key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }} + path: SourcePackages + key: ${{ runner.os }}-swiftpm-${{ hashFiles('**/UhooiPicBook.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved') }} restore-keys: | - ${{ runner.os }}-pods- - - # ライセンス情報の生成、プロジェクトファイルの生成、CocoaPodsで管理しているライブラリのインストール - - name: Generate licenses, Xcode project, and install Pods - run: make generate-licenses + ${{ runner.os }}-swiftpm- # ビルド - name: Xcode build run: make build-debug + # ビルドログのアップロード + - name: Upload build log Artifact + uses: actions/upload-artifact@v2 + if: failure() + with: + name: xcodebuild-logs + path: xcodebuild_build.log + if-no-files-found: ignore + retention-days: 14 + # 単体テストの実行 - name: Xcode test run: make test + # 単体テストログのアップロード + - name: Upload test log Artifact + uses: actions/upload-artifact@v2 + if: failure() + with: + name: xcodebuild-logs + path: xcodebuild_test.log + if-no-files-found: ignore + retention-days: 14 + + # コードカバレッジをHTML形式で取得 + - name: Get code coverage for HTML + run: make get-coverage-html + + # テスト結果とコードカバレッジのアップロード + - name: Upload test results and code coverage Artifact + uses: actions/upload-artifact@v2 + with: + name: results + path: | + build/reports/**/* + html_report/**/* + if-no-files-found: warn + retention-days: 14 + + # コードカバレッジをCobertura形式で取得 + - name: Get code coverage for Cobertura + run: make get-coverage-cobertura + + # コードカバレッジをCodecovへアップロード + - name: Upload code coverage to Codecov + run: make upload-coverage + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + info: runs-on: macOS-latest @@ -119,4 +148,3 @@ jobs: # 端末の一覧出力 - name: Show devices run: make show-devices - diff --git a/.github/workflows/swiftlint.yml b/.github/workflows/swiftlint.yml index a06078cb..e7b086b0 100644 --- a/.github/workflows/swiftlint.yml +++ b/.github/workflows/swiftlint.yml @@ -2,8 +2,6 @@ name: SwiftLint on: pull_request: - branches: - - develop paths: - '.github/workflows/swiftlint.yml' - '.swiftlint.yml' @@ -15,5 +13,5 @@ jobs: steps: - uses: actions/checkout@v2 - name: GitHub Action for SwiftLint - uses: norio-nomura/action-swiftlint@3.1.0 + uses: norio-nomura/action-swiftlint@3.2.1 diff --git a/.gitignore b/.gitignore index 1a6eadf2..c232a523 100644 --- a/.gitignore +++ b/.gitignore @@ -103,3 +103,14 @@ com.mono0926.LicensePlist.plist # GoogleService-Info.plist +xcodebuild_*.log + +# SwiftLint Remote Config Cache +.swiftlint/RemoteConfigCache + +# Slather +xml_report/ +html_report/ + +SourcePackages/ + diff --git a/.iblinter.yml b/.iblinter.yml new file mode 100644 index 00000000..ddf0e051 --- /dev/null +++ b/.iblinter.yml @@ -0,0 +1,30 @@ +# デフォルト有効で無効にするルール +disabled_rules: + #- enable_autolayout + #- duplicate_constraint + #- duplicate_id + #- custom_module + #- ambiguous + +# デフォルト無効で有効にするルール +enabled_rules: + #- custom_class_name # ファイル名は末尾の `ViewController` を省略したいため + - relative_to_margin + - misplaced + #- storyboard_viewcontroller_id # IDは末尾の `ViewController` を省略したいため + - stackview_backgroundcolor + - image_resources + - use_base_class + - view_as_device + - reuse_identifier + - color_resources + - use_trait_collections + +# 対象外のファイル・フォルダ +excluded: + - SourcePackages + - Generated + +view_as_device_rule: + device_id: retina6_1 # iPhone 11 + diff --git a/.slather.yml b/.slather.yml new file mode 100644 index 00000000..c4cf51e2 --- /dev/null +++ b/.slather.yml @@ -0,0 +1,16 @@ +coverage_service: cobertura_xml +xcodeproj: UhooiPicBook.xcodeproj +scheme: UhooiPicBook +source_directory: UhooiPicBook +output_directory: xml_report +ignore: + - SourcePackages/* + - "**/AppDelegate.swift" + - "**/SceneDelegate.swift" + - "**/Generated/*" + - "**/Util/Debug.swift" + - "**/Extensions/UIKit/*" + - "**/UIParts/*" + - "**/Views/*" + - "**/Routers/*" + diff --git a/.swiftlint.yml b/.swiftlint.yml index 7b972476..2c5be7b5 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -1,210 +1,14 @@ -# デフォルト有効で無効にするルール -disabled_rules: - #- block_based_kvo - #- class_delegate_protocol - #- closing_brace - #- closure_parameter_position - #- colon - #- comma - #- compiler_protocol_init - #- control_statement - #- custom_rules - #- cyclomatic_complexity - #- deployment_target - #- discarded_notification_center_observer - #- discouraged_direct_init - #- duplicate_enum_cases - #- duplicate_imports - #- dynamic_inline - #- empty_enum_arguments - #- empty_parameters - #- empty_parentheses_with_trailing_closure - #- file_length - #- for_where - #- force_cast - #- force_try - #- function_body_length - #- function_parameter_count - #- generic_type_name - #- identifier_name - #- implicit_getter - #- inert_defer - #- is_disjoint - #- large_tuple - #- leading_whitespace - #- legacy_cggeometry_functions - #- legacy_constant - #- legacy_constructor - #- legacy_hashing - #- legacy_nsgeometry_functions - #- line_length - #- mark - #- multiple_closures_with_trailing_closure - #- nesting - #- no_fallthrough_only - #- no_space_in_method_call - #- notification_center_detachment - #- nsobject_prefer_isequal - #- opening_brace - #- operator_whitespace - #- private_over_fileprivate - #- private_unit_test - #- protocol_property_accessors_order - #- reduce_boolean - #- redundant_discardable_let - #- redundant_objc_attribute - #- redundant_optional_initialization - #- redundant_set_access_control - #- redundant_string_enum_value - #- redundant_void_return - #- return_arrow_whitespace - #- shorthand_operator - #- statement_position - #- superfluous_disable_command - #- switch_case_alignment - #- syntactic_sugar - #- todo - #- trailing_comma - #- trailing_newline - #- trailing_semicolon - #- trailing_whitespace - #- type_body_length - #- type_name - #- unneeded_break_in_switch - #- unused_capture_list - #- unused_closure_parameter - #- unused_control_flow_label - #- unused_enumerated - #- unused_optional_binding - #- unused_setter_value - #- valid_ibinspectable - #- vertical_parameter_alignment - #- vertical_whitespace - #- void_return - #- weak_computed_property - #- weak_delegate - #- xctfail_message +parent_config: https://raw.githubusercontent.com/uhooi/SwiftLint-Config/v1.0.0/uhooi-base-swiftlint-config.yml -# デフォルト無効で有効にするルール -opt_in_rules: - - anyobject_protocol - - array_init - - attributes - - closure_body_length - - closure_end_indentation - - closure_spacing - - collection_alignment - - conditional_returns_on_newline - - contains_over_filter_count - - contains_over_filter_is_empty - - contains_over_first_not_nil - - contains_over_range_nil_comparison - - convenience_type - #- discouraged_object_literal # オブジェクトリテラルを使いたいため - - discouraged_optional_boolean - - discouraged_optional_collection - - empty_collection_literal - - empty_count - - empty_string - - empty_xctest_method - #- expiring_todo # TODOコメントに有効期限を書かないため - #- explicit_acl # できる限りACLを省略したいため - #- explicit_enum_raw_value # ローバリューを省略することもあるため - - explicit_init - #- explicit_self # 関数は `self.` を付けずに呼び出したいため - #- explicit_top_level_acl # できる限りACLを省略したいため - #- explicit_type_interface # できる限り型推論したいため - #- extension_access_modifier # このルールの意味を理解していないため - - fallthrough - - fatal_error_message - #- file_header # このルールの意味を理解していないため - - file_name - - file_types_order - - first_where - - flatmap_over_map_reduce - - force_unwrapping - - function_default_parameter_at_end - - identical_operands - - implicit_return - #- implicitly_unwrapped_optional # VIPERで変数を `!` で定義したいため - - joined_default_parameter - - last_where - - legacy_multiple - - legacy_random - #- let_var_whitespace # 空白行を設けたくないこともあるため - - literal_expression_end_indentation - - lower_acl_than_parent - - missing_docs - - modifier_order - #- multiline_arguments # 引数は同じ行に2つ入れたいこともあるため - #- multiline_arguments_brackets # 括弧で行を増やしたくないため - #- multiline_function_chains # 関数の呼び出しは同じ行に2つ入れたいこともあるため - #- multiline_literal_brackets # 括弧で行を増やしたくないため - #- multiline_parameters # 引数は同じ行に2つ入れたいこともあるため - #- multiline_parameters_brackets # 括弧で行を増やしたくないため - - nimble_operator - #- no_extension_access_modifier # エクステンションにACLを設定したいことがあるため - #- no_grouping_extension - - nslocalizedstring_key - - nslocalizedstring_require_bundle - #- number_separator # 数字を `_` で区切りたくないため - #- object_literal # リテラルで生成したくないこともあるため - - operator_usage_whitespace - - overridden_super_call - - override_in_extension - - pattern_matching_keywords - #- prefixed_toplevel_constant # 定数のプリフィックスに `k` を付けたくないため - - private_action - - private_outlet - #- prohibited_interface_builder # ストーリーボードを使ってビューを生成したいため - - prohibited_super_call - - quick_discouraged_call - - quick_discouraged_focused_test - - quick_discouraged_pending_test - - raw_value_for_camel_cased_codable_enum - - reduce_into - - redundant_nil_coalescing - - redundant_type_annotation - #- required_deinit # できる限りデイニシャライザを省略したいため - - required_enum_case - - single_test_class - - sorted_first_last - #- sorted_imports # インポート文をアルファベット順以外に並び替えたいこともあるため - - static_operator - - strict_fileprivate - #- strong_iboutlet # `@IBOutlet` を `weak` で定義したいこともあるため - - switch_case_on_newline - - toggle_bool - - trailing_closure - - type_contents_order - - unavailable_function - - unneeded_parentheses_in_closure_argument - - unowned_variable_capture - - untyped_error_in_catch - - unused_declaration - - unused_import - - vertical_parameter_alignment_on_call - #- vertical_whitespace_between_cases # Switch文のケース間に空白行を設けたくないこともあるため - #- vertical_whitespace_closing_braces # 中括弧を閉じる前に空白行を設けたいことがあるため - #- vertical_whitespace_opening_braces # 中括弧を開く前に空白行を設けたいことがあるため - - xct_specific_matcher - - yoda_condition - -# 対象のファイル・フォルダ -# デフォルトからフォルダ名を変更していない場合、プロジェクト名と同名のフォルダを指定すればいい included: + - Shared - UhooiPicBook + - UhooiPicBookStickers + - UhooiPicBookWidgets + - UhooiPicBookWidgetsConfigurableIntent + #- UhooiPicBookTests + #- UhooiPicBookUITests -# 対象外のファイル・フォルダ excluded: - - Pods - UhooiPicBook/Generated -line_length: - warning: 300 - error: 500 - -identifier_name: - min_length: - warning: 1 # `r` `g` `b` などを使いたいため - diff --git a/Cartfile b/Cartfile deleted file mode 100644 index d987b093..00000000 --- a/Cartfile +++ /dev/null @@ -1,7 +0,0 @@ -binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseAnalyticsBinary.json" -binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseCrashlyticsBinary.json" -binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseFirestoreBinary.json" -binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseMessagingBinary.json" -binary "https://dl.google.com/dl/firebase/ios/carthage/FirebasePerformanceBinary.json" -binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseProtobufBinary.json" - diff --git a/Cartfile.resolved b/Cartfile.resolved deleted file mode 100644 index 7893e128..00000000 --- a/Cartfile.resolved +++ /dev/null @@ -1,6 +0,0 @@ -binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseAnalyticsBinary.json" "7.1.0" -binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseCrashlyticsBinary.json" "7.1.0" -binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseFirestoreBinary.json" "7.1.0" -binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseMessagingBinary.json" "7.1.0" -binary "https://dl.google.com/dl/firebase/ios/carthage/FirebasePerformanceBinary.json" "7.1.0" -binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseProtobufBinary.json" "7.1.0" diff --git a/Configs/Carthage.xcconfig b/Configs/Carthage.xcconfig deleted file mode 100644 index 4db1356d..00000000 --- a/Configs/Carthage.xcconfig +++ /dev/null @@ -1,12 +0,0 @@ -// -// Carthage.xcconfig -// UhooiPicBook -// -// Created by uhooi on 2020/09/25. -// - -// Configuration settings file format documentation can be found at: -// https://help.apple.com/xcode/#/dev745c5c974 - -EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64=arm64 arm64e armv7 armv7s armv6 armv8 -EXCLUDED_ARCHS=$(inherited) $(EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_$(EFFECTIVE_PLATFORM_SUFFIX)__NATIVE_ARCH_64_BIT_$(NATIVE_ARCH_64_BIT)) diff --git a/Docs/Screenshots/iPadPro3rdGen/iPadOS13_0/Light/ImagePopup_Japanese.png b/Docs/Screenshots/iPadPro3rdGen/iPadOS13_0/Light/ImagePopup_Japanese.png new file mode 100644 index 00000000..757fd971 Binary files /dev/null and b/Docs/Screenshots/iPadPro3rdGen/iPadOS13_0/Light/ImagePopup_Japanese.png differ diff --git a/Docs/Screenshots/iPadPro3rdGen/iPadOS13_0/Light/MonsterDetail_Japanese.png b/Docs/Screenshots/iPadPro3rdGen/iPadOS13_0/Light/MonsterDetail_Japanese.png new file mode 100644 index 00000000..47adad9d Binary files /dev/null and b/Docs/Screenshots/iPadPro3rdGen/iPadOS13_0/Light/MonsterDetail_Japanese.png differ diff --git a/Docs/Screenshots/iPadPro3rdGen/iPadOS13_0/Light/MonsterList.png b/Docs/Screenshots/iPadPro3rdGen/iPadOS13_0/Light/MonsterList.png new file mode 100644 index 00000000..ca475e22 Binary files /dev/null and b/Docs/Screenshots/iPadPro3rdGen/iPadOS13_0/Light/MonsterList.png differ diff --git a/Docs/Screenshots/iPadPro3rdGen/iPadOS13_0/Light/iMessage_Japanese.png b/Docs/Screenshots/iPadPro3rdGen/iPadOS13_0/Light/iMessage_Japanese.png new file mode 100644 index 00000000..90bb10ef Binary files /dev/null and b/Docs/Screenshots/iPadPro3rdGen/iPadOS13_0/Light/iMessage_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/Dark/Activity.png b/Docs/Screenshots/iPhone11ProMax/Dark/Activity.png deleted file mode 100644 index b3cf070b..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Dark/Activity.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/Dark/ImagePopup.png b/Docs/Screenshots/iPhone11ProMax/Dark/ImagePopup.png deleted file mode 100644 index ba59d5c2..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Dark/ImagePopup.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/Dark/MonsterDetail.png b/Docs/Screenshots/iPhone11ProMax/Dark/MonsterDetail.png deleted file mode 100644 index 371acce7..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Dark/MonsterDetail.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/Dark/MonsterList.png b/Docs/Screenshots/iPhone11ProMax/Dark/MonsterList.png deleted file mode 100644 index 166406ae..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Dark/MonsterList.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/Dark/Spotlight.png b/Docs/Screenshots/iPhone11ProMax/Dark/Spotlight.png deleted file mode 100644 index 45997425..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Dark/Spotlight.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/Dark/WidgetGallery_Medium_English.png b/Docs/Screenshots/iPhone11ProMax/Dark/WidgetGallery_Medium_English.png deleted file mode 100644 index 4fbe03b8..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Dark/WidgetGallery_Medium_English.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/Dark/WidgetGallery_Medium_Japanese.png b/Docs/Screenshots/iPhone11ProMax/Dark/WidgetGallery_Medium_Japanese.png deleted file mode 100644 index 335f2186..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Dark/WidgetGallery_Medium_Japanese.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/Dark/WidgetGallery_Small_English.png b/Docs/Screenshots/iPhone11ProMax/Dark/WidgetGallery_Small_English.png deleted file mode 100644 index c2b410c5..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Dark/WidgetGallery_Small_English.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/Dark/WidgetGallery_Small_Japanese.png b/Docs/Screenshots/iPhone11ProMax/Dark/WidgetGallery_Small_Japanese.png deleted file mode 100644 index 0c1583c0..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Dark/WidgetGallery_Small_Japanese.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/Dark/Widgets.png b/Docs/Screenshots/iPhone11ProMax/Dark/Widgets.png deleted file mode 100644 index 875edd04..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Dark/Widgets.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/Dark/iMessage.png b/Docs/Screenshots/iPhone11ProMax/Dark/iMessage.png deleted file mode 100644 index cbe75279..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Dark/iMessage.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/Light/Activity.png b/Docs/Screenshots/iPhone11ProMax/Light/Activity.png deleted file mode 100644 index 542bf324..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Light/Activity.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/Light/ImagePopup.png b/Docs/Screenshots/iPhone11ProMax/Light/ImagePopup.png deleted file mode 100644 index 14c2179a..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Light/ImagePopup.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/Light/MonsterDetail.png b/Docs/Screenshots/iPhone11ProMax/Light/MonsterDetail.png deleted file mode 100644 index fb0b064c..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Light/MonsterDetail.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/Light/MonsterList.png b/Docs/Screenshots/iPhone11ProMax/Light/MonsterList.png deleted file mode 100644 index 891c5183..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Light/MonsterList.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/Light/Spotlight.png b/Docs/Screenshots/iPhone11ProMax/Light/Spotlight.png deleted file mode 100644 index e829d395..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Light/Spotlight.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/Light/WidgetGallery_Medium_English.png b/Docs/Screenshots/iPhone11ProMax/Light/WidgetGallery_Medium_English.png deleted file mode 100644 index 76907b8f..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Light/WidgetGallery_Medium_English.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/Light/WidgetGallery_Medium_Japanese.png b/Docs/Screenshots/iPhone11ProMax/Light/WidgetGallery_Medium_Japanese.png deleted file mode 100644 index c221e56b..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Light/WidgetGallery_Medium_Japanese.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/Light/WidgetGallery_Small_English.png b/Docs/Screenshots/iPhone11ProMax/Light/WidgetGallery_Small_English.png deleted file mode 100644 index dbd29dfe..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Light/WidgetGallery_Small_English.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/Light/WidgetGallery_Small_Japanese.png b/Docs/Screenshots/iPhone11ProMax/Light/WidgetGallery_Small_Japanese.png deleted file mode 100644 index 85bd34dc..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Light/WidgetGallery_Small_Japanese.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/Light/Widgets.png b/Docs/Screenshots/iPhone11ProMax/Light/Widgets.png deleted file mode 100644 index f37e61e3..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Light/Widgets.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/Light/iMessage.png b/Docs/Screenshots/iPhone11ProMax/Light/iMessage.png deleted file mode 100644 index 18a50164..00000000 Binary files a/Docs/Screenshots/iPhone11ProMax/Light/iMessage.png and /dev/null differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/AboutThisApp_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/AboutThisApp_English.png new file mode 100644 index 00000000..d1ded6a2 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/AboutThisApp_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/AboutThisApp_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/AboutThisApp_Japanese.png new file mode 100644 index 00000000..933b9a9e Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/AboutThisApp_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/Activity_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/Activity_English.png new file mode 100644 index 00000000..129f4783 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/Activity_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/Activity_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/Activity_Japanese.png new file mode 100644 index 00000000..c9df5eea Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/Activity_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/AddingToYourPhotosAlert_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/AddingToYourPhotosAlert_English.png new file mode 100644 index 00000000..bb6d9d06 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/AddingToYourPhotosAlert_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/AddingToYourPhotosAlert_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/AddingToYourPhotosAlert_Japanese.png new file mode 100644 index 00000000..8c35c780 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/AddingToYourPhotosAlert_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/ContactUs_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/ContactUs_English.png new file mode 100644 index 00000000..83162093 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/ContactUs_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/ContactUs_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/ContactUs_Japanese.png new file mode 100644 index 00000000..5e15b950 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/ContactUs_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/ImagePopup_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/ImagePopup_English.png new file mode 100644 index 00000000..aa8c6bf8 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/ImagePopup_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/ImagePopup_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/ImagePopup_Japanese.png new file mode 100644 index 00000000..8ab697fd Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/ImagePopup_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/MenuOpenedInMonsterList_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/MenuOpenedInMonsterList_English.png new file mode 100644 index 00000000..862990ad Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/MenuOpenedInMonsterList_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/MenuOpenedInMonsterList_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/MenuOpenedInMonsterList_Japanese.png new file mode 100644 index 00000000..1c911e26 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/MenuOpenedInMonsterList_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/MonsterDetail_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/MonsterDetail_English.png new file mode 100644 index 00000000..ed292ddb Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/MonsterDetail_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/MonsterDetail_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/MonsterDetail_Japanese.png new file mode 100644 index 00000000..7969ae14 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/MonsterDetail_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/MonsterList.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/MonsterList.png new file mode 100644 index 00000000..3e54bfb0 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/MonsterList.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/SendingYouNotificationsAlert_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/SendingYouNotificationsAlert_English.png new file mode 100644 index 00000000..a3470470 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/SendingYouNotificationsAlert_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/SendingYouNotificationsAlert_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/SendingYouNotificationsAlert_Japanese.png new file mode 100644 index 00000000..ce47c629 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/SendingYouNotificationsAlert_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/Spotlight_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/Spotlight_English.png new file mode 100644 index 00000000..ed50b3f8 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/Spotlight_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/Spotlight_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/Spotlight_Japanese.png new file mode 100644 index 00000000..ff292e3d Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/Spotlight_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_MonsterConfigurable_Medium_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_MonsterConfigurable_Medium_English.png new file mode 100644 index 00000000..b25931d7 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_MonsterConfigurable_Medium_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_MonsterConfigurable_Medium_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_MonsterConfigurable_Medium_Japanese.png new file mode 100644 index 00000000..6dfaeef8 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_MonsterConfigurable_Medium_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_MonsterConfigurable_Small_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_MonsterConfigurable_Small_English.png new file mode 100644 index 00000000..503d46fb Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_MonsterConfigurable_Small_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_MonsterConfigurable_Small_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_MonsterConfigurable_Small_Japanese.png new file mode 100644 index 00000000..42dbcd59 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_MonsterConfigurable_Small_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_Monster_Medium_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_Monster_Medium_English.png new file mode 100644 index 00000000..abfd2c3f Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_Monster_Medium_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_Monster_Medium_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_Monster_Medium_Japanese.png new file mode 100644 index 00000000..a33ea1ae Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_Monster_Medium_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_Monster_Small_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_Monster_Small_English.png new file mode 100644 index 00000000..1156abf5 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_Monster_Small_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_Monster_Small_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_Monster_Small_Japanese.png new file mode 100644 index 00000000..1223c6e9 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/WidgetGallery_Monster_Small_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/Widgets_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/Widgets_English.png new file mode 100644 index 00000000..68cc1592 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/Widgets_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/Widgets_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/Widgets_Japanese.png new file mode 100644 index 00000000..c76cc78a Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/Widgets_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/iMessage_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/iMessage_English.png new file mode 100644 index 00000000..34e72afa Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/iMessage_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/iMessage_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/iMessage_Japanese.png new file mode 100644 index 00000000..14fa537e Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Dark/iMessage_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/AboutThisApp_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/AboutThisApp_English.png new file mode 100644 index 00000000..be2f505d Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/AboutThisApp_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/AboutThisApp_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/AboutThisApp_Japanese.png new file mode 100644 index 00000000..3dc30cfb Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/AboutThisApp_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/Activity_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/Activity_English.png new file mode 100644 index 00000000..bc1445d1 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/Activity_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/Activity_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/Activity_Japanese.png new file mode 100644 index 00000000..e753b04f Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/Activity_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/AddingToYourPhotosAlert_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/AddingToYourPhotosAlert_English.png new file mode 100644 index 00000000..02cba8fe Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/AddingToYourPhotosAlert_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/AddingToYourPhotosAlert_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/AddingToYourPhotosAlert_Japanese.png new file mode 100644 index 00000000..769815a8 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/AddingToYourPhotosAlert_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/ContactUs_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/ContactUs_English.png new file mode 100644 index 00000000..d872e5d1 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/ContactUs_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/ContactUs_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/ContactUs_Japanese.png new file mode 100644 index 00000000..b60bf572 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/ContactUs_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/ImagePopup_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/ImagePopup_English.png new file mode 100644 index 00000000..de5f6462 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/ImagePopup_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/ImagePopup_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/ImagePopup_Japanese.png new file mode 100644 index 00000000..c64b0f6e Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/ImagePopup_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/MenuOpenedInMonsterList_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/MenuOpenedInMonsterList_English.png new file mode 100644 index 00000000..e13254e6 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/MenuOpenedInMonsterList_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/MenuOpenedInMonsterList_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/MenuOpenedInMonsterList_Japanese.png new file mode 100644 index 00000000..d1ea3984 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/MenuOpenedInMonsterList_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/MonsterDetail_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/MonsterDetail_English.png new file mode 100644 index 00000000..7f6db6b3 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/MonsterDetail_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/MonsterDetail_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/MonsterDetail_Japanese.png new file mode 100644 index 00000000..d5688ad9 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/MonsterDetail_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/MonsterList.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/MonsterList.png new file mode 100644 index 00000000..f8179b0c Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/MonsterList.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/SendingYouNotificationsAlert_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/SendingYouNotificationsAlert_English.png new file mode 100644 index 00000000..fba047a7 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/SendingYouNotificationsAlert_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/SendingYouNotificationsAlert_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/SendingYouNotificationsAlert_Japanese.png new file mode 100644 index 00000000..80d030e0 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/SendingYouNotificationsAlert_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/Spotlight_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/Spotlight_English.png new file mode 100644 index 00000000..369f3dbc Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/Spotlight_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/Spotlight_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/Spotlight_Japanese.png new file mode 100644 index 00000000..1dfa2f09 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/Spotlight_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_MonsterConfigurable_Medium_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_MonsterConfigurable_Medium_English.png new file mode 100644 index 00000000..22c6c017 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_MonsterConfigurable_Medium_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_MonsterConfigurable_Medium_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_MonsterConfigurable_Medium_Japanese.png new file mode 100644 index 00000000..4c9c8f17 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_MonsterConfigurable_Medium_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_MonsterConfigurable_Small_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_MonsterConfigurable_Small_English.png new file mode 100644 index 00000000..8204ffe1 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_MonsterConfigurable_Small_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_MonsterConfigurable_Small_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_MonsterConfigurable_Small_Japanese.png new file mode 100644 index 00000000..e12e206a Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_MonsterConfigurable_Small_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_Monster_Medium_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_Monster_Medium_English.png new file mode 100644 index 00000000..18153517 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_Monster_Medium_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_Monster_Medium_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_Monster_Medium_Japanese.png new file mode 100644 index 00000000..8d5a77b6 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_Monster_Medium_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_Monster_Small_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_Monster_Small_English.png new file mode 100644 index 00000000..9e838309 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_Monster_Small_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_Monster_Small_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_Monster_Small_Japanese.png new file mode 100644 index 00000000..1c482744 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/WidgetGallery_Monster_Small_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/Widgets_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/Widgets_English.png new file mode 100644 index 00000000..51caab8e Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/Widgets_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/Widgets_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/Widgets_Japanese.png new file mode 100644 index 00000000..0891ab0c Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/Widgets_Japanese.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/iMessage_English.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/iMessage_English.png new file mode 100644 index 00000000..df3e3919 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/iMessage_English.png differ diff --git a/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/iMessage_Japanese.png b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/iMessage_Japanese.png new file mode 100644 index 00000000..b0576cc8 Binary files /dev/null and b/Docs/Screenshots/iPhone11ProMax/iOS14_3/Light/iMessage_Japanese.png differ diff --git a/Docs/Screenshots/iPhone8Plus/iOS14_3/Light/ImagePopup_Japanese.png b/Docs/Screenshots/iPhone8Plus/iOS14_3/Light/ImagePopup_Japanese.png new file mode 100644 index 00000000..ce191849 Binary files /dev/null and b/Docs/Screenshots/iPhone8Plus/iOS14_3/Light/ImagePopup_Japanese.png differ diff --git a/Docs/Screenshots/iPhone8Plus/iOS14_3/Light/MonsterDetail_Japanese.png b/Docs/Screenshots/iPhone8Plus/iOS14_3/Light/MonsterDetail_Japanese.png new file mode 100644 index 00000000..fadc015e Binary files /dev/null and b/Docs/Screenshots/iPhone8Plus/iOS14_3/Light/MonsterDetail_Japanese.png differ diff --git a/Docs/Screenshots/iPhone8Plus/iOS14_3/Light/MonsterList.png b/Docs/Screenshots/iPhone8Plus/iOS14_3/Light/MonsterList.png new file mode 100644 index 00000000..bd702453 Binary files /dev/null and b/Docs/Screenshots/iPhone8Plus/iOS14_3/Light/MonsterList.png differ diff --git a/Docs/Screenshots/iPhone8Plus/iOS14_3/Light/Widgets_Japanese.png b/Docs/Screenshots/iPhone8Plus/iOS14_3/Light/Widgets_Japanese.png new file mode 100644 index 00000000..b5c038f2 Binary files /dev/null and b/Docs/Screenshots/iPhone8Plus/iOS14_3/Light/Widgets_Japanese.png differ diff --git a/Docs/Screenshots/iPhone8Plus/iOS14_3/Light/iMessage_Japanese.png b/Docs/Screenshots/iPhone8Plus/iOS14_3/Light/iMessage_Japanese.png new file mode 100644 index 00000000..9683c865 Binary files /dev/null and b/Docs/Screenshots/iPhone8Plus/iOS14_3/Light/iMessage_Japanese.png differ diff --git a/Gemfile b/Gemfile index fb287124..5d53727e 100644 --- a/Gemfile +++ b/Gemfile @@ -5,6 +5,6 @@ source "https://rubygems.org" git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } gem "xcpretty" -gem "cocoapods" gem "generamba" +gem "slather" diff --git a/Gemfile.lock b/Gemfile.lock index 8f106f03..a0039f96 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -12,25 +12,7 @@ GEM json (>= 1.5.1) atomos (0.1.3) claide (1.0.3) - cocoapods (1.9.3) - activesupport (>= 4.0.2, < 5) - claide (>= 1.0.2, < 2.0) - cocoapods-core (= 1.9.3) - cocoapods-deintegrate (>= 1.0.3, < 2.0) - cocoapods-downloader (>= 1.2.2, < 2.0) - cocoapods-plugins (>= 1.0.0, < 2.0) - cocoapods-search (>= 1.0.0, < 2.0) - cocoapods-stats (>= 1.0.0, < 2.0) - cocoapods-trunk (>= 1.4.0, < 2.0) - cocoapods-try (>= 1.1.0, < 2.0) - colored2 (~> 3.1) - escape (~> 0.0.4) - fourflusher (>= 2.3.0, < 3.0) - gh_inspector (~> 1.0) - molinillo (~> 0.6.6) - nap (~> 1.0) - ruby-macho (~> 1.4) - xcodeproj (>= 1.14.0, < 2.0) + clamp (1.3.2) cocoapods-core (1.9.3) activesupport (>= 4.0.2, < 6) algoliasearch (~> 1.0) @@ -39,23 +21,11 @@ GEM nap (~> 1.0) netrc (~> 0.11) typhoeus (~> 1.0) - cocoapods-deintegrate (1.0.4) - cocoapods-downloader (1.4.0) - cocoapods-plugins (1.0.0) - nap - cocoapods-search (1.0.0) - cocoapods-stats (1.1.0) - cocoapods-trunk (1.5.0) - nap (>= 0.8, < 2.0) - netrc (~> 0.11) - cocoapods-try (1.2.0) colored2 (3.1.2) concurrent-ruby (1.1.7) - escape (0.0.4) ethon (0.12.0) ffi (>= 1.3.0) ffi (1.13.1) - fourflusher (2.3.1) fuzzy_match (2.0.4) generamba (1.5.0) cocoapods-core (>= 1.4.0, < 2.0.0) @@ -64,20 +34,28 @@ GEM terminal-table (= 1.4.5) thor (= 0.19.1) xcodeproj (>= 1.5.0, < 2.0.0) - gh_inspector (1.1.3) git (1.2.9.1) httpclient (2.8.3) i18n (0.9.5) concurrent-ruby (~> 1.0) json (2.3.1) liquid (4.0.0) + mini_portile2 (2.5.0) minitest (5.14.2) - molinillo (0.6.6) nanaimo (0.3.0) nap (1.1.0) netrc (0.11.0) + nokogiri (1.11.1) + mini_portile2 (~> 2.5.0) + racc (~> 1.4) + racc (1.5.2) rouge (2.0.7) - ruby-macho (1.4.0) + slather (2.6.1) + CFPropertyList (>= 2.2, < 4) + activesupport + clamp (~> 1.3) + nokogiri (~> 1.11) + xcodeproj (~> 1.7) terminal-table (1.4.5) thor (0.19.1) thread_safe (0.3.6) @@ -98,8 +76,8 @@ PLATFORMS ruby DEPENDENCIES - cocoapods generamba + slather xcpretty BUNDLED WITH diff --git a/LicensePlist/license_plist.yml b/LicensePlist/license_plist.yml deleted file mode 100644 index 1e093e60..00000000 --- a/LicensePlist/license_plist.yml +++ /dev/null @@ -1,8 +0,0 @@ -github: - - owner: firebase - name: firebase-ios-sdk - version: 7.1.0 - -rename: - firebase-ios-sdk: Firebase - diff --git a/Makefile b/Makefile index 63c4c8ce..769e1f8a 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # Variables PRODUCT_NAME := UhooiPicBook -WORKSPACE_NAME := ${PRODUCT_NAME}.xcworkspace +PROJECT_NAME := ${PRODUCT_NAME}.xcodeproj SCHEME_NAME := ${PRODUCT_NAME} UI_TESTS_TARGET_NAME := ${PRODUCT_NAME}UITests @@ -9,10 +9,13 @@ TEST_SDK := iphonesimulator TEST_CONFIGURATION := Debug TEST_PLATFORM := iOS Simulator TEST_DEVICE ?= iPhone 12 Pro Max -TEST_OS ?= 14.1 +TEST_OS ?= 14.3 TEST_DESTINATION := 'platform=${TEST_PLATFORM},name=${TEST_DEVICE},OS=${TEST_OS}' COVERAGE_OUTPUT := html_report +XCODEBUILD_BUILD_LOG_NAME := xcodebuild_build.log +XCODEBUILD_TEST_LOG_NAME := xcodebuild_test.log + MODULE_TEMPLATE_NAME ?= uhooi_viper .DEFAULT_GOAL := help @@ -25,16 +28,20 @@ help: .PHONY: setup setup: # Install dependencies and prepared development configuration + $(MAKE) install-ruby $(MAKE) install-bundler $(MAKE) install-templates $(MAKE) install-mint - $(MAKE) install-carthage $(MAKE) generate-licenses +.PHONY: install-ruby +install-ruby: # Install Ruby with rbenv + cat .ruby-version | xargs rbenv install --skip-existing + .PHONY: install-bundler install-bundler: # Install Bundler dependencies bundle config path vendor/bundle - bundle install --jobs 4 --retry 3 + bundle install --without=documentation --jobs 4 --retry 3 .PHONY: update-bundler update-bundler: # Update Bundler dependencies @@ -43,36 +50,7 @@ update-bundler: # Update Bundler dependencies .PHONY: install-mint install-mint: # Install Mint dependencies - mint bootstrap - -.PHONY: install-cocoapods -install-cocoapods: # Install CocoaPods dependencies and generate workspace - bundle exec pod install - -.PHONY: update-cocoapods -update-cocoapods: # Update CocoaPods dependencies and generate workspace - bundle exec pod update - -.PHONY: install-carthage -install-carthage: # Install Carthage dependencies - @$(MAKE) export-carthage-config - mint run carthage carthage bootstrap --platform iOS --cache-builds - @$(MAKE) show-carthage-dependencies - -.PHONY: update-carthage -update-carthage: # Update Carthage dependencies - @$(MAKE) export-carthage-config - mint run carthage carthage update --platform iOS - @$(MAKE) show-carthage-dependencies - -.PHONY: show-carthage-dependencies -show-carthage-dependencies: - @echo '*** Resolved dependencies:' - @cat 'Cartfile.resolved' - -.PHONY: export-carthage-config -export-carthage-config: - export XCODE_XCCONFIG_FILE=Configs/Carthage.xcconfig + mint bootstrap --overwrite y .PHONY: install-templates install-templates: # Install Generamba templates @@ -80,7 +58,7 @@ install-templates: # Install Generamba templates .PHONY: generate-licenses generate-licenses: # Generate licenses with LicensePlist and regenerate project - mint run LicensePlist license-plist --output-path ${PRODUCT_NAME}/Settings.bundle --config-path LicensePlist/license_plist.yml --add-version-numbers + mint run LicensePlist license-plist --output-path ${PRODUCT_NAME}/Settings.bundle --add-version-numbers $(MAKE) generate-xcodeproj .PHONY: generate-module @@ -91,20 +69,22 @@ generate-module: # Generate module with Generamba and regenerate project # MODUL .PHONY: generate-xcodeproj generate-xcodeproj: # Generate project with XcodeGen mint run xcodegen xcodegen generate - $(MAKE) install-cocoapods $(MAKE) open .PHONY: open -open: # Open workspace in Xcode - open ./${WORKSPACE_NAME} +open: # Open project in Xcode + open ./${PROJECT_NAME} .PHONY: clean clean: # Delete cache - xcodebuild clean -alltargets - rm -rf ./Pods - rm -rf ./Carthage rm -rf ./vendor/bundle rm -rf ./Templates + xcodebuild clean -alltargets + +.PHONY: analyze +analyze: # Analyze with SwiftLint + $(MAKE) build-debug + mint run swiftlint swiftlint analyze --autocorrect --compiler-log-path ./${XCODEBUILD_BUILD_LOG_NAME} .PHONY: build-debug build-debug: # Xcode build for debug @@ -112,10 +92,13 @@ build-debug: # Xcode build for debug && xcodebuild \ -sdk ${TEST_SDK} \ -configuration ${TEST_CONFIGURATION} \ --workspace ${WORKSPACE_NAME} \ +-project ${PROJECT_NAME} \ -scheme ${SCHEME_NAME} \ +-destination ${TEST_DESTINATION} \ +-clonedSourcePackagesDirPath './SourcePackages' \ build \ -| bundle exec xcpretty +| tee ./${XCODEBUILD_BUILD_LOG_NAME} \ +| bundle exec xcpretty --color .PHONY: test test: # Xcode test # TEST_DEVICE=[device] TEST_OS=[OS] @@ -123,17 +106,27 @@ test: # Xcode test # TEST_DEVICE=[device] TEST_OS=[OS] && xcodebuild \ -sdk ${TEST_SDK} \ -configuration ${TEST_CONFIGURATION} \ --workspace ${WORKSPACE_NAME} \ +-project ${PROJECT_NAME} \ -scheme ${SCHEME_NAME} \ -destination ${TEST_DESTINATION} \ -skip-testing:${UI_TESTS_TARGET_NAME} \ +-clonedSourcePackagesDirPath './SourcePackages' \ clean test \ -| bundle exec xcpretty --report html +| tee ./${XCODEBUILD_TEST_LOG_NAME} \ +| bundle exec xcpretty --color --report html -.PHONY: get-coverage -get-coverage: # Get code coverage +.PHONY: get-coverage-html +get-coverage-html: # Get code coverage for HTML bundle exec slather coverage --html --output-directory ${COVERAGE_OUTPUT} +.PHONY: get-coverage-cobertura +get-coverage-cobertura: # Get code coverage for Cobertura + bundle exec slather + +.PHONY: upload-coverage +upload-coverage: # Upload code coverage to Codecov + bash -c "bash <(curl -s https://codecov.io/bash) -f xml_report/cobertura.xml -X coveragepy -X gcov -X xcode" + .PHONY: show-devices show-devices: # Show devices xcrun xctrace list devices diff --git a/Mintfile b/Mintfile index e93582b2..52376453 100644 --- a/Mintfile +++ b/Mintfile @@ -1,7 +1,8 @@ -Carthage/Carthage@0.36.0 yonaskolb/xcodegen@2.18.0 -realm/SwiftLint@0.40.3 +realm/SwiftLint@0.42.0 +IBDecodable/IBLinter@0.4.25 fromkk/SpellChecker@0.0.3 uber/mockolo@1.2.8 mono0926/LicensePlist@2.16.0 +mac-cain13/R.swift@v5.3.0 diff --git a/Podfile b/Podfile deleted file mode 100644 index 4b981ebd..00000000 --- a/Podfile +++ /dev/null @@ -1,31 +0,0 @@ -# Uncomment the next line to define a global platform for your project -platform :ios, '13.0' - -target 'UhooiPicBook' do - # Comment the next line if you don't want to use dynamic frameworks - use_frameworks! - - # Pods for UhooiPicBook - pod 'R.swift' - pod 'Gedatsu', configuration: %w(Debug) - pod 'SwiftPrettyPrint', configuration: %w(Debug) - - target 'UhooiPicBookTests' do - inherit! :search_paths - # Pods for testing - end - - target 'UhooiPicBookUITests' do - # Pods for testing - end - -end - -post_install do |installer| - installer.pods_project.targets.each do |target| - target.build_configurations.each do |config| - config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0' - end - end -end - diff --git a/Podfile.lock b/Podfile.lock deleted file mode 100644 index a82e1f83..00000000 --- a/Podfile.lock +++ /dev/null @@ -1,28 +0,0 @@ -PODS: - - Gedatsu (1.2.0) - - R.swift (5.2.2): - - R.swift.Library (~> 5.2.0) - - R.swift.Library (5.2.0) - - SwiftPrettyPrint (1.0.0) - -DEPENDENCIES: - - Gedatsu - - R.swift - - SwiftPrettyPrint - -SPEC REPOS: - trunk: - - Gedatsu - - R.swift - - R.swift.Library - - SwiftPrettyPrint - -SPEC CHECKSUMS: - Gedatsu: 13a21a3cbf7978f9ff671eca5715b94a4309d9a8 - R.swift: 7c52cdc57a66840ffe6cbd8a823d732059d42a32 - R.swift.Library: 5ba4f1631300caf9a4d890186930da85d540769d - SwiftPrettyPrint: 02010eb68c416300eb9d0d0dccafa82b5856466a - -PODFILE CHECKSUM: f92e6c357c9b893d9426f0541709ddda78acbb01 - -COCOAPODS: 1.9.3 diff --git a/README.md b/README.md index 2f4f7e9a..ca50dda2 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,14 @@ # UhooiPicBook-iOS -[![](https://github.com/uhooi/UhooiPicBook/workflows/CI/badge.svg)](https://github.com/uhooi/UhooiPicBook/actions?query=workflow%3ACI) +[![Release](https://img.shields.io/github/v/release/uhooi/UhooiPicBook)](https://github.com/uhooi/UhooiPicBook/releases/latest) [![License](https://img.shields.io/github/license/uhooi/UhooiPicBook)](https://github.com/uhooi/UhooiPicBook/blob/master/LICENSE) -[![Twitter](https://img.shields.io/twitter/url?style=social&url=https%3A%2F%2Ftwitter.com%2Fthe_uhooi)](https://twitter.com/the_uhooi) +[![Platform](https://img.shields.io/badge/platform-iOS-lightgrey)](https://github.com/uhooi/UhooiPicBook) +[![Twitter](https://img.shields.io/twitter/follow/the_uhooi?style=social)](https://twitter.com/the_uhooi) + +|Branch|CI|Code coverage| +|:--|:--|:--| +|[master](https://github.com/uhooi/UhooiPicBook/tree/master)|[![CI](https://github.com/uhooi/UhooiPicBook/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/uhooi/UhooiPicBook/actions/workflows/main.yml)|[![codecov](https://codecov.io/gh/uhooi/UhooiPicBook/branch/master/graph/badge.svg?token=4HTK2YK2FG)](https://codecov.io/gh/uhooi/UhooiPicBook)| +|[develop](https://github.com/uhooi/UhooiPicBook/tree/develop)|[![CI](https://github.com/uhooi/UhooiPicBook/actions/workflows/main.yml/badge.svg?branch=develop)](https://github.com/uhooi/UhooiPicBook/actions/workflows/main.yml)|[![codecov](https://codecov.io/gh/uhooi/UhooiPicBook/branch/develop/graph/badge.svg?token=4HTK2YK2FG)](https://codecov.io/gh/uhooi/UhooiPicBook)| ![Logo](./Docs/Logo.png) @@ -16,41 +22,34 @@ UhooiPicBook-iOS is Uhooi's character book for iOS. |MonsterList|MonsterDetail|ImagePopup| |:--|:--|:--| -|||| +|||| -|Activity|Spotlight|iMessage| +|Menu opened in MonsterList|Spotlight|iMessage| |:--|:--|:--| -|||| +|||| |Widgets| |:--| -|| +|| ### Dark |MonsterList|MonsterDetail|ImagePopup| |:--|:--|:--| -|||| +|||| -|Activity|Spotlight|iMessage| +|Menu opened in MonsterList|Spotlight|iMessage| |:--|:--|:--| -|||| +|||| |Widgets| |:--| -|| +|| ## Development You can develop UhooiPicBook-iOS. -### Environment - -- Xcode: 12.1 -- Swift: 5.3 -- Bundler: 2.1.4 -- Mint: 0.14.2 - ### Configuration - UI implementation: Storyboard + XIB @@ -60,7 +59,12 @@ You can develop UhooiPicBook-iOS. ### Setup -1. Install [Bundler](https://github.com/rubygems/bundler) and [Mint](https://github.com/yonaskolb/Mint) . +1. Install the following tools. + +- [Xcode](https://apps.apple.com/jp/app/xcode/id497799835): 12.3 +- [rbenv](https://github.com/rbenv/rbenv): 1.1.2 +- [Bundler](https://github.com/rubygems/bundler): 2.1.4 +- [Mint](https://github.com/yonaskolb/Mint): 0.16.0 2. Clone the project. @@ -79,22 +83,22 @@ Run `make help` . ``` $ make help setup Install dependencies and prepared development configuration +install-ruby Install Ruby with rbenv install-bundler Install Bundler dependencies update-bundler Update Bundler dependencies install-mint Install Mint dependencies -install-cocoapods Install CocoaPods dependencies and generate workspace -update-cocoapods Update CocoaPods dependencies and generate workspace -install-carthage Install Carthage dependencies -update-carthage Update Carthage dependencies install-templates Install Generamba templates generate-licenses Generate licenses with LicensePlist and regenerate project generate-module MODULE_NAME=[module name] Generate module with Generamba and regenerate project generate-xcodeproj Generate project with XcodeGen -open Open workspace in Xcode +open Open project in Xcode clean Delete cache +analyze Analyze with SwiftLint build-debug Xcode build for debug test TEST_DEVICE=[device] TEST_OS=[OS] Xcode test -get-coverage Get code coverage +get-coverage-html Get code coverage for HTML +get-coverage-cobertura Get code coverage for Cobertura +upload-coverage Upload code coverage to Codecov show-devices Show devices ``` diff --git a/Rambafile b/Rambafile index 25fcf56c..ecc55d83 100644 --- a/Rambafile +++ b/Rambafile @@ -25,10 +25,6 @@ test_file_path: ./UhooiPicBookTests/Modules # The Xcode group path to new tests test_group_path: ./UhooiPicBookTests/Modules -### Dependencies settings section -podfile_path: Podfile -cartfile_path: Cartfile - ### Templates catalogs: - 'https://github.com/uhooi/generamba-catalog' diff --git a/Scripts/FirebaseCrashlytics/run b/Scripts/FirebaseCrashlytics/run deleted file mode 100755 index 9316eeaf..00000000 --- a/Scripts/FirebaseCrashlytics/run +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/sh - -# Copyright 2019 Google -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# run -# -# This script is meant to be run as a Run Script in the "Build Phases" section -# of your Xcode project. It sends debug symbols to symbolicate stacktraces, -# sends build events to track versions, and onboards apps for Crashlytics. -# -# This script calls upload-symbols twice: -# -# 1) First it calls upload-symbols synchronously in "validation" mode. If the -# script finds issues with the build environment, it will report errors to Xcode. -# In validation mode it exits before doing any time consuming work. -# -# 2) Then it calls upload-symbols in the background to actually send the build -# event and upload symbols. It does this in the background so that it doesn't -# slow down your builds. If an error happens here, you won't see it in Xcode. -# -# You can find the output for the background execution in Console.app, by -# searching for "upload-symbols". -# -# If you want verbose output, you can pass the --debug flag to this script -# - -# Figure out where we're being called from -DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) - -# If the first argument is specified without a dash, treat it as the Fabric API -# Key and add it as an argument. -if [ -z "$1" ] || [[ $1 == -* ]]; then - API_KEY_ARG="" -else - API_KEY_ARG="-a $1"; shift -fi - -# Build up the arguments list, passing through any flags added after the -# API Key -ARGUMENTS="$API_KEY_ARG $@" -VALIDATE_ARGUMENTS="$ARGUMENTS --build-phase --validate" -UPLOAD_ARGUMENTS="$ARGUMENTS --build-phase" - -# Quote the path to handle folders with special characters -COMMAND_PATH="\"$DIR/upload-symbols\" " - -# Ensure params are as expected, run in sync mode to validate, -# and cause a build error if validation fails -eval $COMMAND_PATH$VALIDATE_ARGUMENTS -return_code=$? - -if [[ $return_code != 0 ]]; then - exit $return_code -fi - -# Verification passed, convert and upload cSYMs in the background to prevent -# build delays -# -# Note: Validation is performed again at this step before upload -# -# Note: Output can still be found in Console.app, by searching for -# "upload-symbols" -# -eval $COMMAND_PATH$UPLOAD_ARGUMENTS > /dev/null 2>&1 & diff --git a/Scripts/FirebaseCrashlytics/upload-symbols b/Scripts/FirebaseCrashlytics/upload-symbols deleted file mode 100755 index 0a4ebc26..00000000 Binary files a/Scripts/FirebaseCrashlytics/upload-symbols and /dev/null differ diff --git a/Scripts/XcodeGen/iblinter.sh b/Scripts/XcodeGen/iblinter.sh new file mode 100644 index 00000000..cda55578 --- /dev/null +++ b/Scripts/XcodeGen/iblinter.sh @@ -0,0 +1,6 @@ +if which mint >/dev/null; then + xcrun --sdk macosx mint run IBDecodable/IBLinter iblinter lint +else + echo "warning: Mint not installed, download from https://github.com/yonaskolb/Mint" +fi + diff --git a/Scripts/XcodeGen/mockolo.sh b/Scripts/XcodeGen/mockolo.sh new file mode 100644 index 00000000..9706429b --- /dev/null +++ b/Scripts/XcodeGen/mockolo.sh @@ -0,0 +1,7 @@ +if which mint >/dev/null; then + rm -f $SRCROOT/$TARGET_NAME/Generated/MockResults.swift + xcrun --sdk macosx mint run uber/mockolo mockolo --sourcedirs $SRCROOT/$TARGET_NAME $SRCROOT/Shared --destination $SRCROOT/$TARGET_NAME/Generated/MockResults.swift --mock-final +else + echo "warning: Mint not installed, download from https://github.com/yonaskolb/Mint" +fi + diff --git a/Scripts/XcodeGen/rswift.sh b/Scripts/XcodeGen/rswift.sh new file mode 100644 index 00000000..e354d755 --- /dev/null +++ b/Scripts/XcodeGen/rswift.sh @@ -0,0 +1,6 @@ +if which mint >/dev/null; then + xcrun --sdk macosx mint run R.swift rswift generate "$SRCROOT/$TARGET_NAME/Generated/R.generated.swift" +else + echo "warning: Mint not installed, download from https://github.com/yonaskolb/Mint" +fi + diff --git a/Scripts/XcodeGen/spellchecker.sh b/Scripts/XcodeGen/spellchecker.sh new file mode 100644 index 00000000..f0a19e54 --- /dev/null +++ b/Scripts/XcodeGen/spellchecker.sh @@ -0,0 +1,20 @@ +if ! which mint >/dev/null; then + echo "warning: Mint not installed, download from https://github.com/yonaskolb/Mint" + exit 0 +fi + +git_path=/usr/local/bin/git +files=$($git_path diff --diff-filter=d --name-only -- "*.swift" "*.h" "*.m") +if (test -z $files) || (test ${#files[@]} -eq 0); then + echo "no files changed." + exit 0 +fi + +options="" +for file in $files +do + options="$options $SRCROOT/$file" +done + +xcrun --sdk macosx mint run SpellChecker SpellChecker --yml $SRCROOT/spell-checker.yml -- $options + diff --git a/Scripts/XcodeGen/swiftlint.sh b/Scripts/XcodeGen/swiftlint.sh new file mode 100644 index 00000000..50a8a2c0 --- /dev/null +++ b/Scripts/XcodeGen/swiftlint.sh @@ -0,0 +1,7 @@ +if which mint >/dev/null; then + xcrun --sdk macosx mint run swiftlint swiftlint autocorrect --format + xcrun --sdk macosx mint run swiftlint swiftlint +else + echo "warning: Mint not installed, download from https://github.com/yonaskolb/Mint" +fi + diff --git a/Shared/IntentDefinition/Base.lproj/WidgetsConfiguration.intentdefinition b/Shared/IntentDefinition/Base.lproj/WidgetsConfiguration.intentdefinition new file mode 100644 index 00000000..d7b9922b --- /dev/null +++ b/Shared/IntentDefinition/Base.lproj/WidgetsConfiguration.intentdefinition @@ -0,0 +1,261 @@ + + + + + INEnums + + INIntentDefinitionModelVersion + 1.2 + INIntentDefinitionNamespace + uWBxEI + INIntentDefinitionSystemVersion + 20B29 + INIntentDefinitionToolsBuildVersion + 12B45b + INIntentDefinitionToolsVersion + 12.2 + INIntents + + + INIntentCategory + information + INIntentConfigurable + + INIntentDescriptionID + FRyZSP + INIntentEligibleForWidgets + + INIntentIneligibleForSuggestions + + INIntentLastParameterTag + 12 + INIntentManagedParameterCombinations + + monster + + INIntentParameterCombinationSupportsBackgroundExecution + + INIntentParameterCombinationUpdatesLinked + + + + INIntentName + SelectMonster + INIntentParameters + + + INIntentParameterConfigurable + + INIntentParameterDisplayName + Monster + INIntentParameterDisplayNameID + cR4ir7 + INIntentParameterDisplayPriority + 1 + INIntentParameterName + monster + INIntentParameterObjectType + MonsterIntentObject + INIntentParameterObjectTypeNamespace + uWBxEI + INIntentParameterPromptDialogs + + + INIntentParameterPromptDialogCustom + + INIntentParameterPromptDialogType + Configuration + + + INIntentParameterPromptDialogCustom + + INIntentParameterPromptDialogType + Primary + + + INIntentParameterSupportsDynamicEnumeration + + INIntentParameterTag + 12 + INIntentParameterType + Object + + + INIntentResponse + + INIntentResponseCodes + + + INIntentResponseCodeName + success + INIntentResponseCodeSuccess + + + + INIntentResponseCodeName + failure + + + + INIntentTitle + Select Monster + INIntentTitleID + 4VaDj8 + INIntentType + Custom + INIntentVerb + View + + + INTypes + + + INTypeDisplayName + Monster + INTypeDisplayNameID + FHLn3U + INTypeLastPropertyTag + 108 + INTypeName + MonsterIntentObject + INTypeProperties + + + INTypePropertyDefault + + INTypePropertyDisplayPriority + 1 + INTypePropertyName + identifier + INTypePropertyTag + 1 + INTypePropertyType + String + + + INTypePropertyDefault + + INTypePropertyDisplayPriority + 2 + INTypePropertyName + displayString + INTypePropertyTag + 2 + INTypePropertyType + String + + + INTypePropertyDisplayName + Name + INTypePropertyDisplayNameID + 7pb1xe + INTypePropertyDisplayPriority + 3 + INTypePropertyName + name + INTypePropertyTag + 100 + INTypePropertyType + String + + + INTypePropertyDefault + + INTypePropertyDisplayPriority + 4 + INTypePropertyName + pronunciationHint + INTypePropertyTag + 3 + INTypePropertyType + String + + + INTypePropertyDisplayName + Description + INTypePropertyDisplayNameID + pZ2SDO + INTypePropertyDisplayPriority + 5 + INTypePropertyName + body + INTypePropertyTag + 101 + INTypePropertyType + String + + + INTypePropertyDefault + + INTypePropertyDisplayPriority + 6 + INTypePropertyName + alternativeSpeakableMatches + INTypePropertySupportsMultipleValues + + INTypePropertyTag + 4 + INTypePropertyType + SpeakableString + + + INTypePropertyDisplayName + Base Color Code + INTypePropertyDisplayNameID + BH0oLB + INTypePropertyDisplayPriority + 7 + INTypePropertyName + baseColorCode + INTypePropertyTag + 105 + INTypePropertyType + String + + + INTypePropertyDisplayName + Icon Url + INTypePropertyDisplayNameID + LDC0ih + INTypePropertyDisplayPriority + 8 + INTypePropertyName + iconUrl + INTypePropertyTag + 104 + INTypePropertyType + URL + + + INTypePropertyDisplayName + Dancing Url String + INTypePropertyDisplayNameID + mlnQMc + INTypePropertyDisplayPriority + 9 + INTypePropertyName + dancingUrlString + INTypePropertyTag + 106 + INTypePropertyType + String + + + INTypePropertyDisplayName + Order + INTypePropertyDisplayNameID + SVmOax + INTypePropertyDisplayPriority + 10 + INTypePropertyName + order + INTypePropertyTag + 108 + INTypePropertyType + Integer + + + + + + diff --git a/Shared/IntentDefinition/MonsterIntentObject+Convert.swift b/Shared/IntentDefinition/MonsterIntentObject+Convert.swift new file mode 100644 index 00000000..cefa550c --- /dev/null +++ b/Shared/IntentDefinition/MonsterIntentObject+Convert.swift @@ -0,0 +1,40 @@ +// +// MonsterIntentObject+Convert.swift +// UhooiPicBook +// +// Created by Takehito Koshimizu on 2020/11/14. +// + +import Intents + +extension MonsterIntentObject { + convenience init(monster: MonsterDTO) { + self.init(identifier: monster.name, display: monster.name) + self.name = monster.name + self.body = monster.description // The `description` is a reserved word. + self.baseColorCode = monster.baseColorCode + self.iconUrl = URL(string: monster.iconUrlString) + self.dancingUrlString = monster.dancingUrlString + self.order = monster.order as NSNumber + } + + func convertToDTO() -> MonsterDTO? { + guard let name = name, + let description = body, + let baseColorCode = baseColorCode, + let iconUrl = iconUrl, + let dancingUrlString = dancingUrlString, + let order = order + else { + return nil + } + return MonsterDTO( + name: name, + description: description, + baseColorCode: baseColorCode, + iconUrlString: iconUrl.absoluteString, + dancingUrlString: dancingUrlString, + order: order.intValue + ) + } +} diff --git a/Shared/IntentDefinition/en.lproj/WidgetsConfiguration.strings b/Shared/IntentDefinition/en.lproj/WidgetsConfiguration.strings new file mode 100644 index 00000000..232a849f --- /dev/null +++ b/Shared/IntentDefinition/en.lproj/WidgetsConfiguration.strings @@ -0,0 +1,18 @@ +"4VaDj8" = "SelectMonster"; + +"7pb1xe" = "Name"; + +"BH0oLB" = "Base Color Code"; + +"FHLn3U" = "Character"; + +"LDC0ih" = "Icon Url"; + +"SVmOax" = "Order"; + +"cR4ir7" = "Character"; + +"mlnQMc" = "Dancing Url String"; + +"pZ2SDO" = "Description"; + diff --git a/Shared/IntentDefinition/ja.lproj/WidgetsConfiguration.strings b/Shared/IntentDefinition/ja.lproj/WidgetsConfiguration.strings new file mode 100644 index 00000000..ca0ccbeb --- /dev/null +++ b/Shared/IntentDefinition/ja.lproj/WidgetsConfiguration.strings @@ -0,0 +1,18 @@ +"4VaDj8" = "SelectMonster"; + +"7pb1xe" = "名前"; + +"BH0oLB" = "ベースカラーコード"; + +"FHLn3U" = "キャラクター"; + +"LDC0ih" = "アイコンURL"; + +"SVmOax" = "表示順"; + +"cR4ir7" = "キャラクター"; + +"mlnQMc" = "ダンシングURL文字列"; + +"pZ2SDO" = "説明"; + diff --git a/Shared/Repository/Monsters/MonsterDTO.swift b/Shared/Repository/Monsters/MonsterDTO.swift index fd0c3e93..0f11fb60 100644 --- a/Shared/Repository/Monsters/MonsterDTO.swift +++ b/Shared/Repository/Monsters/MonsterDTO.swift @@ -5,8 +5,6 @@ // Created by uhooi on 2020/02/28. // -import Foundation - struct MonsterDTO { let name: String let description: String diff --git a/Shared/Repository/Monsters/MonstersRepository.swift b/Shared/Repository/Monsters/MonstersRepository.swift index ad8eb493..7e39be84 100644 --- a/Shared/Repository/Monsters/MonstersRepository.swift +++ b/Shared/Repository/Monsters/MonstersRepository.swift @@ -17,7 +17,7 @@ final class MonstersFirebaseClient { } extension MonstersFirebaseClient: MonstersRepository { - + func loadMonsters(_ completion: @escaping (Result<[MonsterDTO], Error>) -> Void) { let monstersRef = self.firestore.collection("monsters") monstersRef.getDocuments { querySnapshot, error in @@ -25,11 +25,11 @@ extension MonstersFirebaseClient: MonstersRepository { completion(.failure(error)) return } - + guard let querySnapshot = querySnapshot else { - fatalError("Fail to unwrap `querySnapshot` .") + fatalError("Fail to unwrap `querySnapshot`.") } - + var monsters: [MonsterDTO] = [] for document in querySnapshot.documents.filter({ $0.exists }) { let monster = document.data() @@ -41,12 +41,12 @@ extension MonstersFirebaseClient: MonstersRepository { let order = monster["order"] as? Int else { continue } - + monsters.append(MonsterDTO(name: name, description: description, baseColorCode: baseColorCode, iconUrlString: iconUrlString, dancingUrlString: dancingUrlString, order: order)) } - + completion(.success(monsters)) } } - + } diff --git a/UhooiPicBook/AppDelegate.swift b/UhooiPicBook/AppDelegate.swift index f82af6ea..b7cd5ef4 100644 --- a/UhooiPicBook/AppDelegate.swift +++ b/UhooiPicBook/AppDelegate.swift @@ -9,7 +9,7 @@ import UIKit import FirebaseCore import FirebaseMessaging -#if canImport(Gedatsu) +#if DEBUG import Gedatsu #endif @@ -18,7 +18,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // swiftlint:disable:next discouraged_optional_collection func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - #if canImport(Gedatsu) + #if DEBUG Gedatsu.open() #endif @@ -63,9 +63,9 @@ extension AppDelegate: UNUserNotificationCenterDelegate { willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { if #available(iOS 14.0, *) { - completionHandler([[.banner, .list, .sound]]) + completionHandler([.banner, .list, .sound]) } else { - completionHandler([[.alert, .sound]]) + completionHandler([.alert, .sound]) } } @@ -73,8 +73,20 @@ extension AppDelegate: UNUserNotificationCenterDelegate { _ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { + let userInfo = response.notification.request.content.userInfo + if let urlString = userInfo["url"] as? String { + open(urlString) + } completionHandler() } + + private func open(_ urlString: String) { + guard let url = URL(string: urlString) else { + assertionFailure("Fail to initialize URL.") + return + } + UIApplication.shared.open(url) + } } extension AppDelegate: MessagingDelegate { diff --git a/UhooiPicBook/Extensions/Foundation/Bundle+String.swift b/UhooiPicBook/Extensions/Foundation/Bundle+String.swift new file mode 100644 index 00000000..b087c291 --- /dev/null +++ b/UhooiPicBook/Extensions/Foundation/Bundle+String.swift @@ -0,0 +1,31 @@ +// +// Bundle+String.swift +// UhooiPicBook +// +// Created by uhooi on 2021/02/25. +// + +import Foundation + +extension Bundle { + var displayName: String { + guard let displayName = object(forInfoDictionaryKey: "CFBundleDisplayName") as? String else { + fatalError("Fail to load Display Name.") + } + return displayName + } + + var version: String { + guard let version = object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String else { + fatalError("Fail to load Version.") + } + return version + } + + var build: String { + guard let build = object(forInfoDictionaryKey: "CFBundleVersion") as? String else { + fatalError("Fail to load Build.") + } + return build + } +} diff --git a/UhooiPicBook/Extensions/UIKit/UICollectionView+Animation.swift b/UhooiPicBook/Extensions/UIKit/UICollectionView+Animation.swift new file mode 100644 index 00000000..6aac0475 --- /dev/null +++ b/UhooiPicBook/Extensions/UIKit/UICollectionView+Animation.swift @@ -0,0 +1,40 @@ +// +// UICollectionView+Animation.swift +// UhooiPicBook +// +// Created by Tomosuke Okada on 2021/02/22. +// + +import UIKit + +extension UICollectionView { + + func executeCellSlideUpAnimation() { + // If not called first, `visibleCells` will be empty. + layoutIfNeeded() + + // Temporarily bring visible cells under the collection view. + self.visibleCells.forEach { + $0.transform = CGAffineTransform( + translationX: 0, + y: self.bounds.size.height + ) + } + + // Animate it back to where it should be. + self.visibleCells.enumerated().forEach { object in + UIView.animate( + withDuration: 0.6, + delay: 0.04 * Double(object.offset), + usingSpringWithDamping: 1.6, + initialSpringVelocity: 0, + options: UIView.AnimationOptions.curveEaseIn, + animations: { + object.element.transform = CGAffineTransform(translationX: 0, y: 0) + }, + completion: nil + ) + } + } + +} diff --git a/UhooiPicBook/Extensions/UIKit/UIViewController+Alert.swift b/UhooiPicBook/Extensions/UIKit/UIViewController+Alert.swift new file mode 100644 index 00000000..2960adf5 --- /dev/null +++ b/UhooiPicBook/Extensions/UIKit/UIViewController+Alert.swift @@ -0,0 +1,16 @@ +// +// UIViewController+Alert.swift +// UhooiPicBook +// +// Created by uhooi on 2021/02/25. +// + +import UIKit + +extension UIViewController { + func showAlert(title: String?, message: String?, actions: [UIAlertAction]) { + let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) + actions.forEach { alert.addAction($0) } + present(alert, animated: true) + } +} diff --git a/UhooiPicBook/Modules/MonsterDetail/Interactors/MonsterDetailInteractor.swift b/UhooiPicBook/Modules/MonsterDetail/Interactors/MonsterDetailInteractor.swift index 45b7dcf5..ac6bd858 100644 --- a/UhooiPicBook/Modules/MonsterDetail/Interactors/MonsterDetailInteractor.swift +++ b/UhooiPicBook/Modules/MonsterDetail/Interactors/MonsterDetailInteractor.swift @@ -6,8 +6,6 @@ // Copyright © 2020 THE Uhooi. All rights reserved. // -import Foundation - /// @mockable protocol MonsterDetailInteractorInput: AnyObject { } diff --git a/UhooiPicBook/Modules/MonsterDetail/Presenters/MonsterDetailPresenter.swift b/UhooiPicBook/Modules/MonsterDetail/Presenters/MonsterDetailPresenter.swift index 01baea1d..795d7ea8 100644 --- a/UhooiPicBook/Modules/MonsterDetail/Presenters/MonsterDetailPresenter.swift +++ b/UhooiPicBook/Modules/MonsterDetail/Presenters/MonsterDetailPresenter.swift @@ -6,7 +6,6 @@ // Copyright © 2020 THE Uhooi. All rights reserved. // -import Foundation import UIKit.UIImage protocol MonsterDetailEventHandler: AnyObject { @@ -59,7 +58,7 @@ extension MonsterDetailPresenter: MonsterDetailEventHandler { guard let senderView = senderView, let name = name, let description = description, let icon = icon else { return // TODO: エラーハンドリング } - let text = "\(name)\n\(description)\n#UhooiPicBook" + let text = "\(name)\n\(description)\n\(R.string.localizable.uhooiPicBookHashtag())" self.router.showActivity(senderView, text: text, icon: icon) } diff --git a/UhooiPicBook/Modules/MonsterList/Interactors/MonsterListInteractor.swift b/UhooiPicBook/Modules/MonsterList/Interactors/MonsterListInteractor.swift index 8f8efab9..608de367 100644 --- a/UhooiPicBook/Modules/MonsterList/Interactors/MonsterListInteractor.swift +++ b/UhooiPicBook/Modules/MonsterList/Interactors/MonsterListInteractor.swift @@ -6,8 +6,6 @@ // Copyright © 2020 THE Uhooi. All rights reserved. // -import Foundation - /// @mockable protocol MonsterListInteractorInput: AnyObject { func fetchMonsters(_ completion: @escaping (Result<[MonsterDTO], Error>) -> Void) diff --git a/UhooiPicBook/Modules/MonsterList/Presenters/MonsterListPresenter.swift b/UhooiPicBook/Modules/MonsterList/Presenters/MonsterListPresenter.swift index 4493947b..c142e0ad 100644 --- a/UhooiPicBook/Modules/MonsterList/Presenters/MonsterListPresenter.swift +++ b/UhooiPicBook/Modules/MonsterList/Presenters/MonsterListPresenter.swift @@ -11,6 +11,12 @@ import Foundation protocol MonsterListEventHandler: AnyObject { func viewDidLoad() func didSelectMonster(monster: MonsterEntity) + + // Menu + func didTapContactUs() + func didTapPrivacyPolicy() + func didTapLicenses() + func didTapAboutThisApp() } /// @mockable @@ -60,6 +66,22 @@ extension MonsterListPresenter: MonsterListEventHandler { } } + func didTapContactUs() { + self.router.showContactUs() + } + + func didTapPrivacyPolicy() { + self.router.showPrivacyPolicy() + } + + func didTapLicenses() { + self.router.showSettings() + } + + func didTapAboutThisApp() { + self.router.showAboutThisApp() + } + func didSelectMonster(monster: MonsterEntity) { self.interactor.saveForSpotlight(monster) self.router.showMonsterDetail(monster: monster) diff --git a/UhooiPicBook/Modules/MonsterList/Routers/MonsterListRouter.swift b/UhooiPicBook/Modules/MonsterList/Routers/MonsterListRouter.swift index 37011bc1..51ae2677 100644 --- a/UhooiPicBook/Modules/MonsterList/Routers/MonsterListRouter.swift +++ b/UhooiPicBook/Modules/MonsterList/Routers/MonsterListRouter.swift @@ -11,6 +11,12 @@ import UIKit /// @mockable protocol MonsterListRouterInput: AnyObject { func showMonsterDetail(monster: MonsterEntity) + + // Menu + func showContactUs() + func showPrivacyPolicy() + func showSettings() + func showAboutThisApp() } final class MonsterListRouter { @@ -56,4 +62,40 @@ extension MonsterListRouter: MonsterListRouterInput { self.viewController.navigationController?.pushViewController(vc, animated: true) } + func showContactUs() { + guard let contactUsUrl = URL(string: R.string.localizable.contactUsURL()) else { + fatalError("Fail to initialize contact us URL.") + } + InAppWebBrowserRouter.show(self.viewController, url: contactUsUrl) + } + + func showPrivacyPolicy() { + guard let privacyPolicyUrl = URL(string: R.string.localizable.privacyPolicyURL()) else { + fatalError("Fail to initialize privacy policy URL.") + } + UIApplication.shared.open(privacyPolicyUrl) + } + + func showSettings() { + guard let settingsUrl = URL(string: UIApplication.openSettingsURLString), + UIApplication.shared.canOpenURL(settingsUrl) + else { + fatalError("Fail to open Settings URL.") + } + UIApplication.shared.open(settingsUrl) + } + + func showAboutThisApp() { + let title = Bundle.main.displayName + let message = """ +\(R.string.localizable.thisAppIsOpenSourceSoftware()) +\(R.string.localizable.uhooiPicBookGitHubURL()) + +\(R.string.localizable.version()) \(Bundle.main.version) (\(Bundle.main.build)) +\(R.string.localizable.copyright()) +""" + let okAction = UIAlertAction(title: R.string.localizable.oK(), style: .default) { _ in } + self.viewController.showAlert(title: title, message: message, actions: [okAction]) + } + } diff --git a/UhooiPicBook/Modules/MonsterList/Views/MonsterCollectionViewCell.swift b/UhooiPicBook/Modules/MonsterList/Views/MonsterCollectionViewCell.swift index b61eeabd..6517f1a7 100644 --- a/UhooiPicBook/Modules/MonsterList/Views/MonsterCollectionViewCell.swift +++ b/UhooiPicBook/Modules/MonsterList/Views/MonsterCollectionViewCell.swift @@ -26,6 +26,12 @@ final class MonsterCollectionViewCell: UICollectionViewCell { newValue.text = nil } } + // MARK: View Life-Cycle Methods + override func prepareForReuse() { + super.prepareForReuse() + self.iconImageView.image = nil + self.nameLabel.text = nil + } // MARK: Other Internal Methods diff --git a/UhooiPicBook/Modules/MonsterList/Views/MonsterList.storyboard b/UhooiPicBook/Modules/MonsterList/Views/MonsterList.storyboard index 21893ba6..976dc6b0 100644 --- a/UhooiPicBook/Modules/MonsterList/Views/MonsterList.storyboard +++ b/UhooiPicBook/Modules/MonsterList/Views/MonsterList.storyboard @@ -1,9 +1,11 @@ - + - + + + @@ -17,7 +19,7 @@ - + @@ -34,7 +36,8 @@ - + + @@ -46,11 +49,14 @@ - + + + + @@ -59,4 +65,10 @@ + + + + + + diff --git a/UhooiPicBook/Modules/MonsterList/Views/MonsterListViewController.swift b/UhooiPicBook/Modules/MonsterList/Views/MonsterListViewController.swift index bb9d0b30..7a921ec0 100644 --- a/UhooiPicBook/Modules/MonsterList/Views/MonsterListViewController.swift +++ b/UhooiPicBook/Modules/MonsterList/Views/MonsterListViewController.swift @@ -30,6 +30,33 @@ final class MonsterListViewController: UIViewController { // MARK: IBOutlets + @IBOutlet private weak var menuButton: UIBarButtonItem! { + willSet { + if #available(iOS 14.0, *) { + newValue.menu = UIMenu( + title: "", + children: [ + UIAction(title: R.string.localizable.contactUs()) { _ in + self.presenter.didTapContactUs() + }, + UIAction(title: R.string.localizable.privacyPolicy()) { _ in + self.presenter.didTapPrivacyPolicy() + }, + UIAction(title: R.string.localizable.licenses()) { _ in + self.presenter.didTapLicenses() + }, + UIAction(title: R.string.localizable.aboutThisApp()) { _ in + self.presenter.didTapAboutThisApp() + } + ] + ) + } else { + newValue.isEnabled = false + newValue.tintColor = .clear + } + } + } + @IBOutlet private weak var monstersCollectionView: UICollectionView! { willSet { newValue.register(R.nib.monsterCollectionViewCell) @@ -119,6 +146,7 @@ extension MonsterListViewController: MonsterListUserInterface { self.monsters = monsters DispatchQueue.main.async { self.monstersCollectionView.reloadData() + self.monstersCollectionView.executeCellSlideUpAnimation() } } diff --git a/UhooiPicBook/Repository/Temp/TempRepository.swift b/UhooiPicBook/Repository/Temp/TempRepository.swift index 2ad4f6bb..19f20c0a 100644 --- a/UhooiPicBook/Repository/Temp/TempRepository.swift +++ b/UhooiPicBook/Repository/Temp/TempRepository.swift @@ -6,8 +6,6 @@ // Created by uhooi on 2020/05/12. // -import Foundation - /// @mockable protocol MonstersTempRepository { func loadMonster(key: String) -> MonsterEntity? diff --git a/UhooiPicBook/Resources/Base.lproj/LaunchScreen.storyboard b/UhooiPicBook/Resources/Base.lproj/LaunchScreen.storyboard index 865e9329..0b64f641 100644 --- a/UhooiPicBook/Resources/Base.lproj/LaunchScreen.storyboard +++ b/UhooiPicBook/Resources/Base.lproj/LaunchScreen.storyboard @@ -1,8 +1,11 @@ - - + + + - + + + @@ -11,10 +14,10 @@ - + - + @@ -22,4 +25,9 @@ + + + + + diff --git a/UhooiPicBook/Resources/Info.plist b/UhooiPicBook/Resources/Info.plist index 1842a314..0ef6e51a 100644 --- a/UhooiPicBook/Resources/Info.plist +++ b/UhooiPicBook/Resources/Info.plist @@ -2,10 +2,10 @@ - NSPhotoLibraryAddUsageDescription - これにより、写真を保存できるようになります。 CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + ウホーイ図鑑 CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -22,6 +22,12 @@ $(CURRENT_PROJECT_VERSION) LSRequiresIPhoneOS + NSPhotoLibraryAddUsageDescription + これにより、写真を保存できるようになります。 + NSUserActivityTypes + + SelectMonsterIntent + UIApplicationSceneManifest UIApplicationSupportsMultipleScenes diff --git a/UhooiPicBook/Resources/en.lproj/InfoPlist.strings b/UhooiPicBook/Resources/en.lproj/InfoPlist.strings new file mode 100644 index 00000000..b04e4a35 --- /dev/null +++ b/UhooiPicBook/Resources/en.lproj/InfoPlist.strings @@ -0,0 +1,10 @@ +/* + InfoPlist.strings + UhooiPicBook + + Created by uhooi on 2021/02/26. + +*/ + +"CFBundleDisplayName" = "UhooiPicBook"; +"NSPhotoLibraryAddUsageDescription" = "You will be able to save your photos."; diff --git a/UhooiPicBook/Resources/en.lproj/Localizable.strings b/UhooiPicBook/Resources/en.lproj/Localizable.strings new file mode 100644 index 00000000..1613ac18 --- /dev/null +++ b/UhooiPicBook/Resources/en.lproj/Localizable.strings @@ -0,0 +1,31 @@ +/* + Localizable.strings + UhooiPicBook + + Created by uhooi on 2021/02/25. + +*/ + +// Monster detail +"UhooiPicBook hashtag" = "#UhooiPicBook"; + +// Menu +"Contact us" = "Contact us"; +"Privacy policy" = "Privacy policy"; +"Licenses" = "Licenses"; +"About this app" = "About this app"; + +// Contact us +"Contact us URL" = "https://forms.gle/GYM2NC48aaeEXhTh8"; + +// Privacy policy +"Privacy policy URL" = "https://theuhooi.com/privacy-policy/"; + +// About this app +"This app is open source software" = "This app is open source software."; +"UhooiPicBook GitHub URL" = "https://github.com/uhooi/UhooiPicBook"; +"Version" = "Version"; +"Copyright" = "© 2021 THE Uhooi"; + +// Alert +"OK" = "OK"; diff --git a/UhooiPicBook/Resources/ja.lproj/InfoPlist.strings b/UhooiPicBook/Resources/ja.lproj/InfoPlist.strings new file mode 100644 index 00000000..e38215ad --- /dev/null +++ b/UhooiPicBook/Resources/ja.lproj/InfoPlist.strings @@ -0,0 +1,10 @@ +/* + InfoPlist.strings + UhooiPicBook + + Created by uhooi on 2021/02/26. + +*/ + +"CFBundleDisplayName" = "ウホーイ図鑑"; +"NSPhotoLibraryAddUsageDescription" = "これにより、写真を保存できるようになります。"; diff --git a/UhooiPicBook/Resources/ja.lproj/Localizable.strings b/UhooiPicBook/Resources/ja.lproj/Localizable.strings new file mode 100644 index 00000000..bce6aa68 --- /dev/null +++ b/UhooiPicBook/Resources/ja.lproj/Localizable.strings @@ -0,0 +1,31 @@ +/* + Localizable.strings + UhooiPicBook + + Created by uhooi on 2021/02/25. + +*/ + +// Monster detail +"UhooiPicBook hashtag" = "#UhooiPicBook"; + +// Menu +"Contact us" = "お問い合わせ"; +"Privacy policy" = "プライバシーポリシー"; +"Licenses" = "ライセンス"; +"About this app" = "このアプリについて"; + +// Contact us +"Contact us URL" = "https://forms.gle/Bopyk1CCpJqoR3Zy7"; + +// Privacy policy +"Privacy policy URL" = "https://theuhooi.com/privacy-policy/"; + +// About this app +"This app is open source software" = "このアプリはオープンソースソフトウェアです。"; +"UhooiPicBook GitHub URL" = "https://github.com/uhooi/UhooiPicBook"; +"Version" = "バージョン"; +"Copyright" = "© 2021 THE Uhooi"; + +// Alert +"OK" = "OK"; diff --git a/UhooiPicBook/UIParts/ImagePopup/ImagePopup.storyboard b/UhooiPicBook/UIParts/ImagePopup/ImagePopup.storyboard index affa3c0a..9cff82d7 100644 --- a/UhooiPicBook/UIParts/ImagePopup/ImagePopup.storyboard +++ b/UhooiPicBook/UIParts/ImagePopup/ImagePopup.storyboard @@ -1,8 +1,9 @@ - + - + + @@ -38,6 +39,7 @@ + @@ -46,7 +48,6 @@ - @@ -58,7 +59,7 @@ - + diff --git a/UhooiPicBook/UIParts/InAppWebBrowser/InAppWebBrowser.storyboard b/UhooiPicBook/UIParts/InAppWebBrowser/InAppWebBrowser.storyboard new file mode 100644 index 00000000..fe011ea7 --- /dev/null +++ b/UhooiPicBook/UIParts/InAppWebBrowser/InAppWebBrowser.storyboard @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/UhooiPicBook/UIParts/InAppWebBrowser/InAppWebBrowserRouter.swift b/UhooiPicBook/UIParts/InAppWebBrowser/InAppWebBrowserRouter.swift new file mode 100644 index 00000000..e6bd987c --- /dev/null +++ b/UhooiPicBook/UIParts/InAppWebBrowser/InAppWebBrowserRouter.swift @@ -0,0 +1,31 @@ +// +// InAppWebBrowserRouter.swift +// UhooiPicBook +// +// Created by uhooi on 27/02/2021. +// Copyright © 2021 THE Uhooi. All rights reserved. +// + +import UIKit + +enum InAppWebBrowserRouter { + + // MARK: Type Methods + + static func show(_ parent: UIViewController, url: URL) { + let vc = assembleModule(url: url) + parent.present(vc, animated: true) + } + + // MARK: Other Private Methods + + private static func assembleModule(url: URL) -> InAppWebBrowserViewController { + guard let view = R.storyboard.inAppWebBrowser.instantiateInitialViewController() else { + fatalError("Fail to load InAppWebBrowserViewController from Storyboard.") + } + view.url = url + + return view + } + +} diff --git a/UhooiPicBook/UIParts/InAppWebBrowser/InAppWebBrowserViewController.swift b/UhooiPicBook/UIParts/InAppWebBrowser/InAppWebBrowserViewController.swift new file mode 100644 index 00000000..70ee0b80 --- /dev/null +++ b/UhooiPicBook/UIParts/InAppWebBrowser/InAppWebBrowserViewController.swift @@ -0,0 +1,86 @@ +// +// InAppWebBrowserViewController.swift +// UhooiPicBook +// +// Created by uhooi on 27/02/2021. +// Copyright © 2021 THE Uhooi. All rights reserved. +// + +import UIKit +import WebKit + +final class InAppWebBrowserViewController: UIViewController { + + // MARK: Type Aliases + + // MARK: Stored Instance Properties + + var url: URL! + + private var progressView = UIProgressView(progressViewStyle: .bar) + private var estimatedProgressObservation: NSKeyValueObservation? + + // MARK: Computed Instance Properties + + // MARK: IBOutlets + + @IBOutlet private weak var webView: WKWebView! + + // MARK: View Life-Cycle Methods + + override func viewDidLoad() { + super.viewDidLoad() + + configureView() + loadWebView() + } + + // MARK: IBActions + + // MARK: Other Private Methods + + private func configureView() { + configureProgressView() + configureWebView() + } + + private func configureProgressView() { + self.progressView.frame = CGRect(x: 0.0, y: 0.0, width: self.view.frame.size.width, height: 0.0) + self.view.addSubview(self.progressView) + } + + private func configureWebView() { + observeWebView() + } + + private func observeWebView() { + self.estimatedProgressObservation = self.webView.observe(\.estimatedProgress, options: [.new]) { webView, _ in + // swiftlint:disable:next trailing_closure + UIView.animate( + withDuration: 0.33, + animations: { + self.progressView.alpha = 1.0 + } + ) + self.progressView.setProgress(Float(webView.estimatedProgress), animated: true) + + if webView.estimatedProgress >= 1.0 { + UIView.animate( + withDuration: 0.33, + animations: { + self.progressView.alpha = 0.0 + }, + completion: { _ in + self.progressView.setProgress(0.0, animated: false) + } + ) + } + } + } + + private func loadWebView() { + let request = URLRequest(url: self.url) + self.webView.load(request) + } + +} diff --git a/UhooiPicBook/Util/Debug.swift b/UhooiPicBook/Util/Debug.swift index 48bbb11b..18016a6b 100644 --- a/UhooiPicBook/Util/Debug.swift +++ b/UhooiPicBook/Util/Debug.swift @@ -5,7 +5,7 @@ // Created by uhooi on 2020/05/08. // -#if canImport(SwiftPrettyPrint) +#if DEBUG import SwiftPrettyPrint typealias Debug = SwiftPrettyPrint.Pretty #endif diff --git a/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/Contents.json b/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/Contents.json index e4f57eeb..60f53754 100644 --- a/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/Contents.json +++ b/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/Contents.json @@ -90,6 +90,18 @@ }, { "filename" : "nopetsune_sticker_small.sticker" + }, + { + "filename" : "asainu_sticker_small.sticker" + }, + { + "filename" : "tetsureon_sticker_small.sticker" + }, + { + "filename" : "mikkaneko_sticker_small.sticker" + }, + { + "filename" : "meriusa_sticker_small.sticker" } ] } diff --git a/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/asainu_sticker_small.sticker/Contents.json b/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/asainu_sticker_small.sticker/Contents.json new file mode 100644 index 00000000..40afc356 --- /dev/null +++ b/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/asainu_sticker_small.sticker/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "filename" : "asainu_sticker_small.png" + } +} diff --git a/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/asainu_sticker_small.sticker/asainu_sticker_small.png b/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/asainu_sticker_small.sticker/asainu_sticker_small.png new file mode 100644 index 00000000..ab4fc06f Binary files /dev/null and b/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/asainu_sticker_small.sticker/asainu_sticker_small.png differ diff --git a/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/meriusa_sticker_small.sticker/Contents.json b/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/meriusa_sticker_small.sticker/Contents.json new file mode 100644 index 00000000..c2581baf --- /dev/null +++ b/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/meriusa_sticker_small.sticker/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "filename" : "meriusa_sticker_small.png" + } +} diff --git a/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/meriusa_sticker_small.sticker/meriusa_sticker_small.png b/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/meriusa_sticker_small.sticker/meriusa_sticker_small.png new file mode 100644 index 00000000..9c1fb5cc Binary files /dev/null and b/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/meriusa_sticker_small.sticker/meriusa_sticker_small.png differ diff --git a/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/mikkaneko_sticker_small.sticker/Contents.json b/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/mikkaneko_sticker_small.sticker/Contents.json new file mode 100644 index 00000000..2ac97a10 --- /dev/null +++ b/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/mikkaneko_sticker_small.sticker/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "filename" : "mikkaneko_sticker_small.png" + } +} diff --git a/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/mikkaneko_sticker_small.sticker/mikkaneko_sticker_small.png b/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/mikkaneko_sticker_small.sticker/mikkaneko_sticker_small.png new file mode 100644 index 00000000..7fc20223 Binary files /dev/null and b/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/mikkaneko_sticker_small.sticker/mikkaneko_sticker_small.png differ diff --git a/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/tetsureon_sticker_small.sticker/Contents.json b/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/tetsureon_sticker_small.sticker/Contents.json new file mode 100644 index 00000000..d54eba58 --- /dev/null +++ b/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/tetsureon_sticker_small.sticker/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "filename" : "tetsureon_sticker_small.png" + } +} diff --git a/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/tetsureon_sticker_small.sticker/tetsureon_sticker_small.png b/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/tetsureon_sticker_small.sticker/tetsureon_sticker_small.png new file mode 100644 index 00000000..5b0df1ac Binary files /dev/null and b/UhooiPicBookStickers/Stickers.xcassets/Sticker Pack.stickerpack/tetsureon_sticker_small.sticker/tetsureon_sticker_small.png differ diff --git a/UhooiPicBookTests/Extensions/Foundation/BundleStringTests.swift b/UhooiPicBookTests/Extensions/Foundation/BundleStringTests.swift new file mode 100644 index 00000000..eb1be497 --- /dev/null +++ b/UhooiPicBookTests/Extensions/Foundation/BundleStringTests.swift @@ -0,0 +1,54 @@ +// +// BundleVersionTests.swift +// UhooiPicBookTests +// +// Created by uhooi on 2021/02/25. +// + +import XCTest +@testable import UhooiPicBook + +final class BundleStringTests: XCTestCase { + + // MARK: TestCase Life-Cycle Methods + + override func setUpWithError() throws { + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + // MARK: - Test Methods + + // MARK: displayName + + func test_bundle_displayName() { + guard let language = Locale.preferredLanguages.first else { + XCTFail("Fail to load user's preferred languages.") + return + } + + var expected = "" + switch Locale(identifier: language).languageCode { + case "en": + expected = "UhooiPicBook" + default: + expected = "ウホーイ図鑑" + } + XCTAssertEqual(Bundle.main.displayName, expected) + } + + // MARK: version + + func test_bundle_version() { + XCTAssertEqual(Bundle.main.version, "1.4.0") + } + + // MARK: build + + func test_bundle_build() { + XCTAssertEqual(Bundle.main.build, "15") + } + +} diff --git a/UhooiPicBookTests/Modules/MonsterList/Presenters/MonsterListPresenterTests.swift b/UhooiPicBookTests/Modules/MonsterList/Presenters/MonsterListPresenterTests.swift index ac63a246..32a58981 100644 --- a/UhooiPicBookTests/Modules/MonsterList/Presenters/MonsterListPresenterTests.swift +++ b/UhooiPicBookTests/Modules/MonsterList/Presenters/MonsterListPresenterTests.swift @@ -145,6 +145,50 @@ final class MonsterListPresenterTests: XCTestCase { XCTAssertEqual(self.interactorMock.saveForSpotlightCallCount, 1) XCTAssertEqual(self.routerMock.showMonsterDetailCallCount, 1) } + + // MARK: didTapContactUs() + + func test_didTapContactUs() { + self.presenter.didTapContactUs() + + XCTAssertEqual(self.routerMock.showContactUsCallCount, 1) + XCTAssertEqual(self.routerMock.showPrivacyPolicyCallCount, 0) + XCTAssertEqual(self.routerMock.showSettingsCallCount, 0) + XCTAssertEqual(self.routerMock.showAboutThisAppCallCount, 0) + } + + // MARK: didTapPrivacyPolicy() + + func test_didTapPrivacyPolicy() { + self.presenter.didTapPrivacyPolicy() + + XCTAssertEqual(self.routerMock.showContactUsCallCount, 0) + XCTAssertEqual(self.routerMock.showPrivacyPolicyCallCount, 1) + XCTAssertEqual(self.routerMock.showSettingsCallCount, 0) + XCTAssertEqual(self.routerMock.showAboutThisAppCallCount, 0) + } + + // MARK: didTapLicenses() + + func test_didTapLicenses() { + self.presenter.didTapLicenses() + + XCTAssertEqual(self.routerMock.showContactUsCallCount, 0) + XCTAssertEqual(self.routerMock.showPrivacyPolicyCallCount, 0) + XCTAssertEqual(self.routerMock.showSettingsCallCount, 1) + XCTAssertEqual(self.routerMock.showAboutThisAppCallCount, 0) + } + + // MARK: didTapAboutThisApp() + + func test_didTapAboutThisApp() { + self.presenter.didTapAboutThisApp() + + XCTAssertEqual(self.routerMock.showContactUsCallCount, 0) + XCTAssertEqual(self.routerMock.showPrivacyPolicyCallCount, 0) + XCTAssertEqual(self.routerMock.showSettingsCallCount, 0) + XCTAssertEqual(self.routerMock.showAboutThisAppCallCount, 1) + } // MARK: MonsterListInteractorOutput diff --git a/UhooiPicBookWidgets/Monster/MonsterConfigurableWidget.swift b/UhooiPicBookWidgets/Monster/MonsterConfigurableWidget.swift new file mode 100644 index 00000000..72deda84 --- /dev/null +++ b/UhooiPicBookWidgets/Monster/MonsterConfigurableWidget.swift @@ -0,0 +1,69 @@ +// +// MonsterConfigurableWidget.swift +// UhooiPicBookWidgets +// +// Created by Takehito Koshimizu on 2020/11/14. +// + +import WidgetKit +import SwiftUI + +private struct MonsterProvider { + typealias Entry = MonsterEntry + typealias Intent = SelectMonsterIntent + + private let imageManager: ImageCacheManagerProtocol + + init(imageManager: ImageCacheManagerProtocol) { + self.imageManager = imageManager + } +} + +struct MonsterConfigurableWidget: Widget { + var body: some WidgetConfiguration { + IntentConfiguration( + kind: "MonsterConfigurable", + intent: SelectMonsterIntent.self, + provider: MonsterProvider(imageManager: ImageCacheManager()) + ) { entry in + MonsterEntryView(entry: entry) + } + .configurationDisplayName("Configuration display name") + .description("Configurable description") + .supportedFamilies([.systemSmall, .systemMedium]) + } +} + +extension MonsterProvider: IntentTimelineProvider { + func placeholder(in context: Context) -> Entry { + .createDefault() + } + + func getSnapshot(for intent: Intent, in context: Context, completion: @escaping (Entry) -> Void) { + completion(.createDefault()) + } + + func getTimeline(for intent: Intent, in context: Context, completion: @escaping (Timeline) -> Void) { + convertDTOToEntry(dto: intent.monster?.convertToDTO()) { entry in + let entries = [entry ?? .createDefault()] + completion(Timeline(entries: entries, policy: .never)) + } + } + + private func convertDTOToEntry(dto: MonsterDTO?, completion: @escaping (Entry?) -> Void) { + if let dto = dto, let iconUrl = URL(string: dto.iconUrlString) { + self.imageManager.cacheImage(imageUrl: iconUrl) { result in + switch result { + case let .success(icon): + let name = dto.name + let description = dto.description.replacingOccurrences(of: "\\n", with: "\n") + completion(Entry(date: Date(), name: name, description: description, icon: icon)) + case .failure: + completion(nil) + } + } + } else { + completion(nil) + } + } +} diff --git a/UhooiPicBookWidgets/Monster/MonsterEntry.swift b/UhooiPicBookWidgets/Monster/MonsterEntry.swift new file mode 100644 index 00000000..9646f2a8 --- /dev/null +++ b/UhooiPicBookWidgets/Monster/MonsterEntry.swift @@ -0,0 +1,25 @@ +// +// MonsterEntry.swift +// UhooiPicBookWidgets +// +// Created by uhooi on 2020/12/14. +// + +import UIKit.UIImage +import WidgetKit + +struct MonsterEntry: TimelineEntry { + let date: Date + let name: String + let description: String + let icon: UIImage + + static func createDefault() -> Self { + .init( + date: Date(), + name: "uhooi", + description: "ゆかいな みどりの せいぶつ。\nわるそうに みえるが むがい。", + icon: UIImage(named: "Uhooi")! // swiftlint:disable:this force_unwrapping + ) + } +} diff --git a/UhooiPicBookWidgets/Monster/MonsterEntryView.swift b/UhooiPicBookWidgets/Monster/MonsterEntryView.swift index abb6301d..8710a7a1 100644 --- a/UhooiPicBookWidgets/Monster/MonsterEntryView.swift +++ b/UhooiPicBookWidgets/Monster/MonsterEntryView.swift @@ -8,10 +8,10 @@ import WidgetKit import SwiftUI -struct MonsterEntryView : View { - var entry: MonsterWidget.Provider.Entry +struct MonsterEntryView: View { + var entry: MonsterEntry @Environment(\.widgetFamily) private var family - + var body: some View { switch family { case .systemSmall: @@ -44,18 +44,18 @@ struct MonsterEntryView : View { EmptyView() } } - + private var icon: some View { Image(uiImage: entry.icon) .resizable() .aspectRatio(contentMode: .fit) } - + private var name: some View { Text(entry.name) .font(.headline) } - + private var description: some View { Text(entry.description) .font(.body) @@ -63,16 +63,18 @@ struct MonsterEntryView : View { } struct MonsterEntryView_Previews: PreviewProvider { - typealias Entry = MonsterWidget.Entry - + typealias Entry = MonsterEntry + static var previews: some View { - previewEntryViewGroup - .previewContext(WidgetPreviewContext(family: .systemSmall)) - previewEntryViewGroup - .previewContext(WidgetPreviewContext(family: .systemMedium)) + ForEach(families.indices) { index in + previewEntryViewGroup + .previewContext(WidgetPreviewContext(family: families[index])) + } } - - static private var previewEntryViewGroup: some View { + + private static let families: [WidgetFamily] = [.systemSmall, .systemMedium] + + private static var previewEntryViewGroup: some View { Group { MonsterEntryView(entry: .createDefault()) .redacted(reason: .placeholder) @@ -83,22 +85,22 @@ struct MonsterEntryView_Previews: PreviewProvider { MonsterEntryView(entry: createLongEntry()) } } - - static private func createShortEntry() -> Entry { + + private static func createShortEntry() -> Entry { .init( date: Date(), name: "1", description: "1", - icon: UIImage(named: "Uhooi")! + icon: UIImage(named: "Uhooi")! // swiftlint:disable:this force_unwrapping ) } - - static private func createLongEntry() -> Entry { + + private static func createLongEntry() -> Entry { .init( date: Date(), name: "123456789012345678901234567890", description: "12345678901234567890\n12345678901234567890\n12345678901234567890", - icon: UIImage(named: "Uhooi")! + icon: UIImage(named: "Uhooi")! // swiftlint:disable:this force_unwrapping ) } } diff --git a/UhooiPicBookWidgets/Monster/MonsterWidget.swift b/UhooiPicBookWidgets/Monster/MonsterWidget.swift index 4cfa10b1..20cf1f33 100644 --- a/UhooiPicBookWidgets/Monster/MonsterWidget.swift +++ b/UhooiPicBookWidgets/Monster/MonsterWidget.swift @@ -9,101 +9,92 @@ import WidgetKit import SwiftUI import FirebaseCore -struct MonsterWidget: Widget { - init() { - FirebaseApp.configure() +private struct MonsterProvider { + typealias Entry = MonsterEntry + + private let monstersRepository: MonstersRepository + private let imageCacheManager: ImageCacheManagerProtocol + + init(monstersRepository: MonstersRepository, imageCacheManager: ImageCacheManagerProtocol) { + self.monstersRepository = monstersRepository + self.imageCacheManager = imageCacheManager } - +} + +struct MonsterWidget: Widget { var body: some WidgetConfiguration { - StaticConfiguration(kind: "Monster", provider: Provider(monstersRepository: MonstersFirebaseClient(), imageCacheManager: ImageCacheManager())) { entry in + StaticConfiguration( + kind: "Monster", + provider: MonsterProvider( + monstersRepository: MonstersFirebaseClient(), + imageCacheManager: ImageCacheManager() + ) + ) { entry in MonsterEntryView(entry: entry) } - .configurationDisplayName("configurationDisplayName") - .description("description") + .configurationDisplayName("Configuration display name") + .description("Description") .supportedFamilies([.systemSmall, .systemMedium]) } + + init() { + FirebaseApp.configure() + } } -extension MonsterWidget { - struct Provider: TimelineProvider { - typealias Entry = MonsterWidget.Entry - - private let monstersRepository: MonstersRepository - private let imageCacheManager: ImageCacheManagerProtocol - - init(monstersRepository: MonstersRepository, imageCacheManager: ImageCacheManagerProtocol) { - self.monstersRepository = monstersRepository - self.imageCacheManager = imageCacheManager - } - - func placeholder(in context: Context) -> Entry { - .createDefault() - } - - func getSnapshot(in context: Context, completion: @escaping (Entry) -> ()) { - completion(.createDefault()) - } - - func getTimeline(in context: Context, completion: @escaping (Timeline) -> ()) { - var entries: [Entry] = [] - - self.monstersRepository.loadMonsters { result in - switch result { - case let .success(monsters): - let currentDate = Date() - var hourOffset = 0 - for monster in monsters.sorted(by: { $0.order < $1.order }) { - let name = monster.name - let description = monster.description.replacingOccurrences(of: "\\n", with: "\n") - let iconUrlString = monster.iconUrlString - - guard let iconUrl = URL(string: iconUrlString) else { - continue - } - - let group = DispatchGroup() - group.enter() - - self.imageCacheManager.cacheImage(imageUrl: iconUrl) { result in - switch result { - case let .success(icon): - let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)! - let entry = Entry(date: entryDate, name: name, description: description, icon: icon) - entries.append(entry) - hourOffset += 1 - case .failure(_): - break +extension MonsterProvider: TimelineProvider { + func placeholder(in context: Context) -> Entry { + .createDefault() + } + + func getSnapshot(in context: Context, completion: @escaping (Entry) -> Void) { + completion(.createDefault()) + } + + func getTimeline(in context: Context, completion: @escaping (Timeline) -> Void) { + var entries: [Entry] = [] + + // swiftlint:disable:next closure_body_length + self.monstersRepository.loadMonsters { result in + switch result { + case let .success(monsters): + let currentDate = Date() + var hourOffset = 0 + for monster in monsters.sorted(by: { $0.order < $1.order }) { + let name = monster.name + let description = monster.description.replacingOccurrences(of: "\\n", with: "\n") + let iconUrlString = monster.iconUrlString + + guard let iconUrl = URL(string: iconUrlString) else { + continue + } + + let group = DispatchGroup() + group.enter() + + self.imageCacheManager.cacheImage(imageUrl: iconUrl) { result in + switch result { + case let .success(icon): + guard let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate) else { + fatalError("Fail to unwrap `entryDate`. hourOffset: \(hourOffset), currentDate: \(currentDate)") } - - group.leave() + let entry = Entry(date: entryDate, name: name, description: description, icon: icon) + entries.append(entry) + hourOffset += 1 + case .failure: + break } - - group.wait() + + group.leave() } - case .failure(_): - break + + group.wait() } - - completion(Timeline(entries: entries, policy: .atEnd)) + case .failure: + break } - } - } -} -extension MonsterWidget { - struct Entry: TimelineEntry { - let date: Date - let name: String - let description: String - let icon: UIImage - - static func createDefault() -> Entry { - .init( - date: Date(), - name: "uhooi", - description: "ゆかいな みどりの せいぶつ。\nわるそうに みえるが むがい。", - icon: UIImage(named: "Uhooi")! - ) + completion(Timeline(entries: entries, policy: .atEnd)) } } } diff --git a/UhooiPicBookWidgets/UhooiPicBookWidgets.swift b/UhooiPicBookWidgets/UhooiPicBookWidgets.swift index 42830ff7..5d52ff02 100644 --- a/UhooiPicBookWidgets/UhooiPicBookWidgets.swift +++ b/UhooiPicBookWidgets/UhooiPicBookWidgets.swift @@ -5,12 +5,12 @@ // Created by uhooi on 2020/11/08. // -import WidgetKit import SwiftUI @main struct UhooiPicBookWidgets: WidgetBundle { var body: some Widget { MonsterWidget() + MonsterConfigurableWidget() } } diff --git a/UhooiPicBookWidgets/en.lproj/Localizable.strings b/UhooiPicBookWidgets/en.lproj/Localizable.strings index 40608210..ff0d07d2 100644 --- a/UhooiPicBookWidgets/en.lproj/Localizable.strings +++ b/UhooiPicBookWidgets/en.lproj/Localizable.strings @@ -6,5 +6,7 @@ */ -"configurationDisplayName" = "Character's info"; -"description" = "See character's info. Every hour it updates to the next character's info."; +"Configuration display name" = "Character's info"; +"Description" = "See character's info. Every hour it updates to the next character's info."; + +"Configurable description" = "Choose your favorite character in the \"Edit Widget\" section."; diff --git a/UhooiPicBookWidgets/ja.lproj/Localizable.strings b/UhooiPicBookWidgets/ja.lproj/Localizable.strings index a0428bf4..f7c0ae7d 100644 --- a/UhooiPicBookWidgets/ja.lproj/Localizable.strings +++ b/UhooiPicBookWidgets/ja.lproj/Localizable.strings @@ -6,5 +6,7 @@ */ -"configurationDisplayName" = "キャラクター情報"; -"description" = "キャラクター情報を表示します。1時間ごとに次のキャラクターの情報に更新します。"; +"Configuration display name" = "キャラクター情報"; +"Description" = "キャラクター情報を表示します。1時間ごとに次のキャラクターの情報に更新します。"; + +"Configurable description" = "「ウィジェットを編集」で好きなキャラクターを選択しましょう。"; diff --git a/UhooiPicBookWidgetsConfigurableIntent/Info.plist b/UhooiPicBookWidgetsConfigurableIntent/Info.plist new file mode 100644 index 00000000..4b8ec0fe --- /dev/null +++ b/UhooiPicBookWidgetsConfigurableIntent/Info.plist @@ -0,0 +1,42 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + UhooiPicBookWidgetsConfigurableIntent + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSExtension + + NSExtensionAttributes + + IntentsRestrictedWhileLocked + + IntentsRestrictedWhileProtectedDataUnavailable + + IntentsSupported + + SelectMonsterIntent + + + NSExtensionPointIdentifier + com.apple.intents-service + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).IntentHandler + + + diff --git a/UhooiPicBookWidgetsConfigurableIntent/IntentHandler.swift b/UhooiPicBookWidgetsConfigurableIntent/IntentHandler.swift new file mode 100644 index 00000000..f0474817 --- /dev/null +++ b/UhooiPicBookWidgetsConfigurableIntent/IntentHandler.swift @@ -0,0 +1,36 @@ +// +// IntentHandler.swift +// UhooiPicBookWidgetsConfigurableIntent +// +// Created by Takehito Koshimizu on 2020/11/14. +// + +import Intents +import FirebaseCore + +final class IntentHandler: INExtension, SelectMonsterIntentHandling { + + private let repository: MonstersRepository + + override init() { + FirebaseApp.configure() + self.repository = MonstersFirebaseClient() + super.init() + } + + func provideMonsterOptionsCollection( + for intent: SelectMonsterIntent, + with completion: @escaping (INObjectCollection?, Error?) -> Void) { + self.repository.loadMonsters { result in + switch result { + case let .success(monsters): + let monsterIntentObject = monsters + .sorted { $0.order < $1.order } + .map(MonsterIntentObject.init) + completion(INObjectCollection(items: monsterIntentObject), nil) + case let .failure(error): + completion(nil, error) + } + } + } +} diff --git a/project.yml b/project.yml index e68179d4..4b3a5f87 100644 --- a/project.yml +++ b/project.yml @@ -5,18 +5,32 @@ options: deploymentTarget: iOS: 13.0 developmentLanguage: ja - xcodeVersion: "12.1" - carthageExecutablePath: unset SDKROOT && mint run Carthage/Carthage carthage + xcodeVersion: "12.3" settings: base: - MARKETING_VERSION: 1.3.0 - CURRENT_PROJECT_VERSION: 14 + MARKETING_VERSION: 1.4.0 + CURRENT_PROJECT_VERSION: 15 DEVELOPMENT_TEAM: 47E56DYP3N + OTHER_LDFLAGS: $(inherited) $(OTHER_LDFLAGS) -ObjC configs: debug: DEBUG_INFORMATION_FORMAT: "dwarf-with-dsym" +packages: + Rswift: + url: https://github.com/mac-cain13/R.swift.Library + version: 5.3.0 + Gedatsu: + url: https://github.com/bannzai/Gedatsu + version: 1.2.0 + SwiftPrettyPrint: + url: https://github.com/YusukeHosonuma/SwiftPrettyPrint + version: 1.0.0 + Firebase: + url: https://github.com/firebase/firebase-ios-sdk + version: 7.3.1 + targets: UhooiPicBook: type: application @@ -34,9 +48,10 @@ targets: base: INFOPLIST_FILE: UhooiPicBook/Resources/Info.plist CODE_SIGN_ENTITLEMENTS: UhooiPicBook/Resources/UhooiPicBook.entitlements - OTHER_LDFLAGS: $(inherited) $(OTHER_LDFLAGS) -ObjC - OTHER_SWIFT_FLAGS: $(inherited) -Xfrontend -warn-long-expression-type-checking=500 -Xfrontend -warn-long-function-bodies=500 DEVELOPMENT_LANGUAGE: jp + configs: + debug: + OTHER_SWIFT_FLAGS: $(inherited) -Xfrontend -warn-long-expression-type-checking=500 -Xfrontend -warn-long-function-bodies=500 dependencies: - target: UhooiPicBookStickers embed: true @@ -45,109 +60,44 @@ targets: copyFiles: destination: plugins - target: UhooiPicBookWidgets - - framework: Carthage/Build/iOS/abseil.framework - embed: false - - framework: Carthage/Build/iOS/BoringSSL-GRPC.framework - embed: false - - framework: Carthage/Build/iOS/FIRAnalyticsConnector.framework - embed: false - - framework: Carthage/Build/iOS/FirebaseABTesting.framework - embed: false - - framework: Carthage/Build/iOS/FirebaseAnalytics.framework - embed: false - - framework: Carthage/Build/iOS/FirebaseCore.framework - embed: false - - framework: Carthage/Build/iOS/FirebaseCoreDiagnostics.framework - embed: false - - framework: Carthage/Build/iOS/FirebaseCrashlytics.framework - embed: false - - framework: Carthage/Build/iOS/FirebaseFirestore.framework - embed: false - - framework: Carthage/Build/iOS/FirebaseInstallations.framework - embed: false - - framework: Carthage/Build/iOS/FirebaseInstanceID.framework - embed: false - - framework: Carthage/Build/iOS/FirebaseMessaging.framework - embed: false - - framework: Carthage/Build/iOS/FirebasePerformance.framework - embed: false - - framework: Carthage/Build/iOS/FirebaseRemoteConfig.framework - embed: false - - framework: Carthage/Build/iOS/GoogleAppMeasurement.framework - embed: false - - framework: Carthage/Build/iOS/GoogleDataTransport.framework - embed: false - - framework: Carthage/Build/iOS/GoogleToolboxForMac.framework - embed: false - - framework: Carthage/Build/iOS/GoogleUtilities.framework - embed: false - - framework: Carthage/Build/iOS/gRPC-C++.framework - embed: false - - framework: Carthage/Build/iOS/gRPC-Core.framework - embed: false - - framework: Carthage/Build/iOS/GTMSessionFetcher.framework - embed: false - - framework: Carthage/Build/iOS/leveldb-library.framework - embed: false - - framework: Carthage/Build/iOS/nanopb.framework - embed: false - - framework: Carthage/Build/iOS/PromisesObjC.framework - embed: false - - framework: Carthage/Build/iOS/Protobuf.framework - embed: false + - target: UhooiPicBookWidgetsConfigurableIntent + - package: Rswift + - package: Gedatsu + - package: SwiftPrettyPrint + - package: Firebase + product: FirebaseAnalytics + - package: Firebase + product: FirebaseAppDistribution-Beta + - package: Firebase + product: FirebaseCrashlytics + - package: Firebase + product: FirebaseFirestore + - package: Firebase + product: FirebaseInstallations + - package: Firebase + product: FirebaseMessaging + - package: Firebase + product: FirebaseRemoteConfig preBuildScripts: - - script: | - "$PODS_ROOT/R.swift/rswift" generate "$SRCROOT/$TARGET_NAME/Generated/R.generated.swift" + - path: ./Scripts/XcodeGen/rswift.sh name: Generate Resources with R.swift inputFiles: - $TEMP_DIR/rswift-lastrun outputFiles: - $SRCROOT/$TARGET_NAME/Generated/R.generated.swift - - script: | - unset SDKROOT - if which mint >/dev/null; then - rm -f $SRCROOT/$TARGET_NAME/Generated/MockResults.swift - mint run uber/mockolo mockolo --sourcedirs $SRCROOT/$TARGET_NAME $SRCROOT/Shared --destination $SRCROOT/$TARGET_NAME/Generated/MockResults.swift --mock-final - else - echo "warning: Mint not installed, download from https://github.com/yonaskolb/Mint" - fi + - path: ./Scripts/XcodeGen/mockolo.sh name: Generate Mocks with Mockolo outputFiles: - $SRCROOT/$TARGET_NAME/Generated/MockResults.swift postCompileScripts: - - script: | - unset SDKROOT - if which mint >/dev/null; then - mint run swiftlint swiftlint autocorrect --format - mint run swiftlint swiftlint - else - echo "warning: Mint not installed, download from https://github.com/yonaskolb/Mint" - fi + - path: ./Scripts/XcodeGen/swiftlint.sh name: Run SwiftLint - - script: | - unset SDKROOT - if ! which mint >/dev/null; then - echo "warning: Mint not installed, download from https://github.com/yonaskolb/Mint" - exit 0 - fi - - git_path=/usr/local/bin/git - files=$($git_path diff --diff-filter=d --name-only -- "*.swift" "*.h" "*.m") - if (test -z $files) || (test ${#files[@]} -eq 0); then - echo "no files changed." - exit 0 - fi - - options="" - for file in $files - do - options="$options $SRCROOT/$file" - done - - mint run SpellChecker SpellChecker --yml $SRCROOT/spell-checker.yml -- $options + - path: ./Scripts/XcodeGen/iblinter.sh + name: Run IBLinter + - path: ./Scripts/XcodeGen/spellchecker.sh name: Run SpellChecker postBuildScripts: - - script: /bin/sh ./Scripts/FirebaseCrashlytics/run + - script: ./SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run name: Run Firebase Crashlytics inputFiles: - $(SRCROOT)/$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH) @@ -225,82 +175,66 @@ targets: dependencies: - sdk: SwiftUI.framework - sdk: WidgetKit.framework - - framework: Carthage/Build/iOS/abseil.framework - embed: false - - framework: Carthage/Build/iOS/BoringSSL-GRPC.framework - embed: false - - framework: Carthage/Build/iOS/FIRAnalyticsConnector.framework - embed: false - - framework: Carthage/Build/iOS/FirebaseAnalytics.framework - embed: false - - framework: Carthage/Build/iOS/FirebaseCore.framework - embed: false - - framework: Carthage/Build/iOS/FirebaseCoreDiagnostics.framework - embed: false - - framework: Carthage/Build/iOS/FirebaseCrashlytics.framework - embed: false - - framework: Carthage/Build/iOS/FirebaseFirestore.framework - embed: false - - framework: Carthage/Build/iOS/FirebaseInstallations.framework - embed: false - - framework: Carthage/Build/iOS/FirebaseRemoteConfig.framework - embed: false - - framework: Carthage/Build/iOS/GoogleAppMeasurement.framework - embed: false - - framework: Carthage/Build/iOS/GoogleDataTransport.framework - embed: false - - framework: Carthage/Build/iOS/GoogleToolboxForMac.framework - embed: false - - framework: Carthage/Build/iOS/GoogleUtilities.framework - embed: false - - framework: Carthage/Build/iOS/gRPC-C++.framework - embed: false - - framework: Carthage/Build/iOS/gRPC-Core.framework - embed: false - - framework: Carthage/Build/iOS/GTMSessionFetcher.framework - embed: false - - framework: Carthage/Build/iOS/leveldb-library.framework - embed: false - - framework: Carthage/Build/iOS/nanopb.framework - embed: false - - framework: Carthage/Build/iOS/PromisesObjC.framework - embed: false - - framework: Carthage/Build/iOS/Protobuf.framework - embed: false - postCompileScripts: - - script: | - unset SDKROOT - if which mint >/dev/null; then - mint run swiftlint swiftlint autocorrect --format - mint run swiftlint swiftlint - else - echo "warning: Mint not installed, download from https://github.com/yonaskolb/Mint" - fi - name: Run SwiftLint - - script: | - unset SDKROOT - if ! which mint >/dev/null; then - echo "warning: Mint not installed, download from https://github.com/yonaskolb/Mint" - exit 0 - fi - - git_path=/usr/local/bin/git - files=$($git_path diff --diff-filter=d --name-only -- "*.swift" "*.h" "*.m") - if (test -z $files) || (test ${#files[@]} -eq 0); then - echo "no files changed." - exit 0 - fi - - options="" - for file in $files - do - options="$options $SRCROOT/$file" - done + - package: Firebase + product: FirebaseAnalytics + - package: Firebase + product: FirebaseAppDistribution-Beta + - package: Firebase + product: FirebaseCrashlytics + - package: Firebase + product: FirebaseFirestore + - package: Firebase + product: FirebaseInstallations + - package: Firebase + product: FirebaseMessaging + - package: Firebase + product: FirebaseRemoteConfig + postBuildScripts: + - script: ./SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run + name: Run Firebase Crashlytics + inputFiles: + - $(SRCROOT)/$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH) - mint run SpellChecker SpellChecker --yml $SRCROOT/spell-checker.yml -- $options - name: Run SpellChecker + UhooiPicBookWidgetsConfigurableIntent: + type: app-extension + platform: iOS + deploymentTarget: 14.0 + settings: + base: + CODE_SIGN_IDENTITY: "iPhone Developer" + CODE_SIGN_STYLE: Automatic + GCC_PREPROCESSOR_DEFINITIONS: + - "DEBUG=1" + - "$(inherited)" + INFOPLIST_FILE: UhooiPicBookWidgetsConfigurableIntent/Info.plist + LD_RUNPATH_SEARCH_PATHS: + - "$(inherited)" + - "@executable_path/Frameworks" + - "@executable_path/../../Frameworks" + OTHER_LDFLAGS: $(inherited) $(OTHER_LDFLAGS) -ObjC + PRODUCT_BUNDLE_IDENTIFIER: com.theuhooi.UhooiPicBook.WidgetsConfigurableIntent + PRODUCT_NAME: "UhooiPicBookWidgetsConfigurableIntent" + SKIP_INSTALL: YES + sources: + - UhooiPicBookWidgetsConfigurableIntent + - Shared + dependencies: + - package: Firebase + product: FirebaseAnalytics + - package: Firebase + product: FirebaseAppDistribution-Beta + - package: Firebase + product: FirebaseCrashlytics + - package: Firebase + product: FirebaseFirestore + - package: Firebase + product: FirebaseInstallations + - package: Firebase + product: FirebaseMessaging + - package: Firebase + product: FirebaseRemoteConfig postBuildScripts: - - script: /bin/sh ./Scripts/FirebaseCrashlytics/run + - script: ./SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run name: Run Firebase Crashlytics inputFiles: - $(SRCROOT)/$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH) @@ -310,6 +244,15 @@ schemes: build: targets: UhooiPicBook: all + postActions: + - script: rm -rf "${TARGET_BUILD_DIR}/${PRODUCT_NAME}.app/Frameworks/FirebaseAnalytics.framework" && + rm -rf "${TARGET_BUILD_DIR}/${PRODUCT_NAME}.app/Frameworks/GoogleAppMeasurement.framework" && + rm -rf "${TARGET_BUILD_DIR}/${PRODUCT_NAME}.app/PlugIns/FirebaseAnalytics.framework" && + rm -rf "${TARGET_BUILD_DIR}/${PRODUCT_NAME}.app/PlugIns/GoogleAppMeasurement.framework" && + rm -rf "${TARGET_BUILD_DIR}/${PRODUCT_NAME}.app/PlugIns/UhooiPicBookWidgets.appex/Frameworks" && + rm -rf "${TARGET_BUILD_DIR}/${PRODUCT_NAME}.app/PlugIns/UhooiPicBookWidgetsConfigurableIntent.appex/Frameworks" + name: Remove Firebase frameworks + settingsTarget: UhooiPicBook run: config: Debug test: @@ -330,4 +273,3 @@ schemes: config: Debug archive: config: Release - diff --git a/spell-checker.yml b/spell-checker.yml index f3187176..75221009 100644 --- a/spell-checker.yml +++ b/spell-checker.yml @@ -8,6 +8,7 @@ whiteList: - swiftlint - gedatsu - json + - hashable - fcm # Uhooi @@ -17,4 +18,6 @@ whiteList: - ayausa - chibird - tomosuke + - takehito + - koshimizu