From b5435bb3fc356d962aff9dc03cb646a182fe87a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Bola=C3=B1os?= <94141394+mario-bolanos-sumup@users.noreply.github.com> Date: Tue, 22 Nov 2022 10:25:39 -0500 Subject: [PATCH] Initial commit --- .gitignore | 99 +++ .gitmodules | 6 + .swiftlint.yml | 6 + Gemfile | 8 + Gemfile.lock | 291 +++++++ Podfile | 49 ++ README.md | 27 + catalog-info.yaml | 78 ++ fastlane/Fastfile | 20 + fastlane/README.md | 225 +++++ github/workflows/main.yml | 36 + github/workflows/publish_pod.yml | 27 + github/workflows/update_pod_version.yml | 27 + make.sh | 81 ++ submodules/ios-tooling | 1 + submodules/mobile-tooling | 1 + {{NAME}}.podspec | 23 + {{NAME}}/PodSample.swift | 10 + .../Tests/Snapshot/PodSnapshotTests.swift | 24 + {{NAME}}/Tests/Unit/PodUnitTests.swift | 17 + .../contents.xcworkspacedata | 10 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + {{NAME}}SampleApp/{{NAME}}/AppDelegate.swift | 33 + .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 98 +++ .../{{NAME}}/Assets.xcassets/Contents.json | 6 + .../{{NAME}}/AuthTokenProvider+{{NAME}}.swift | 31 + .../Base.lproj/LaunchScreen.storyboard | 54 ++ {{NAME}}SampleApp/{{NAME}}/Info.plist | 45 + .../{{NAME}}/SnapshotTests.xctestplan | 42 + .../{{NAME}}/UnitTests.xctestplan | 24 + .../{{NAME}}/ViewController.swift | 103 +++ .../project.pbxproj | 818 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcschemes/{{NAME}}SampleApp.xcscheme | 72 ++ .../xcschemes/{{NAME}}SnapshotTests.xcscheme | 77 ++ .../xcschemes/{{NAME}}UnitTests.xcscheme | 52 ++ .../SampleAppSnapshotTests.swift | 21 + .../SampleAppUnitTests.swift | 14 + 40 files changed, 2590 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 .swiftlint.yml create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 Podfile create mode 100644 README.md create mode 100644 catalog-info.yaml create mode 100644 fastlane/Fastfile create mode 100644 fastlane/README.md create mode 100644 github/workflows/main.yml create mode 100644 github/workflows/publish_pod.yml create mode 100644 github/workflows/update_pod_version.yml create mode 100644 make.sh create mode 160000 submodules/ios-tooling create mode 160000 submodules/mobile-tooling create mode 100644 {{NAME}}.podspec create mode 100644 {{NAME}}/PodSample.swift create mode 100644 {{NAME}}/Tests/Snapshot/PodSnapshotTests.swift create mode 100644 {{NAME}}/Tests/Unit/PodUnitTests.swift create mode 100644 {{NAME}}SampleApp.xcworkspace/contents.xcworkspacedata create mode 100644 {{NAME}}SampleApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 {{NAME}}SampleApp/{{NAME}}/AppDelegate.swift create mode 100644 {{NAME}}SampleApp/{{NAME}}/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 {{NAME}}SampleApp/{{NAME}}/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 {{NAME}}SampleApp/{{NAME}}/Assets.xcassets/Contents.json create mode 100644 {{NAME}}SampleApp/{{NAME}}/AuthTokenProvider+{{NAME}}.swift create mode 100644 {{NAME}}SampleApp/{{NAME}}/Base.lproj/LaunchScreen.storyboard create mode 100644 {{NAME}}SampleApp/{{NAME}}/Info.plist create mode 100644 {{NAME}}SampleApp/{{NAME}}/SnapshotTests.xctestplan create mode 100644 {{NAME}}SampleApp/{{NAME}}/UnitTests.xctestplan create mode 100644 {{NAME}}SampleApp/{{NAME}}/ViewController.swift create mode 100644 {{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/project.pbxproj create mode 100644 {{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 {{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 {{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/xcshareddata/xcschemes/{{NAME}}SampleApp.xcscheme create mode 100644 {{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/xcshareddata/xcschemes/{{NAME}}SnapshotTests.xcscheme create mode 100644 {{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/xcshareddata/xcschemes/{{NAME}}UnitTests.xcscheme create mode 100644 {{NAME}}SampleApp/{{NAME}}SnapshotTests/SampleAppSnapshotTests.swift create mode 100644 {{NAME}}SampleApp/{{NAME}}UnitTests/SampleAppUnitTests.swift diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e37b90a --- /dev/null +++ b/.gitignore @@ -0,0 +1,99 @@ +ci-build-out/ +ci-derived-data/ + +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## User settings +xcuserdata/ + +## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) +*.xcscmblueprint +*.xccheckout + +## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) +build/ +DerivedData/ +*.moved-aside +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 + +## Obj-C/Swift specific +*.hmap + +## App packaging +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +# Package.pins +# Package.resolved +# *.xcodeproj +# +# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata +# hence it is not needed unless you have added a package configuration file to your project +# .swiftpm + +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ +# +# Add this line if you want to avoid checking in source code from the Xcode workspace +# *.xcworkspace + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build/ + +# Accio dependency management +Dependencies/ +.accio/ + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. +# Instead, use fastlane to re-generate the screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/#source-control + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots/**/*.png +fastlane/test_output + +# Code Injection +# +# After new code Injection tools there's a generated folder /iOSInjectionProject +# https://github.com/johnno1962/injectionforxcode + +iOSInjectionProject/ + +# Local bundler installation cache on CI +.bundle/ +vendor/ + +.DS_Store diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e9436dc --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "submodules/ios-tooling"] + path = submodules/ios-tooling + url = git@github.com:sumup/ios-tooling.git +[submodule "submodules/mobile-tooling"] + path = submodules/mobile-tooling + url = git@github.com:sumup/mobile-tooling.git diff --git a/.swiftlint.yml b/.swiftlint.yml new file mode 100644 index 0000000..2060077 --- /dev/null +++ b/.swiftlint.yml @@ -0,0 +1,6 @@ +parent_config: submodules/ios-tooling/SwiftLint/.swiftlint_base.yml +excluded: # paths to ignore during linting. Takes precedence over `included`. + - {{NAME}}SampleApp/Pods +included: + - {{NAME}} + - {{NAME}}SampleApp diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..0161a5e --- /dev/null +++ b/Gemfile @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "cocoapods", "~> 1.11.0" +gem "fastlane", "~> 2.177" +gem "xcode-install", "~> 2.6" +gem 'xcpretty-actions-formatter', '~> 0.1.2' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..4e23057 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,291 @@ +GEM + remote: https://rubygems.org/ + specs: + CFPropertyList (3.0.5) + rexml + activesupport (6.1.6) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) + zeitwerk (~> 2.3) + addressable (2.8.1) + public_suffix (>= 2.0.2, < 6.0) + algoliasearch (1.27.5) + httpclient (~> 2.8, >= 2.8.3) + json (>= 1.5.1) + artifactory (3.0.15) + atomos (0.1.3) + aws-eventstream (1.2.0) + aws-partitions (1.636.0) + aws-sdk-core (3.154.0) + aws-eventstream (~> 1, >= 1.0.2) + aws-partitions (~> 1, >= 1.525.0) + aws-sigv4 (~> 1.1) + jmespath (~> 1, >= 1.6.1) + aws-sdk-kms (1.58.0) + aws-sdk-core (~> 3, >= 3.127.0) + aws-sigv4 (~> 1.1) + aws-sdk-s3 (1.114.0) + aws-sdk-core (~> 3, >= 3.127.0) + aws-sdk-kms (~> 1) + aws-sigv4 (~> 1.4) + aws-sigv4 (1.5.1) + aws-eventstream (~> 1, >= 1.0.2) + babosa (1.0.4) + claide (1.0.3) + cocoapods (1.11.3) + addressable (~> 2.8) + claide (>= 1.0.2, < 2.0) + cocoapods-core (= 1.11.3) + cocoapods-deintegrate (>= 1.0.3, < 2.0) + cocoapods-downloader (>= 1.4.0, < 2.0) + cocoapods-plugins (>= 1.0.0, < 2.0) + cocoapods-search (>= 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.8.0) + nap (~> 1.0) + ruby-macho (>= 1.0, < 3.0) + xcodeproj (>= 1.21.0, < 2.0) + cocoapods-core (1.11.3) + activesupport (>= 5.0, < 7) + addressable (~> 2.8) + algoliasearch (~> 1.0) + concurrent-ruby (~> 1.1) + fuzzy_match (~> 2.0.4) + nap (~> 1.0) + netrc (~> 0.11) + public_suffix (~> 4.0) + typhoeus (~> 1.0) + cocoapods-deintegrate (1.0.5) + cocoapods-downloader (1.6.3) + cocoapods-plugins (1.0.0) + nap + cocoapods-search (1.0.1) + cocoapods-trunk (1.6.0) + nap (>= 0.8, < 2.0) + netrc (~> 0.11) + cocoapods-try (1.2.0) + colored (1.2) + colored2 (3.1.2) + commander (4.6.0) + highline (~> 2.0.0) + concurrent-ruby (1.1.10) + declarative (0.0.20) + digest-crc (0.6.4) + rake (>= 12.0.0, < 14.0.0) + domain_name (0.5.20190701) + unf (>= 0.0.5, < 1.0.0) + dotenv (2.8.1) + emoji_regex (3.2.3) + escape (0.0.4) + ethon (0.15.0) + ffi (>= 1.15.0) + excon (0.92.5) + faraday (1.10.2) + faraday-em_http (~> 1.0) + faraday-em_synchrony (~> 1.0) + faraday-excon (~> 1.1) + faraday-httpclient (~> 1.0) + faraday-multipart (~> 1.0) + faraday-net_http (~> 1.0) + faraday-net_http_persistent (~> 1.0) + faraday-patron (~> 1.0) + faraday-rack (~> 1.0) + faraday-retry (~> 1.0) + ruby2_keywords (>= 0.0.4) + faraday-cookie_jar (0.0.7) + faraday (>= 0.8.0) + http-cookie (~> 1.0.0) + faraday-em_http (1.0.0) + faraday-em_synchrony (1.0.0) + faraday-excon (1.1.0) + faraday-httpclient (1.0.1) + faraday-multipart (1.0.4) + multipart-post (~> 2) + faraday-net_http (1.0.1) + faraday-net_http_persistent (1.2.0) + faraday-patron (1.0.0) + faraday-rack (1.0.0) + faraday-retry (1.0.3) + faraday_middleware (1.2.0) + faraday (~> 1.0) + fastimage (2.2.6) + fastlane (2.210.1) + CFPropertyList (>= 2.3, < 4.0.0) + addressable (>= 2.8, < 3.0.0) + artifactory (~> 3.0) + aws-sdk-s3 (~> 1.0) + babosa (>= 1.0.3, < 2.0.0) + bundler (>= 1.12.0, < 3.0.0) + colored + commander (~> 4.6) + dotenv (>= 2.1.1, < 3.0.0) + emoji_regex (>= 0.1, < 4.0) + excon (>= 0.71.0, < 1.0.0) + faraday (~> 1.0) + faraday-cookie_jar (~> 0.0.6) + faraday_middleware (~> 1.0) + fastimage (>= 2.1.0, < 3.0.0) + gh_inspector (>= 1.1.2, < 2.0.0) + google-apis-androidpublisher_v3 (~> 0.3) + google-apis-playcustomapp_v1 (~> 0.1) + google-cloud-storage (~> 1.31) + highline (~> 2.0) + json (< 3.0.0) + jwt (>= 2.1.0, < 3) + mini_magick (>= 4.9.4, < 5.0.0) + multipart-post (~> 2.0.0) + naturally (~> 2.2) + optparse (~> 0.1.1) + plist (>= 3.1.0, < 4.0.0) + rubyzip (>= 2.0.0, < 3.0.0) + security (= 0.1.3) + simctl (~> 1.6.3) + terminal-notifier (>= 2.0.0, < 3.0.0) + terminal-table (>= 1.4.5, < 2.0.0) + tty-screen (>= 0.6.3, < 1.0.0) + tty-spinner (>= 0.8.0, < 1.0.0) + word_wrap (~> 1.0.0) + xcodeproj (>= 1.13.0, < 2.0.0) + xcpretty (~> 0.3.0) + xcpretty-travis-formatter (>= 0.0.3) + ffi (1.15.5) + fourflusher (2.3.1) + fuzzy_match (2.0.4) + gh_inspector (1.1.3) + google-apis-androidpublisher_v3 (0.28.0) + google-apis-core (>= 0.9.0, < 2.a) + google-apis-core (0.9.0) + addressable (~> 2.5, >= 2.5.1) + googleauth (>= 0.16.2, < 2.a) + httpclient (>= 2.8.1, < 3.a) + mini_mime (~> 1.0) + representable (~> 3.0) + retriable (>= 2.0, < 4.a) + rexml + webrick + google-apis-iamcredentials_v1 (0.15.0) + google-apis-core (>= 0.9.0, < 2.a) + google-apis-playcustomapp_v1 (0.11.0) + google-apis-core (>= 0.9.0, < 2.a) + google-apis-storage_v1 (0.17.0) + google-apis-core (>= 0.7, < 2.a) + google-cloud-core (1.6.0) + google-cloud-env (~> 1.0) + google-cloud-errors (~> 1.0) + google-cloud-env (1.6.0) + faraday (>= 0.17.3, < 3.0) + google-cloud-errors (1.3.0) + google-cloud-storage (1.42.0) + addressable (~> 2.8) + digest-crc (~> 0.4) + google-apis-iamcredentials_v1 (~> 0.1) + google-apis-storage_v1 (~> 0.17.0) + google-cloud-core (~> 1.6) + googleauth (>= 0.16.2, < 2.a) + mini_mime (~> 1.0) + googleauth (1.2.0) + faraday (>= 0.17.3, < 3.a) + jwt (>= 1.4, < 3.0) + memoist (~> 0.16) + multi_json (~> 1.11) + os (>= 0.9, < 2.0) + signet (>= 0.16, < 2.a) + highline (2.0.3) + http-cookie (1.0.5) + domain_name (~> 0.5) + httpclient (2.8.3) + i18n (1.10.0) + concurrent-ruby (~> 1.0) + jmespath (1.6.1) + json (2.6.2) + jwt (2.5.0) + memoist (0.16.2) + mini_magick (4.11.0) + mini_mime (1.1.2) + minitest (5.16.2) + molinillo (0.8.0) + multi_json (1.15.0) + multipart-post (2.0.0) + nanaimo (0.3.0) + nap (1.1.0) + naturally (2.2.1) + netrc (0.11.0) + optparse (0.1.1) + os (1.1.4) + plist (3.6.0) + public_suffix (4.0.7) + rake (13.0.6) + representable (3.2.0) + declarative (< 0.1.0) + trailblazer-option (>= 0.1.1, < 0.2.0) + uber (< 0.2.0) + retriable (3.1.2) + rexml (3.2.5) + rouge (2.0.7) + ruby-macho (2.5.1) + ruby2_keywords (0.0.5) + rubyzip (2.3.2) + security (0.1.3) + signet (0.17.0) + addressable (~> 2.8) + faraday (>= 0.17.5, < 3.a) + jwt (>= 1.5, < 3.0) + multi_json (~> 1.10) + simctl (1.6.8) + CFPropertyList + naturally + terminal-notifier (2.0.0) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + trailblazer-option (0.1.2) + tty-cursor (0.7.1) + tty-screen (0.8.1) + tty-spinner (0.9.3) + tty-cursor (~> 0.7) + typhoeus (1.4.0) + ethon (>= 0.9.0) + tzinfo (2.0.4) + concurrent-ruby (~> 1.0) + uber (0.1.0) + unf (0.1.4) + unf_ext + unf_ext (0.0.8.2) + unicode-display_width (1.8.0) + webrick (1.7.0) + word_wrap (1.0.0) + xcode-install (2.8.0) + claide (>= 0.9.1, < 1.1.0) + fastlane (>= 2.1.0, < 3.0.0) + xcodeproj (1.22.0) + CFPropertyList (>= 2.3.3, < 4.0) + atomos (~> 0.1.3) + claide (>= 1.0.2, < 2.0) + colored2 (~> 3.1) + nanaimo (~> 0.3.0) + rexml (~> 3.2.4) + xcpretty (0.3.0) + rouge (~> 2.0.7) + xcpretty-actions-formatter (0.1.2) + xcpretty (~> 0.2) + xcpretty-travis-formatter (1.0.1) + xcpretty (~> 0.2, >= 0.0.7) + zeitwerk (2.6.0) + +PLATFORMS + ruby + +DEPENDENCIES + cocoapods (~> 1.11.0) + fastlane (~> 2.177) + xcode-install (~> 2.6) + xcpretty-actions-formatter (~> 0.1.2) + +BUNDLED WITH + 2.3.10 diff --git a/Podfile b/Podfile new file mode 100644 index 0000000..6f4a454 --- /dev/null +++ b/Podfile @@ -0,0 +1,49 @@ +platform :ios, '12.0' + +project '{{NAME}}SampleApp/{{NAME}}SampleApp.xcproj' + +source "git@github.com:sumup/cocoapods-specs.git" +source 'https://cdn.cocoapods.org' + +load "submodules/ios-tooling/cocoapods/Podfile-Helper.rb" + +target '{{NAME}}SampleApp' do + + inhibit_all_warnings! + use_frameworks! + + pod '{{NAME}}', :path => '.', :inhibit_warnings => false + pod 'SMPIdentity', '~> 0.2.22', :subspecs => ['SampleAppIntegration'] + + target '{{NAME}}UnitTests' do + inherit! :search_paths + end + + target '{{NAME}}SnapshotTests' do + inherit! :search_paths + pod 'SumUpSnapshotTesting' + end +end + +post_install do |installer| + remove_mac_catalyst_support(installer) + fix_deployment_target(installer) + fix_last_upgrade_check(installer) +end + +def remove_mac_catalyst_support(installer) + apply_settings_to_generated_projects(installer, { + 'SUPPORTS_MACCATALYST' => 'NO', + 'SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD' => 'NO' + }) +end + +def apply_settings_to_generated_projects(installer, build_settings) + installer.generated_projects.each do |project| + project.build_configurations.each do |config| + build_settings.each do |key, value| + config.build_settings[key] = value + end + end + end +end diff --git a/README.md b/README.md new file mode 100644 index 0000000..b175d07 --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# iOS Feature/Service Template + +An iOS project for quickly creating new pods, with both a `Service` and a +`Feature` subspecs. + +## Features +- SampleApp +- SnapshotTests +- Swiftlint +- Fastlane +- Github Actions + +## Usage + +To get started, create a new repository based on this repository. You can do +this directly on GitHub, by using the "**Use this template**" button at the top +of the page, or just by [clicking +here](https://github.com/sumup/ios-pod-template/generate). + +--- + +1. Run the `make.sh` command inside the repository, and follow the prompts. + +## Contributing + +This repo is meant to evolve. Anyone is more than welcome to open a pull-request +to add features they may want to see. diff --git a/catalog-info.yaml b/catalog-info.yaml new file mode 100644 index 0000000..ffe24d8 --- /dev/null +++ b/catalog-info.yaml @@ -0,0 +1,78 @@ +# Catalog Service template +# Please follow all comments to update values. +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + # Name of the service, required + name: ios-pod-template + # Human readable version of the name of the service, required + title: Ios Pod Template + # Short and crisp description of the service, required + description: An iOS project for quickly creating new pods. + annotations: + # Slug of the GitHub repo, required + github.com/project-slug: sumup/ios-pod-template + # Location of the mkdocs.yml file, optional + #backstage.io/techdocs-ref: dir:./docs + # Tags that identify the service by characteristics, required: + # - pii, if service deals with personal identifiable information) + # - pci, if service is located in the PCI zone (deals with payments related data) + # - critical-path, if service needs immediate response in case of incident + # - externally-exposed, if API is reachable through wwww + # Example: [critical-path, pii] + tags: [ ] + links: [ ] + # Link to Alerts Runbook, required + #- title: Alerts Runbook + # url: https://sumupteam.atlassian.net/wiki/spaces/DEV/pages/2517664574/Ecom+Platform+Squad+Runbook + # Link to Confluence Team page, optional + #- title: Confluence Page + # url: https://sumupteam.atlassian.net/wiki/spaces/DEV/pages/554239270/Ecom+Platform+Squad + # Link to Slack channel for service alerts, required + #- title: Slack Alert Channel + # url: https://sumup.slack.com/archives/CC1GHFV3P + # Link to Slack support channel for service (e.g. team/squad channel), required + #- title: Slack Support Channel + # url: https://sumup.slack.com/archives/CC1GHFV3P + # Link to Grafana dashboards, recommended + #- title: Grafana + # url: https://grafana.sam-app.ro/dashboards/f/yN_aXbBGz/ecom-platform + # type: telemetry + # Link to Honeycomb dashboards, recommended + #- title: Honeycomb + # url: https://ui.honeycomb.io/sumup/board/A3ThTUE4rXf/Ecom-Platform + # type: telemetry +spec: + # Defines the type of Component (service, website, library, see https://backstage.io/docs/features/software-catalog/descriptor-format#spectype-required), required + type: unspecified + # Marks the state of the service (production, experimental, deprecated, see https://backstage.io/docs/features/software-catalog/descriptor-format#speclifecycle-required), required + lifecycle: unspecified + # GitHub team owner, see https://github.com/orgs/sumup/teams, required + owner: unspecified + # The system this Component is part of, recommended + system: unspecified + # List of API's the service exposes, reference name from the API definition section below, required + # If adding the API's is a blocker, slack #backstage to get our help + providesApis: [ ] + # List of API's the service is connected to, see openapi or https://sumup.roadie.so/api-docs, required + consumesApis: [ ] +#--- +# API definition example +#apiVersion: backstage.io/v1alpha1 +#kind: API +#metadata: +# name: ios-pod-template-api +# title: Ios Pod Template API +# # add [externally-exposed] if API is reachable through wwww, required if applicable +# tags: [ ] +# # API description, required +# description: | +# Sample API description. +#spec: +# type: openapi +# # Marks the state of the API (production, experimental, deprecated, see https://backstage.io/docs/features/software-catalog/descriptor-format#speclifecycle-required), required +# lifecycle: unspecified +# # Github team owner, see https://github.com/orgs/sumup/teams, required +# owner: unspecified +# definition: +# $text: https://github.com/sumup/ecom-platform/blob/master/apps/vatcalculator/docs/index.yaml diff --git a/fastlane/Fastfile b/fastlane/Fastfile new file mode 100644 index 0000000..b780b78 --- /dev/null +++ b/fastlane/Fastfile @@ -0,0 +1,20 @@ +# This file contains the fastlane.tools configuration +# You can find the documentation at https://docs.fastlane.tools +# +# For a list of all available actions, check out +# +# https://docs.fastlane.tools/actions +# +# For a list of all available plugins, check out +# +# https://docs.fastlane.tools/plugins/available-plugins +# + +import('../submodules/ios-tooling/fastlane/FastlaneHelpers.rb') +import('../submodules/ios-tooling/fastlane/FastlanePodHelpers.rb') + +before_all do + ENV[SumUpEnv::WORKSPACE] = '{{NAME}}SampleApp.xcworkspace' + ENV[SumUpEnv::SCHEME] = '{{NAME}}SampleApp' + ENV[SumUpEnv::PODSPEC] = '{{NAME}}' +end diff --git a/fastlane/README.md b/fastlane/README.md new file mode 100644 index 0000000..1790884 --- /dev/null +++ b/fastlane/README.md @@ -0,0 +1,225 @@ +fastlane documentation +---- + +# Installation + +Make sure you have the latest version of the Xcode command line tools installed: + +```sh +xcode-select --install +``` + +For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane) + +# Available Actions + +### sumup_ci_setup + +```sh +[bundle exec] fastlane sumup_ci_setup +``` + +Set up CI + +### sumup_swiftlint + +```sh +[bundle exec] fastlane sumup_swiftlint +``` + +Lint project into ci-build-out/swiftlint.result + +Parameters: + +- reporter: Choose output reporter. Available: xcode, json, csv, checkstyle, codeclimate, junit, html, emoji, sonarqube, markdown, github-actions-logging. Default: junit + +- disable_failure: Boolean indicating if the lane should fail if linting has errors. + +- config_file: The path to the config file. Defaults to #{HelperDefaults.instance.default_swiftlint_config} + +- output_file: Path to output SwiftLint result. Defaults to `#{HelperDefaults.instance.default_artifact_dir}/swiftlint.result` + +### sumup_build + +```sh +[bundle exec] fastlane sumup_build +``` + +Build a project with necessary setup + +Parameters: + +- workspace: Path to the workspace file. + +- project: Path to the project file. + +- scheme: The name of the scheme to run the tests on. + +### sumup_test_run + +```sh +[bundle exec] fastlane sumup_test_run +``` + +Run unit tests and do the necessary cleanups afterwards + +Parameters: + +- workspace: Path to the workspace file. + +- project: Path to the project file. + +- scheme: The name of the scheme to run the tests on. + +- code_coverage: Should code coverage be generated? Defaults to false. + +- clean: Should the project be cleaned before building it? Defaults to true. + +- force_x86_64_build: Should we make sure to build for x86_64? Defaults to false + +- result_bundle: Should an Xcode result bundle be generated in the output directory? Defaults to false + +- device: Specify a simulator device. Defaults to iPhone 8 + +- device_os_version: Specify a simulator version. Defaults to 14.2 + +- output_files: Specify the test output file + +### sumup_lint_pod + +```sh +[bundle exec] fastlane sumup_lint_pod +``` + +Lint the pod + +Parameters: + +- pod : The name of the podspec to use. Defaults to the value of the `PodHelperDefaults.instance.podspec` variable. + +- quick : Indicates if only quick linting should be done without building. Defaults to true. + +### sumup_test_pod + +```sh +[bundle exec] fastlane sumup_test_pod +``` + +Run pod tests + +Parameters: + +- pod : The name of the pod to use. Defaults to the value of the `PodHelperDefaults.instance.podspec` variable. + +### sumup_publish_pod + +```sh +[bundle exec] fastlane sumup_publish_pod +``` + +Publish the Pod to our private repo + +Parameters: + +- pod : The name of the pod to use. Defaults to the value of the `PodHelperDefaults.instance.podspec` variable. + +- repo : The name of the sumup repository in your local configuration. Defaults to `sumup-private` + +### sumup_bump_pod_version + +```sh +[bundle exec] fastlane sumup_bump_pod_version +``` + +Bump and commit the version number of the Pod. If no exact version is provided, it will bump the podspec automatically. + +Parameters: + +- pod : The name of the pod to use. Defaults to the value of the `PodHelperDefaults.instance.podspec` variable. + +- bump_type: The type of this version bump. Available: patch, minor, major. Default: patch + +- version_number: Change to a specific version. This will replace the bump type value. E.g. "1.2.3" + +- create_branch: Bool indicating whether to create a new branch for the version update or not. Default: false + +- tag_commit: Bool indicating whether to tag the commit or not. Default: false + +- push_commit: Bool indicating whether to push the commit (and the tag) or not. Default: false + +### sumup_slack_publish_version_result + +```sh +[bundle exec] fastlane sumup_slack_publish_version_result +``` + +Send Slack message with the publish result. + +Parameters: + +- podspec: The name of the podspec without extension. Required. + +- success: Bool indicating the status of the publish. Required. + +### sumup_distribute_preview_app + +```sh +[bundle exec] fastlane sumup_distribute_preview_app +``` + +Upload preview app to AppCenter. + +Requires: + +- the `appcenter` plugin to be installed: `bundle exec fastlane add_plugin appcenter` + +- `APP_CENTER_TOKEN` environment variable to be set + +- `MATCH_GIT_BASIC_AUTHORIZATION` environment variable to be set + +- `MATCH_PASSWORD` environment variable to be set + +Parameters: + +- scheme: Name of the scheme that builds the preview app. Required. + +- bundle_id: Bundle id of the application. Required. + +- pod_name: Name of the pod. Defaults to `PodHelperDefaults.instance.podspec`. + +- app_center_name: Name of the app in AppCenter. Defaults to `scheme`. + +- project_target: Name of the target that builds the preview app. Defaults to `scheme`. + +- project_path: Path to the directory containing the project. Defaults to `.`. + +- workspace_path: Path to the workspace relative to `project_path`. Defaults to `scheme`.xcworkspace. + +- xcodeproj_path: Path to the xcodeproj relative to `project_path`. Defaults to `scheme`.xcodeproj. + +- plist_path: Path to the plist relative to `project_path`. Defaults to `scheme`/Info.plist. + +- certificates_repo: URL to the match certificates repo. Defaults to `PodHelperDefaults.instance.certificates_repo` + +- changelog: Changelog to use for release. Defaults to commit history since last tag. + +---- + + +## iOS + +### ios test_sample_app + +```sh +[bundle exec] fastlane ios test_sample_app +``` + +Run unit tests of the sample app + +---- + +This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run. + +More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools). + +The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools). diff --git a/github/workflows/main.yml b/github/workflows/main.yml new file mode 100644 index 0000000..e34ea71 --- /dev/null +++ b/github/workflows/main.yml @@ -0,0 +1,36 @@ +name: Build and test + +on: + push: + branches: [ main ] + pull_request: + types: [opened, synchronize, reopened, unlabeled] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build-and-test: + timeout-minutes: 30 + name: Build and test + if: | + github.event_name != 'pull_request' || + ( + !contains(github.event.pull_request.labels.*.name, format('ci{0} none', ':')) && + (github.event.action != 'unlabeled' || github.event.label.name == format('ci{0} none', ':')) + ) + runs-on: macos-12 + + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + token: ${{ secrets.GH_ACTIONS_PAT }} + submodules: recursive + + - name: Run Pod Tests + uses: ./submodules/ios-tooling/gh-actions/run-pod-tests + with: + ssh-key: ${{ secrets.ACTIONS_SSH_AGENT_KEY }} + failed-snapshots-dir: submodules/snapshots/specs/ diff --git a/github/workflows/publish_pod.yml b/github/workflows/publish_pod.yml new file mode 100644 index 0000000..9b89d94 --- /dev/null +++ b/github/workflows/publish_pod.yml @@ -0,0 +1,27 @@ +name: Publish Pod + +on: + push: + tags: + # Trigger on semantic version tags 'x.y' or 'x.y.z' + - '[0-9]+.[0-9]+' + - '[0-9]+.[0-9]+.[0-9]+' + +jobs: + pod-publish: + name: Publish Pod + runs-on: macos-12 + timeout-minutes: 20 + + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + token: ${{ secrets.GH_ACTIONS_PAT }} + submodules: recursive + + - name: Publish Pod + uses: ./submodules/ios-tooling/gh-actions/publish-pod + with: + github-token: ${{ secrets.GH_ACTIONS_PAT }} + name: '{{NAME}}' diff --git a/github/workflows/update_pod_version.yml b/github/workflows/update_pod_version.yml new file mode 100644 index 0000000..ba836e6 --- /dev/null +++ b/github/workflows/update_pod_version.yml @@ -0,0 +1,27 @@ +name: Update pod version + +on: + workflow_dispatch: + inputs: + version: + description: 'The version number to use to update the pod. If not provided, the patch version will be incremented.' + required: false + default: '' + +jobs: + update_pod_version: + name: Update pod version + runs-on: ubuntu-20.04 + timeout-minutes: 5 + + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + token: ${{ secrets.GH_ACTIONS_PAT }} + submodules: recursive + + - name: Update pod version + uses: ./submodules/ios-tooling/gh-actions/update-pod-version + with: + version: ${{ github.event.inputs.version }} diff --git a/make.sh b/make.sh new file mode 100644 index 0000000..eb80f36 --- /dev/null +++ b/make.sh @@ -0,0 +1,81 @@ +#!/bin/sh +set -e + +readonly WORKING_DIR=$(cd -P -- "$(dirname -- "$0")" && pwd -P) + +# Prompty user for information + +echo "Please enter the name of your module:" +read NAME +echo "Please enter a brief summary of your module:" +read SUMMARY +echo "Please enter your name, as the author:" +read AUTHOR +echo "Please enter your team name, as the codeowner (eg: @sumup/online-payments-bifrost):" +read CODEOWNER + +read YEAR MONTH DAY <<<$(date +'%Y %m %d') + +GIT_PATH=$(git remote -v | grep fetch | sed 's/origin\tgit@github.com://' | sed 's/ (fetch)//') + +echo + +# Trim spaces in APP_NAME +readonly NAME_NO_SPACES=$(echo "$NAME" | sed "s/ //g") + +# Rename files structure +echo ">>> 🔎 Replacing files structure" + +## user define function +rename(){ + local DIR=$1 + local NEW_DIR=$2 + mv $DIR $NEW_DIR +} + +readonly NAME_PLACEHOLDER="{{NAME}}" +readonly SUMMARY_PLACEHOLDER="{{SUMMARY}}" +readonly AUTHOR_PLACEHOLDER="{{AUTHOR}}" +readonly GIT_PATH_PLACEHOLDER="{{GIT_PATH}}" +readonly DAY_PLACEHOLDER="{{DAY}}" +readonly MONTH_PLACEHOLDER="{{MONTH}}" +readonly YEAR_PLACEHOLDER="{{YEAR}}" + +rename "${NAME_PLACEHOLDER}" "${NAME_NO_SPACES}" +rename "${NAME_PLACEHOLDER}.podspec" "${NAME_NO_SPACES}.podspec" +rename "${NAME_PLACEHOLDER}SampleApp/${NAME_PLACEHOLDER}/AuthTokenProvider+${NAME_PLACEHOLDER}.swift" "${NAME_PLACEHOLDER}SampleApp/${NAME_PLACEHOLDER}/AuthTokenProvider+${NAME_NO_SPACES}.swift" +rename "${NAME_PLACEHOLDER}SampleApp/${NAME_PLACEHOLDER}" "${NAME_PLACEHOLDER}SampleApp/${NAME_NO_SPACES}" +rename "${NAME_PLACEHOLDER}SampleApp/${NAME_PLACEHOLDER}SampleApp.xcodeproj/xcshareddata/xcschemes/${NAME_PLACEHOLDER}SampleApp.xcscheme" "${NAME_PLACEHOLDER}SampleApp/${NAME_PLACEHOLDER}SampleApp.xcodeproj/xcshareddata/xcschemes/${NAME_NO_SPACES}SampleApp.xcscheme" +rename "${NAME_PLACEHOLDER}SampleApp/${NAME_PLACEHOLDER}SampleApp.xcodeproj/xcshareddata/xcschemes/${NAME_PLACEHOLDER}SnapshotTests.xcscheme" "${NAME_PLACEHOLDER}SampleApp/${NAME_PLACEHOLDER}SampleApp.xcodeproj/xcshareddata/xcschemes/${NAME_NO_SPACES}SnapshotTests.xcscheme" +rename "${NAME_PLACEHOLDER}SampleApp/${NAME_PLACEHOLDER}SampleApp.xcodeproj/xcshareddata/xcschemes/${NAME_PLACEHOLDER}UnitTests.xcscheme" "${NAME_PLACEHOLDER}SampleApp/${NAME_PLACEHOLDER}SampleApp.xcodeproj/xcshareddata/xcschemes/${NAME_NO_SPACES}UnitTests.xcscheme" +rename "${NAME_PLACEHOLDER}SampleApp/${NAME_PLACEHOLDER}SampleApp.xcodeproj" "${NAME_PLACEHOLDER}SampleApp/${NAME_NO_SPACES}SampleApp.xcodeproj" +rename "${NAME_PLACEHOLDER}SampleApp.xcworkspace" "${NAME_NO_SPACES}SampleApp.xcworkspace" +rename "${NAME_PLACEHOLDER}SampleApp/${NAME_PLACEHOLDER}SnapshotTests" "${NAME_PLACEHOLDER}SampleApp/${NAME_NO_SPACES}SnapshotTests" +rename "${NAME_PLACEHOLDER}SampleApp/${NAME_PLACEHOLDER}UnitTests" "${NAME_PLACEHOLDER}SampleApp/${NAME_NO_SPACES}UnitTests" +rename "${NAME_PLACEHOLDER}SampleApp" "${NAME_NO_SPACES}SampleApp" + +# Search and replace in files +echo ">>> 🔎 Replacing placeholders within files..." +LC_ALL=C find $WORKING_DIR -not -path '*/\.git*' -type f -exec sed -i "" "s/${NAME_PLACEHOLDER}/${NAME}/g" {} + +LC_ALL=C find $WORKING_DIR -not -path '*/\.git*' -type f -exec sed -i "" "s/${SUMMARY_PLACEHOLDER}/${SUMMARY}/g" {} + +LC_ALL=C find $WORKING_DIR -not -path '*/\.git*' -type f -exec sed -i "" "s/${AUTHOR_PLACEHOLDER}/${AUTHOR}/g" {} + +LC_ALL=C find $WORKING_DIR -not -path '*/\.git*' -type f -exec sed -i "" "s/${DAY_PLACEHOLDER}/${DAY}/g" {} + +LC_ALL=C find $WORKING_DIR -not -path '*/\.git*' -type f -exec sed -i "" "s/${MONTH_PLACEHOLDER}/${MONTH}/g" {} + +LC_ALL=C find $WORKING_DIR -not -path '*/\.git*' -type f -exec sed -i "" "s/${YEAR_PLACEHOLDER}/${YEAR}/g" {} + +LC_ALL=C find $WORKING_DIR -not -path '*/\.git*' -type f -exec sed -i "" "s;${GIT_PATH_PLACEHOLDER};${GIT_PATH};g" {} + +echo ">>> ✅ Completed" + +echo ">>> 💎 Installing gems" +bundle install +echo ">>> 🧩 Installing submodules" +git submodule update --init --recursive +echo ">>> 🍫 Installing pod dependencies" +bundle exec pod install --repo-update + +# Update scripts +echo ">>> 🗑 Removing script files" +rm -rf make.sh +mv github .github +echo "* $CODEOWNER" > ".github/CODEOWNERS" + +echo ">>> ✅ Completed" diff --git a/submodules/ios-tooling b/submodules/ios-tooling new file mode 160000 index 0000000..270a4dc --- /dev/null +++ b/submodules/ios-tooling @@ -0,0 +1 @@ +Subproject commit 270a4dc5c729f4ff562c33e6e5e4cf9b238241ab diff --git a/submodules/mobile-tooling b/submodules/mobile-tooling new file mode 160000 index 0000000..1e31634 --- /dev/null +++ b/submodules/mobile-tooling @@ -0,0 +1 @@ +Subproject commit 1e316340b11f3d17ca2fe9ac49caffe2d1199e4b diff --git a/{{NAME}}.podspec b/{{NAME}}.podspec new file mode 100644 index 0000000..1923f7b --- /dev/null +++ b/{{NAME}}.podspec @@ -0,0 +1,23 @@ +Pod::Spec.new do |s| + s.name = '{{NAME}}' + s.version = '0.0.1' + s.summary = '{{SUMMARY}}' + + s.homepage = 'https://github.com/{{GIT_PATH}}' + s.license = { :type => 'Proprietary', :text => 'Copyright {{YEAR}} SumUp' } + s.author = 'SumUp' + s.source = { :git => 'git@github.com:{{GIT_PATH}}', :tag => s.version.to_s } + + s.swift_versions = ['5.3'] + + s.platform = :ios + s.ios.deployment_target = '12.0' + + s.dependency 'SMPCrashReporting', '~> 1.2.0' + s.dependency 'SMPLogging', '~> 1.0.2' + + s.source_files = ['{{NAME}}/**/*.{swift}'] + s.exclude_files = ['{{NAME}}/Tests/**/*'] + + s.resource_bundle = { "{{NAME}}Resources" => ["{{NAME}}/**/*.{lproj,xcassets,strings}"] } +end diff --git a/{{NAME}}/PodSample.swift b/{{NAME}}/PodSample.swift new file mode 100644 index 0000000..3b36431 --- /dev/null +++ b/{{NAME}}/PodSample.swift @@ -0,0 +1,10 @@ +// +// PodSample.swift +// {{NAME}} +// +// Created by {{AUTHOR}} on {{DAY}}.{{MONTH}}.{{YEAR}}. +// + +public struct PodSample { + let value = 1 +} diff --git a/{{NAME}}/Tests/Snapshot/PodSnapshotTests.swift b/{{NAME}}/Tests/Snapshot/PodSnapshotTests.swift new file mode 100644 index 0000000..cfb25fe --- /dev/null +++ b/{{NAME}}/Tests/Snapshot/PodSnapshotTests.swift @@ -0,0 +1,24 @@ +// +// PodSnapshotTests.swift +// {{NAME}} +// +// Created by {{AUTHOR}} on {{DAY}}.{{MONTH}}.{{YEAR}}. +// + +import SumUpSnapshotTesting +import XCTest + +@testable import {{NAME}} + +final class PodSnapshotTests: SumUpSnapshotTestCase { + override func setUp() { + super.setUp() + // set to true to update the references images + recordMode = false + } + + func testSample() { + let sut = PodSample() + XCTAssertEqual(sut.value, 1) + } +} diff --git a/{{NAME}}/Tests/Unit/PodUnitTests.swift b/{{NAME}}/Tests/Unit/PodUnitTests.swift new file mode 100644 index 0000000..3ce0706 --- /dev/null +++ b/{{NAME}}/Tests/Unit/PodUnitTests.swift @@ -0,0 +1,17 @@ +// +// PodUnitTests.swift +// {{NAME}} +// +// Created by {{AUTHOR}} on {{DAY}}.{{MONTH}}.{{YEAR}}. +// + +import XCTest + +@testable import {{NAME}} + +final class PodUnitTests: XCTestCase { + func testSample() { + let sut = PodSample() + XCTAssertEqual(sut.value, 1) + } +} diff --git a/{{NAME}}SampleApp.xcworkspace/contents.xcworkspacedata b/{{NAME}}SampleApp.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..30d60ca --- /dev/null +++ b/{{NAME}}SampleApp.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/{{NAME}}SampleApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/{{NAME}}SampleApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/{{NAME}}SampleApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/{{NAME}}SampleApp/{{NAME}}/AppDelegate.swift b/{{NAME}}SampleApp/{{NAME}}/AppDelegate.swift new file mode 100644 index 0000000..e6cacb3 --- /dev/null +++ b/{{NAME}}SampleApp/{{NAME}}/AppDelegate.swift @@ -0,0 +1,33 @@ +// +// AppDelegate.swift +// {{NAME}} +// +// Created by {{AUTHOR}} on {{DAY}}.{{MONTH}}.{{YEAR}}. +// + +import SMPIdentity +import UIKit + +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + window = UIWindow(frame: UIScreen.main.bounds) + let rootViewController = ViewController() + let navigationController = UINavigationController(rootViewController: rootViewController) + window?.rootViewController = navigationController + window?.makeKeyAndVisible() + + AppAuthService.setup(infoProvider: InfoProviderDefault.shared) + return true + } + + func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool { + if AppAuthService.shared.handleResponse(url: url) { + return true + } + return false + } +} diff --git a/{{NAME}}SampleApp/{{NAME}}/Assets.xcassets/AccentColor.colorset/Contents.json b/{{NAME}}SampleApp/{{NAME}}/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/{{NAME}}SampleApp/{{NAME}}/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/{{NAME}}SampleApp/{{NAME}}/Assets.xcassets/AppIcon.appiconset/Contents.json b/{{NAME}}SampleApp/{{NAME}}/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..9221b9b --- /dev/null +++ b/{{NAME}}SampleApp/{{NAME}}/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/{{NAME}}SampleApp/{{NAME}}/Assets.xcassets/Contents.json b/{{NAME}}SampleApp/{{NAME}}/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/{{NAME}}SampleApp/{{NAME}}/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/{{NAME}}SampleApp/{{NAME}}/AuthTokenProvider+{{NAME}}.swift b/{{NAME}}SampleApp/{{NAME}}/AuthTokenProvider+{{NAME}}.swift new file mode 100644 index 0000000..b78cd43 --- /dev/null +++ b/{{NAME}}SampleApp/{{NAME}}/AuthTokenProvider+{{NAME}}.swift @@ -0,0 +1,31 @@ +// +// AuthTokenProvider+{{NAME}}.swift +// {{NAME}} +// +// Created by {{AUTHOR}} on {{DAY}}.{{MONTH}}.{{YEAR}}. +// + +import SMPIdentity + +class LegacyTokenProvider: AuthTokenProvider { + static let shared: LegacyTokenProvider = .init() + + var token: String? + + func getToken(resultBlock: @escaping GetTokenResultBlock) { + guard let token = token else { + resultBlock(.failure(.notLoggedIn)) + return + } + resultBlock(.success(token)) + } +} + +class InfoProviderDefault: AppAuthInfoProvider { + static let shared = InfoProviderDefault() + + var email: String? + var preferredLanguages: [String]? + var deviceId: String? + var keyId: String? +} diff --git a/{{NAME}}SampleApp/{{NAME}}/Base.lproj/LaunchScreen.storyboard b/{{NAME}}SampleApp/{{NAME}}/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..0e5e537 --- /dev/null +++ b/{{NAME}}SampleApp/{{NAME}}/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/{{NAME}}SampleApp/{{NAME}}/Info.plist b/{{NAME}}SampleApp/{{NAME}}/Info.plist new file mode 100644 index 0000000..a8624ed --- /dev/null +++ b/{{NAME}}SampleApp/{{NAME}}/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSupportsIndirectInputEvents + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/{{NAME}}SampleApp/{{NAME}}/SnapshotTests.xctestplan b/{{NAME}}SampleApp/{{NAME}}/SnapshotTests.xctestplan new file mode 100644 index 0000000..c27b0f7 --- /dev/null +++ b/{{NAME}}SampleApp/{{NAME}}/SnapshotTests.xctestplan @@ -0,0 +1,42 @@ +{ + "configurations" : [ + { + "id" : "F8124260-5062-4A64-8D3B-8133967B70E1", + "name" : "Configuration 1", + "options" : { + + } + } + ], + "defaultOptions" : { + "commandLineArgumentEntries" : [ + + ], + "environmentVariableEntries" : [ + { + "key" : "IMAGE_DIFF_DIR", + "value" : "$(SOURCE_ROOT)\/..\/{{NAME}}\/Tests\/Snapshot\/specs\/FailureDiffs" + }, + { + "key" : "FB_REFERENCE_IMAGE_DIR", + "value" : "$(SOURCE_ROOT)\/..\/{{NAME}}\/Tests\/Snapshot\/specs\/ReferenceImages" + } + ], + "targetForVariableExpansion" : { + "containerPath" : "container:{{NAME}}SampleApp.xcodeproj", + "identifier" : "C46929E825F28DCC0037E096", + "name" : "{{NAME}}SampleApp" + }, + "testTimeoutsEnabled" : true + }, + "testTargets" : [ + { + "target" : { + "containerPath" : "container:{{NAME}}SampleApp.xcodeproj", + "identifier" : "E032B10C28D878F4005DAD27", + "name" : "{{NAME}}SnapshotTests" + } + } + ], + "version" : 1 +} diff --git a/{{NAME}}SampleApp/{{NAME}}/UnitTests.xctestplan b/{{NAME}}SampleApp/{{NAME}}/UnitTests.xctestplan new file mode 100644 index 0000000..2fd9285 --- /dev/null +++ b/{{NAME}}SampleApp/{{NAME}}/UnitTests.xctestplan @@ -0,0 +1,24 @@ +{ + "configurations" : [ + { + "id" : "B08D9F2E-050E-4307-B725-793F269B8964", + "name" : "Configuration 1", + "options" : { + + } + } + ], + "defaultOptions" : { + + }, + "testTargets" : [ + { + "target" : { + "containerPath" : "container:{{NAME}}SampleApp.xcodeproj", + "identifier" : "E0CA9FBE290683B700072950", + "name" : "{{NAME}}UnitTests" + } + } + ], + "version" : 1 +} diff --git a/{{NAME}}SampleApp/{{NAME}}/ViewController.swift b/{{NAME}}SampleApp/{{NAME}}/ViewController.swift new file mode 100644 index 0000000..513e9f1 --- /dev/null +++ b/{{NAME}}SampleApp/{{NAME}}/ViewController.swift @@ -0,0 +1,103 @@ +// +// ViewController.swift +// {{NAME}} +// +// Created by {{AUTHOR}} on {{DAY}}.{{MONTH}}.{{YEAR}}. +// + +import {{NAME}} +import SMPIdentity +import UIKit + +class ViewController: UIViewController { + private var autoRefreshObservation: AutoRefreshObservation? + + override func viewDidLoad() { + super.viewDidLoad() + + AppAuthService.shared.add(observer: self) + if AppAuthService.shared.loginState.isLoggedIn { + print("Stored login found, trying to get a valid token...") + refreshToken(force: false) + } + setUpViews() + } + + private func setUpViews() { + view.backgroundColor = .white + navigationItem.title = "ViewController" + + setUpLoginButton() + setUpSelectServerButton() + } + + private func setUpSelectServerButton() { + let selectServerButton = UIBarButtonItem(title: String(describing: IdentityServer.current).capitalized, + style: .plain, + target: self, + action: #selector(selectServer)) + navigationItem.leftBarButtonItem = selectServerButton + } + + private func setUpLoginButton() { + let loginButton = IdentityLoginBarButtonItem(presenter: self) + loginButton.statusChangedBlock = { isLoggedIn, error in + switch (isLoggedIn, error) { + case (true, _): + print("Login success") + case let (false, .some(error)): + print("Login failure: \(error.localizedDescription)") + case (false, .none): + print("Logout success") + } + } + navigationItem.rightBarButtonItem = loginButton + } + + @objc private func selectServer() { + let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) + + IdentityServer.allCases.forEach { server in + let action = UIAlertAction(title: String(describing: server).capitalized, + style: .default) { action in + IdentityServer.changeCurrent(server) + self.navigationItem.leftBarButtonItem?.title = action.title + } + actionSheet.addAction(action) + } + let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) + actionSheet.addAction(cancelAction) + present(actionSheet, animated: true) + } + + private func refreshToken(force: Bool) { + AppAuthService.shared.getToken(forceRefresh: force) { [weak self] result in + self?.handleTokenRefreshResult(result: result) + } + } + + private func handleTokenRefreshResult(result: AppAuthService.GetTokenResult) { + switch result { + case let .success(accessToken): + print("Acquired a valid token.") + print("[ACCESS_TOKEN] \(accessToken)") + case let .failure(error): + print("Failed to get a valid token.") + print("[ERROR] \(error)") + } + } +} + +extension ViewController: AutoRefreshObserver { + func didRefresh(accessToken: String) { + print("Token refreshed: \(accessToken)") + } + + func didInvalidateLogin() { + print("Login invalidated") + } + + func didStopAutoRefreshDueToFailure(_ error: Error) { + print("Auto-refresh stopped due to failure: \(error.localizedDescription)") + } +} diff --git a/{{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/project.pbxproj b/{{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/project.pbxproj new file mode 100644 index 0000000..345d0c4 --- /dev/null +++ b/{{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/project.pbxproj @@ -0,0 +1,818 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXBuildFile section */ + 38AAC48420D0AFF22B0FFFB7 /* Pods_{{NAME}}UnitTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 01B6F1CD3CDE5790CE8952B8 /* Pods_{{NAME}}UnitTests.framework */; }; + B9F28797D57827F149B02398 /* Pods_{{NAME}}SnapshotTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8852CE74306EDAC67D83B30B /* Pods_{{NAME}}SnapshotTests.framework */; }; + CD1875EC0668F77E5A4A1F8F /* Pods_{{NAME}}SampleApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D5718AF792674405DE47F3B /* Pods_{{NAME}}SampleApp.framework */; }; + E032B10328D877A4005DAD27 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E032B0FC28D877A4005DAD27 /* ViewController.swift */; }; + E032B10428D877A4005DAD27 /* AuthTokenProvider+{{NAME}}.swift in Sources */ = {isa = PBXBuildFile; fileRef = E032B0FD28D877A4005DAD27 /* AuthTokenProvider+{{NAME}}.swift */; }; + E032B10528D877A4005DAD27 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E032B0FE28D877A4005DAD27 /* Assets.xcassets */; }; + E032B10628D877A4005DAD27 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E032B0FF28D877A4005DAD27 /* LaunchScreen.storyboard */; }; + E032B10728D877A4005DAD27 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E032B10128D877A4005DAD27 /* AppDelegate.swift */; }; + E032B11028D878F4005DAD27 /* SampleAppSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E032B10F28D878F4005DAD27 /* SampleAppSnapshotTests.swift */; }; + E0CA9FC2290683B700072950 /* SampleAppUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0CA9FC1290683B700072950 /* SampleAppUnitTests.swift */; }; + E0CA9FCB2906866300072950 /* PodUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0CA9FCA2906866300072950 /* PodUnitTests.swift */; }; + E0CA9FCD2906867000072950 /* PodSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0CA9FCC2906867000072950 /* PodSnapshotTests.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + E032B11128D878F4005DAD27 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C46929E125F28DCC0037E096 /* Project object */; + proxyType = 1; + remoteGlobalIDString = C46929E825F28DCC0037E096; + remoteInfo = {{NAME}}; + }; + E081E7C528E311B5009BC638 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C46929E125F28DCC0037E096 /* Project object */; + proxyType = 1; + remoteGlobalIDString = C443EC2926208E7D00FEB287; + remoteInfo = SwiftLint; + }; + E08EC9D528E30F1D00E07A8A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C46929E125F28DCC0037E096 /* Project object */; + proxyType = 1; + remoteGlobalIDString = C443EC2926208E7D00FEB287; + remoteInfo = SwiftLint; + }; + E0CA9FC3290683B700072950 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C46929E125F28DCC0037E096 /* Project object */; + proxyType = 1; + remoteGlobalIDString = C46929E825F28DCC0037E096; + remoteInfo = {{NAME}}SampleApp; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 01B6F1CD3CDE5790CE8952B8 /* Pods_{{NAME}}UnitTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_{{NAME}}UnitTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 3E21DCEF1F1447E04421D44C /* Pods-{{NAME}}UnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-{{NAME}}UnitTests.release.xcconfig"; path = "../../Pods/Target Support Files/Pods-{{NAME}}UnitTests/Pods-{{NAME}}UnitTests.release.xcconfig"; sourceTree = ""; }; + 64A330AAADA421FC16B2F3CC /* Pods-{{NAME}}SnapshotTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-{{NAME}}SnapshotTests.debug.xcconfig"; path = "../../Pods/Target Support Files/Pods-{{NAME}}SnapshotTests/Pods-{{NAME}}SnapshotTests.debug.xcconfig"; sourceTree = ""; }; + 8852CE74306EDAC67D83B30B /* Pods_{{NAME}}SnapshotTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_{{NAME}}SnapshotTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 8B701E7714E675D9807A6F5D /* Pods-{{NAME}}UnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-{{NAME}}UnitTests.debug.xcconfig"; path = "../../Pods/Target Support Files/Pods-{{NAME}}UnitTests/Pods-{{NAME}}UnitTests.debug.xcconfig"; sourceTree = ""; }; + 8D5718AF792674405DE47F3B /* Pods_{{NAME}}SampleApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_{{NAME}}SampleApp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9834AABED752121CC05A7D13 /* Pods-{{NAME}}Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-{{NAME}}Tests.debug.xcconfig"; path = "Target Support Files/Pods-{{NAME}}Tests/Pods-{{NAME}}Tests.debug.xcconfig"; sourceTree = ""; }; + B4F5E906324582CED0C4324C /* Pods-{{NAME}}SampleApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-{{NAME}}SampleApp.debug.xcconfig"; path = "../../Pods/Target Support Files/Pods-{{NAME}}SampleApp/Pods-{{NAME}}SampleApp.debug.xcconfig"; sourceTree = ""; }; + C46929E925F28DCC0037E096 /* {{NAME}}SampleApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = {{NAME}}SampleApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + C551972F94B0CEF1567385B7 /* Pods-{{NAME}}SampleApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-{{NAME}}SampleApp.release.xcconfig"; path = "../../Pods/Target Support Files/Pods-{{NAME}}SampleApp/Pods-{{NAME}}SampleApp.release.xcconfig"; sourceTree = ""; }; + CAAFE24845B392E99F14652B /* Pods_{{NAME}}Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_{{NAME}}Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E032B0FC28D877A4005DAD27 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + E032B0FD28D877A4005DAD27 /* AuthTokenProvider+{{NAME}}.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AuthTokenProvider+{{NAME}}.swift"; sourceTree = ""; }; + E032B0FE28D877A4005DAD27 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + E032B10028D877A4005DAD27 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + E032B10128D877A4005DAD27 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + E032B10228D877A4005DAD27 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E032B10D28D878F4005DAD27 /* {{NAME}}SnapshotTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = {{NAME}}SnapshotTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + E032B10F28D878F4005DAD27 /* SampleAppSnapshotTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SampleAppSnapshotTests.swift; path = ../../../{{NAME}}SampleApp/{{NAME}}SnapshotTests/SampleAppSnapshotTests.swift; sourceTree = ""; }; + E0CA9FBF290683B700072950 /* {{NAME}}UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = {{NAME}}UnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + E0CA9FC1290683B700072950 /* SampleAppUnitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SampleAppUnitTests.swift; path = ../../../{{NAME}}SampleApp/{{NAME}}UnitTests/SampleAppUnitTests.swift; sourceTree = ""; }; + E0CA9FCA2906866300072950 /* PodUnitTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PodUnitTests.swift; sourceTree = ""; }; + E0CA9FCC2906867000072950 /* PodSnapshotTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PodSnapshotTests.swift; sourceTree = ""; }; + E0CAA2192906966900072950 /* SnapshotTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = SnapshotTests.xctestplan; sourceTree = ""; }; + E0E5D98928D8C84E00B04B0D /* UnitTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UnitTests.xctestplan; sourceTree = ""; }; + E8AC9E929BE7AC35BC1AF42E /* Pods-{{NAME}}SnapshotTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-{{NAME}}SnapshotTests.release.xcconfig"; path = "../../Pods/Target Support Files/Pods-{{NAME}}SnapshotTests/Pods-{{NAME}}SnapshotTests.release.xcconfig"; sourceTree = ""; }; + F57A4770029E0756A5DED034 /* Pods-{{NAME}}Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-{{NAME}}Tests.release.xcconfig"; path = "Target Support Files/Pods-{{NAME}}Tests/Pods-{{NAME}}Tests.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + C46929E625F28DCC0037E096 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + CD1875EC0668F77E5A4A1F8F /* Pods_{{NAME}}SampleApp.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E032B10A28D878F4005DAD27 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + B9F28797D57827F149B02398 /* Pods_{{NAME}}SnapshotTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E0CA9FBC290683B700072950 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 38AAC48420D0AFF22B0FFFB7 /* Pods_{{NAME}}UnitTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 72DB137664A5B936DFEBD325 /* Pods */ = { + isa = PBXGroup; + children = ( + B4F5E906324582CED0C4324C /* Pods-{{NAME}}SampleApp.debug.xcconfig */, + C551972F94B0CEF1567385B7 /* Pods-{{NAME}}SampleApp.release.xcconfig */, + 64A330AAADA421FC16B2F3CC /* Pods-{{NAME}}SnapshotTests.debug.xcconfig */, + E8AC9E929BE7AC35BC1AF42E /* Pods-{{NAME}}SnapshotTests.release.xcconfig */, + 9834AABED752121CC05A7D13 /* Pods-{{NAME}}Tests.debug.xcconfig */, + F57A4770029E0756A5DED034 /* Pods-{{NAME}}Tests.release.xcconfig */, + 8B701E7714E675D9807A6F5D /* Pods-{{NAME}}UnitTests.debug.xcconfig */, + 3E21DCEF1F1447E04421D44C /* Pods-{{NAME}}UnitTests.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + C46929E025F28DCC0037E096 = { + isa = PBXGroup; + children = ( + E032B0FB28D877A4005DAD27 /* {{NAME}} */, + E0CA9FC0290683B700072950 /* {{NAME}}UnitTests */, + E032B10E28D878F4005DAD27 /* {{NAME}}SnapshotTests */, + C46929EA25F28DCC0037E096 /* Products */, + 72DB137664A5B936DFEBD325 /* Pods */, + CB6A3DD983CF63B7510F3593 /* Frameworks */, + ); + sourceTree = ""; + }; + C46929EA25F28DCC0037E096 /* Products */ = { + isa = PBXGroup; + children = ( + C46929E925F28DCC0037E096 /* {{NAME}}SampleApp.app */, + E032B10D28D878F4005DAD27 /* {{NAME}}SnapshotTests.xctest */, + E0CA9FBF290683B700072950 /* {{NAME}}UnitTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + CB6A3DD983CF63B7510F3593 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 8D5718AF792674405DE47F3B /* Pods_{{NAME}}SampleApp.framework */, + 8852CE74306EDAC67D83B30B /* Pods_{{NAME}}SnapshotTests.framework */, + CAAFE24845B392E99F14652B /* Pods_{{NAME}}Tests.framework */, + 01B6F1CD3CDE5790CE8952B8 /* Pods_{{NAME}}UnitTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + E032B0FB28D877A4005DAD27 /* {{NAME}} */ = { + isa = PBXGroup; + children = ( + E032B10128D877A4005DAD27 /* AppDelegate.swift */, + E032B0FC28D877A4005DAD27 /* ViewController.swift */, + E032B0FD28D877A4005DAD27 /* AuthTokenProvider+{{NAME}}.swift */, + E032B0FE28D877A4005DAD27 /* Assets.xcassets */, + E032B0FF28D877A4005DAD27 /* LaunchScreen.storyboard */, + E0E5D98928D8C84E00B04B0D /* UnitTests.xctestplan */, + E0CAA2192906966900072950 /* SnapshotTests.xctestplan */, + E032B10228D877A4005DAD27 /* Info.plist */, + ); + path = {{NAME}}; + sourceTree = ""; + }; + E032B10E28D878F4005DAD27 /* {{NAME}}SnapshotTests */ = { + isa = PBXGroup; + children = ( + E0CA9FCC2906867000072950 /* PodSnapshotTests.swift */, + E032B10F28D878F4005DAD27 /* SampleAppSnapshotTests.swift */, + ); + name = {{NAME}}SnapshotTests; + path = ../{{NAME}}/Tests/Snapshot; + sourceTree = ""; + }; + E0CA9FC0290683B700072950 /* {{NAME}}UnitTests */ = { + isa = PBXGroup; + children = ( + E0CA9FCA2906866300072950 /* PodUnitTests.swift */, + E0CA9FC1290683B700072950 /* SampleAppUnitTests.swift */, + ); + name = {{NAME}}UnitTests; + path = ../{{NAME}}/Tests/Unit; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXLegacyTarget section */ + C443EC2926208E7D00FEB287 /* SwiftLint */ = { + isa = PBXLegacyTarget; + buildArgumentsString = ""; + buildConfigurationList = C443EC2C26208E7D00FEB287 /* Build configuration list for PBXLegacyTarget "SwiftLint" */; + buildPhases = ( + ); + buildToolPath = "submodules/ios-tooling/SwiftLint/xcode-swift-lint.sh"; + buildWorkingDirectory = ..; + dependencies = ( + ); + name = SwiftLint; + passBuildSettingsInEnvironment = 0; + productName = SwiftLint; + }; +/* End PBXLegacyTarget section */ + +/* Begin PBXNativeTarget section */ + C46929E825F28DCC0037E096 /* {{NAME}}SampleApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = C4692A1325F28DCE0037E096 /* Build configuration list for PBXNativeTarget "{{NAME}}SampleApp" */; + buildPhases = ( + A6A4A8B24AA54F6B358FAEAF /* [CP] Check Pods Manifest.lock */, + C46929E525F28DCC0037E096 /* Sources */, + C46929E625F28DCC0037E096 /* Frameworks */, + C46929E725F28DCC0037E096 /* Resources */, + 05E5B43E95B6DBD3B89A9523 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + E08EC9D628E30F1D00E07A8A /* PBXTargetDependency */, + ); + name = {{NAME}}SampleApp; + productName = Soteria; + productReference = C46929E925F28DCC0037E096 /* {{NAME}}SampleApp.app */; + productType = "com.apple.product-type.application"; + }; + E032B10C28D878F4005DAD27 /* {{NAME}}SnapshotTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = E032B11328D878F4005DAD27 /* Build configuration list for PBXNativeTarget "{{NAME}}SnapshotTests" */; + buildPhases = ( + 69A04B9258871148886CE11B /* [CP] Check Pods Manifest.lock */, + E032B10928D878F4005DAD27 /* Sources */, + E032B10A28D878F4005DAD27 /* Frameworks */, + E032B10B28D878F4005DAD27 /* Resources */, + 9473409B55F5A8747B17C69D /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + E081E7C628E311B5009BC638 /* PBXTargetDependency */, + E032B11228D878F4005DAD27 /* PBXTargetDependency */, + ); + name = {{NAME}}SnapshotTests; + productName = {{NAME}}SnapshotTests; + productReference = E032B10D28D878F4005DAD27 /* {{NAME}}SnapshotTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + E0CA9FBE290683B700072950 /* {{NAME}}UnitTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = E0CA9FC5290683B700072950 /* Build configuration list for PBXNativeTarget "{{NAME}}UnitTests" */; + buildPhases = ( + 251EC279F454638985946BA1 /* [CP] Check Pods Manifest.lock */, + E0CA9FBB290683B700072950 /* Sources */, + E0CA9FBC290683B700072950 /* Frameworks */, + E0CA9FBD290683B700072950 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + E0CA9FC4290683B700072950 /* PBXTargetDependency */, + ); + name = {{NAME}}UnitTests; + productName = {{NAME}}UnitTests; + productReference = E0CA9FBF290683B700072950 /* {{NAME}}UnitTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + C46929E125F28DCC0037E096 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1340; + LastUpgradeCheck = 1240; + TargetAttributes = { + C443EC2926208E7D00FEB287 = { + CreatedOnToolsVersion = 12.2; + }; + C46929E825F28DCC0037E096 = { + CreatedOnToolsVersion = 12.4; + }; + E032B10C28D878F4005DAD27 = { + CreatedOnToolsVersion = 13.4.1; + TestTargetID = C46929E825F28DCC0037E096; + }; + E0CA9FBE290683B700072950 = { + CreatedOnToolsVersion = 13.4.1; + TestTargetID = C46929E825F28DCC0037E096; + }; + }; + }; + buildConfigurationList = C46929E425F28DCC0037E096 /* Build configuration list for PBXProject "{{NAME}}SampleApp" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = C46929E025F28DCC0037E096; + productRefGroup = C46929EA25F28DCC0037E096 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + C46929E825F28DCC0037E096 /* {{NAME}}SampleApp */, + C443EC2926208E7D00FEB287 /* SwiftLint */, + E0CA9FBE290683B700072950 /* {{NAME}}UnitTests */, + E032B10C28D878F4005DAD27 /* {{NAME}}SnapshotTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + C46929E725F28DCC0037E096 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E032B10628D877A4005DAD27 /* LaunchScreen.storyboard in Resources */, + E032B10528D877A4005DAD27 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E032B10B28D878F4005DAD27 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E0CA9FBD290683B700072950 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 05E5B43E95B6DBD3B89A9523 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-{{NAME}}SampleApp/Pods-{{NAME}}SampleApp-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-{{NAME}}SampleApp/Pods-{{NAME}}SampleApp-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-{{NAME}}SampleApp/Pods-{{NAME}}SampleApp-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 251EC279F454638985946BA1 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-{{NAME}}UnitTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 69A04B9258871148886CE11B /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-{{NAME}}SnapshotTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 9473409B55F5A8747B17C69D /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-{{NAME}}SnapshotTests/Pods-{{NAME}}SnapshotTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-{{NAME}}SnapshotTests/Pods-{{NAME}}SnapshotTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-{{NAME}}SnapshotTests/Pods-{{NAME}}SnapshotTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + A6A4A8B24AA54F6B358FAEAF /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-{{NAME}}SampleApp-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + C46929E525F28DCC0037E096 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E032B10728D877A4005DAD27 /* AppDelegate.swift in Sources */, + E032B10428D877A4005DAD27 /* AuthTokenProvider+{{NAME}}.swift in Sources */, + E032B10328D877A4005DAD27 /* ViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E032B10928D878F4005DAD27 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E0CA9FCD2906867000072950 /* PodSnapshotTests.swift in Sources */, + E032B11028D878F4005DAD27 /* SampleAppSnapshotTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E0CA9FBB290683B700072950 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E0CA9FCB2906866300072950 /* PodUnitTests.swift in Sources */, + E0CA9FC2290683B700072950 /* SampleAppUnitTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + E032B11228D878F4005DAD27 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C46929E825F28DCC0037E096 /* {{NAME}}SampleApp */; + targetProxy = E032B11128D878F4005DAD27 /* PBXContainerItemProxy */; + }; + E081E7C628E311B5009BC638 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C443EC2926208E7D00FEB287 /* SwiftLint */; + targetProxy = E081E7C528E311B5009BC638 /* PBXContainerItemProxy */; + }; + E08EC9D628E30F1D00E07A8A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C443EC2926208E7D00FEB287 /* SwiftLint */; + targetProxy = E08EC9D528E30F1D00E07A8A /* PBXContainerItemProxy */; + }; + E0CA9FC4290683B700072950 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C46929E825F28DCC0037E096 /* {{NAME}}SampleApp */; + targetProxy = E0CA9FC3290683B700072950 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + E032B0FF28D877A4005DAD27 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + E032B10028D877A4005DAD27 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + C443EC2A26208E7D00FEB287 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Debug; + }; + C443EC2B26208E7D00FEB287 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Release; + }; + C4692A1125F28DCE0037E096 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + C4692A1225F28DCE0037E096 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + C4692A1425F28DCE0037E096 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B4F5E906324582CED0C4324C /* Pods-{{NAME}}SampleApp.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "$(SRCROOT)/{{NAME}}/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.sumup.{{NAME}}SampleApp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + C4692A1525F28DCE0037E096 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C551972F94B0CEF1567385B7 /* Pods-{{NAME}}SampleApp.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "$(SRCROOT)/{{NAME}}/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.sumup.{{NAME}}SampleApp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + E032B11428D878F4005DAD27 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 64A330AAADA421FC16B2F3CC /* Pods-{{NAME}}SnapshotTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.5; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.sumup.{{NAME}}SnapshotTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/{{NAME}}SampleApp.app/{{NAME}}SampleApp"; + }; + name = Debug; + }; + E032B11528D878F4005DAD27 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E8AC9E929BE7AC35BC1AF42E /* Pods-{{NAME}}SnapshotTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.5; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.sumup.{{NAME}}SnapshotTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/{{NAME}}SampleApp.app/{{NAME}}SampleApp"; + }; + name = Release; + }; + E0CA9FC6290683B700072950 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8B701E7714E675D9807A6F5D /* Pods-{{NAME}}UnitTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.5; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.sumup.{{NAME}}UnitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/{{NAME}}SampleApp.app/{{NAME}}SampleApp"; + }; + name = Debug; + }; + E0CA9FC7290683B700072950 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3E21DCEF1F1447E04421D44C /* Pods-{{NAME}}UnitTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.5; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.sumup.{{NAME}}UnitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/{{NAME}}SampleApp.app/{{NAME}}SampleApp"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + C443EC2C26208E7D00FEB287 /* Build configuration list for PBXLegacyTarget "SwiftLint" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C443EC2A26208E7D00FEB287 /* Debug */, + C443EC2B26208E7D00FEB287 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C46929E425F28DCC0037E096 /* Build configuration list for PBXProject "{{NAME}}SampleApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C4692A1125F28DCE0037E096 /* Debug */, + C4692A1225F28DCE0037E096 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C4692A1325F28DCE0037E096 /* Build configuration list for PBXNativeTarget "{{NAME}}SampleApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C4692A1425F28DCE0037E096 /* Debug */, + C4692A1525F28DCE0037E096 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E032B11328D878F4005DAD27 /* Build configuration list for PBXNativeTarget "{{NAME}}SnapshotTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E032B11428D878F4005DAD27 /* Debug */, + E032B11528D878F4005DAD27 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E0CA9FC5290683B700072950 /* Build configuration list for PBXNativeTarget "{{NAME}}UnitTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E0CA9FC6290683B700072950 /* Debug */, + E0CA9FC7290683B700072950 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = C46929E125F28DCC0037E096 /* Project object */; +} diff --git a/{{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/{{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/{{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/{{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/{{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/{{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/{{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/xcshareddata/xcschemes/{{NAME}}SampleApp.xcscheme b/{{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/xcshareddata/xcschemes/{{NAME}}SampleApp.xcscheme new file mode 100644 index 0000000..f75a230 --- /dev/null +++ b/{{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/xcshareddata/xcschemes/{{NAME}}SampleApp.xcscheme @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/{{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/xcshareddata/xcschemes/{{NAME}}SnapshotTests.xcscheme b/{{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/xcshareddata/xcschemes/{{NAME}}SnapshotTests.xcscheme new file mode 100644 index 0000000..2d56af7 --- /dev/null +++ b/{{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/xcshareddata/xcschemes/{{NAME}}SnapshotTests.xcscheme @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/{{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/xcshareddata/xcschemes/{{NAME}}UnitTests.xcscheme b/{{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/xcshareddata/xcschemes/{{NAME}}UnitTests.xcscheme new file mode 100644 index 0000000..5109a10 --- /dev/null +++ b/{{NAME}}SampleApp/{{NAME}}SampleApp.xcodeproj/xcshareddata/xcschemes/{{NAME}}UnitTests.xcscheme @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/{{NAME}}SampleApp/{{NAME}}SnapshotTests/SampleAppSnapshotTests.swift b/{{NAME}}SampleApp/{{NAME}}SnapshotTests/SampleAppSnapshotTests.swift new file mode 100644 index 0000000..72a82c6 --- /dev/null +++ b/{{NAME}}SampleApp/{{NAME}}SnapshotTests/SampleAppSnapshotTests.swift @@ -0,0 +1,21 @@ +// +// SampleAppSnapshotTests.swift +// {{NAME}}SnapshotTests +// +// Created by {{AUTHOR}} on {{DAY}}.{{MONTH}}.{{YEAR}}. +// + +import SumUpSnapshotTesting +import XCTest + +class SampleAppSnapshotTests: SumUpSnapshotTestCase { + override func setUp() { + super.setUp() + // set to true to update the references images + recordMode = false + } + + func testSample() { + XCTAssertTrue(true) + } +} diff --git a/{{NAME}}SampleApp/{{NAME}}UnitTests/SampleAppUnitTests.swift b/{{NAME}}SampleApp/{{NAME}}UnitTests/SampleAppUnitTests.swift new file mode 100644 index 0000000..6714169 --- /dev/null +++ b/{{NAME}}SampleApp/{{NAME}}UnitTests/SampleAppUnitTests.swift @@ -0,0 +1,14 @@ +// +// SampleAppUnitTests.swift +// {{NAME}}UnitTests +// +// Created by {{AUTHOR}} on {{DAY}}.{{MONTH}}.{{YEAR}}. +// + +import XCTest + +class SampleAppUnitTests: XCTestCase { + func testSample() { + XCTAssertTrue(true) + } +}