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