├── AD_Demo
├── AD_Demo
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ ├── AppIcon-129x29@2x.png
│ │ │ ├── AppIcon-129x29@3x.png
│ │ │ ├── AppIcon-140x40@2x.png
│ │ │ ├── AppIcon-140x40@3x.png
│ │ │ ├── AppIcon-160x60@2x.png
│ │ │ ├── AppIcon-160x60@3x.png
│ │ │ ├── AppIcon-140x40~ipad.png
│ │ │ ├── AppIcon-160x60@3x-1.png
│ │ │ ├── AppIcon-176x76~ipad.png
│ │ │ ├── AppIcon-129x29@2x~ipad.png
│ │ │ ├── AppIcon-140x40@2x~ipad.png
│ │ │ ├── AppIcon-176x76@2x~ipad.png
│ │ │ └── Contents.json
│ ├── ViewController.swift
│ ├── ViewControllerSecond.swift
│ ├── Info.plist
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ └── AppDelegate.swift
├── fastlane
│ ├── metadata
│ │ ├── AppIcon.png
│ │ └── itunes_rating_config.json
│ ├── Appfile
│ ├── screenshots
│ │ ├── zh-Hans
│ │ │ ├── iPhone5-01firstPage-d41d8cd98f00b204e9800998ecf8427e.png
│ │ │ ├── iPhone6-01firstPage-d41d8cd98f00b204e9800998ecf8427e.png
│ │ │ ├── iPhone5-02secondPage-d41d8cd98f00b204e9800998ecf8427e.png
│ │ │ ├── iPhone6-02secondPage-d41d8cd98f00b204e9800998ecf8427e.png
│ │ │ ├── iPhone6Plus-01firstPage-d41d8cd98f00b204e9800998ecf8427e.png
│ │ │ └── iPhone6Plus-02secondPage-d41d8cd98f00b204e9800998ecf8427e.png
│ │ ├── README.txt
│ │ └── screenshots.html
│ ├── Snapfile
│ ├── report.xml
│ ├── Fastfile
│ ├── README.md
│ ├── Deliverfile
│ ├── SnapshotHelper.swift
│ └── SnapshotHelper2-3.swift
├── AD_Demo.xcodeproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcuserdata
│ │ │ └── gyjrong.xcuserdatad
│ │ │ │ └── UserInterfaceState.xcuserstate
│ │ └── xcshareddata
│ │ │ └── AD_Demo.xcscmblueprint
│ ├── xcuserdata
│ │ └── gyjrong.xcuserdatad
│ │ │ └── xcschemes
│ │ │ ├── xcschememanagement.plist
│ │ │ └── AD_Demo.xcscheme
│ └── project.pbxproj
└── AD_DemoUITests
│ ├── Info.plist
│ ├── AD_DemoUITests.swift
│ └── SnapshotHelper.swift
├── LICENSE
└── README.md
/AD_Demo/AD_Demo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/AD_Demo/fastlane/metadata/AppIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mythkiven/AD_Fastlane/HEAD/AD_Demo/fastlane/metadata/AppIcon.png
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-129x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mythkiven/AD_Fastlane/HEAD/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-129x29@2x.png
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-129x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mythkiven/AD_Fastlane/HEAD/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-129x29@3x.png
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-140x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mythkiven/AD_Fastlane/HEAD/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-140x40@2x.png
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-140x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mythkiven/AD_Fastlane/HEAD/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-140x40@3x.png
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-160x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mythkiven/AD_Fastlane/HEAD/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-160x60@2x.png
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-160x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mythkiven/AD_Fastlane/HEAD/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-160x60@3x.png
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-140x40~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mythkiven/AD_Fastlane/HEAD/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-140x40~ipad.png
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-160x60@3x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mythkiven/AD_Fastlane/HEAD/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-160x60@3x-1.png
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-176x76~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mythkiven/AD_Fastlane/HEAD/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-176x76~ipad.png
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-129x29@2x~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mythkiven/AD_Fastlane/HEAD/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-129x29@2x~ipad.png
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-140x40@2x~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mythkiven/AD_Fastlane/HEAD/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-140x40@2x~ipad.png
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-176x76@2x~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mythkiven/AD_Fastlane/HEAD/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/AppIcon-176x76@2x~ipad.png
--------------------------------------------------------------------------------
/AD_Demo/fastlane/Appfile:
--------------------------------------------------------------------------------
1 |
2 | # app 的 bundle identifier
3 | app_identifier "com.3code.ADDemo"
4 |
5 | # 你的 Apple email address
6 | apple_id "Apple 邮件地址"
7 |
8 | # 开发的 Team ID
9 | team_id "Team ID"
10 |
11 |
--------------------------------------------------------------------------------
/AD_Demo/fastlane/screenshots/zh-Hans/iPhone5-01firstPage-d41d8cd98f00b204e9800998ecf8427e.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mythkiven/AD_Fastlane/HEAD/AD_Demo/fastlane/screenshots/zh-Hans/iPhone5-01firstPage-d41d8cd98f00b204e9800998ecf8427e.png
--------------------------------------------------------------------------------
/AD_Demo/fastlane/screenshots/zh-Hans/iPhone6-01firstPage-d41d8cd98f00b204e9800998ecf8427e.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mythkiven/AD_Fastlane/HEAD/AD_Demo/fastlane/screenshots/zh-Hans/iPhone6-01firstPage-d41d8cd98f00b204e9800998ecf8427e.png
--------------------------------------------------------------------------------
/AD_Demo/fastlane/screenshots/zh-Hans/iPhone5-02secondPage-d41d8cd98f00b204e9800998ecf8427e.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mythkiven/AD_Fastlane/HEAD/AD_Demo/fastlane/screenshots/zh-Hans/iPhone5-02secondPage-d41d8cd98f00b204e9800998ecf8427e.png
--------------------------------------------------------------------------------
/AD_Demo/fastlane/screenshots/zh-Hans/iPhone6-02secondPage-d41d8cd98f00b204e9800998ecf8427e.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mythkiven/AD_Fastlane/HEAD/AD_Demo/fastlane/screenshots/zh-Hans/iPhone6-02secondPage-d41d8cd98f00b204e9800998ecf8427e.png
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/AD_Demo/fastlane/screenshots/zh-Hans/iPhone6Plus-01firstPage-d41d8cd98f00b204e9800998ecf8427e.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mythkiven/AD_Fastlane/HEAD/AD_Demo/fastlane/screenshots/zh-Hans/iPhone6Plus-01firstPage-d41d8cd98f00b204e9800998ecf8427e.png
--------------------------------------------------------------------------------
/AD_Demo/fastlane/screenshots/zh-Hans/iPhone6Plus-02secondPage-d41d8cd98f00b204e9800998ecf8427e.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mythkiven/AD_Fastlane/HEAD/AD_Demo/fastlane/screenshots/zh-Hans/iPhone6Plus-02secondPage-d41d8cd98f00b204e9800998ecf8427e.png
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo.xcodeproj/project.xcworkspace/xcuserdata/gyjrong.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mythkiven/AD_Fastlane/HEAD/AD_Demo/AD_Demo.xcodeproj/project.xcworkspace/xcuserdata/gyjrong.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/AD_Demo/fastlane/Snapfile:
--------------------------------------------------------------------------------
1 |
2 |
3 | # 图片尺寸
4 | devices([
5 | "iPhone 5",
6 | "iPhone 6",
7 | "iPhone 6 Plus"
8 | ])
9 |
10 | # 语言
11 | languages([
12 | "zh-Hans"
13 | ])
14 |
15 | # 储存位置
16 | output_directory "./fastlane/screenshots"
17 |
18 | # 删除以前图片?
19 | clear_previous_screenshots true
20 |
--------------------------------------------------------------------------------
/AD_Demo/fastlane/metadata/itunes_rating_config.json:
--------------------------------------------------------------------------------
1 | {"CARTOON_FANTASY_VIOLENCE": 0,
2 | "REALISTIC_VIOLENCE": 0,
3 | "PROLONGED_GRAPHIC_SADISTIC_REALISTIC_VIOLENCE": 0,
4 | "PROFANITY_CRUDE_HUMOR": 0,
5 | "MATURE_SUGGESTIVE": 0,
6 | "HORROR": 2,
7 | "MEDICAL_TREATMENT_INFO": 0,
8 | "ALCOHOL_TOBACCO_DRUGS": 0,
9 | "GAMBLING": 0,
10 | "SEXUAL_CONTENT_NUDITY": 0,
11 | "GRAPHIC_SEXUAL_CONTENT_NUDITY": 0,
12 | "UNRESTRICTED_WEB_ACCESS": 0,
13 | "GAMBLING_CONTESTS": 0
14 | }
15 |
--------------------------------------------------------------------------------
/AD_Demo/fastlane/screenshots/README.txt:
--------------------------------------------------------------------------------
1 | Put all screenshots you want to use inside the folder of its language (e.g. en-US).
2 | The device type will automatically be recognized using the image resolution. Apple TV screenshots
3 | should be stored in a subdirectory named appleTV with language folders inside of it. iMessage
4 | screenshots, like Apple TV screenshots, should also be stored in a subdirectory named iMessage
5 | with language folders inside of it.
6 |
7 | The screenshots can be named whatever you want, but keep in mind they are sorted alphabetically.
8 |
--------------------------------------------------------------------------------
/AD_Demo/fastlane/report.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // AD_Demo
4 | //
5 | // https://github.com/mythkiven/AD_Fastlane
6 |
7 | import UIKit
8 |
9 | class ViewController: UIViewController {
10 |
11 | override func viewDidLoad() {
12 | super.viewDidLoad()
13 | // Do any additional setup after loading the view, typically from a nib.
14 | }
15 |
16 | override func viewDidAppear(_ animated: Bool) {
17 |
18 | }
19 | override func didReceiveMemoryWarning() {
20 | super.didReceiveMemoryWarning()
21 | // Dispose of any resources that can be recreated.
22 | }
23 |
24 |
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/AD_Demo/AD_DemoUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 11
21 |
22 |
23 |
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo/ViewControllerSecond.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewControllerS.swift
3 | // AD_Demo
4 | //
5 | // https://github.com/mythkiven/AD_Fastlane
6 |
7 |
8 | import UIKit
9 |
10 | class ViewControllerSecond: UIViewController {
11 |
12 | override func viewDidLoad() {
13 | super.viewDidLoad()
14 | // Do any additional setup after loading the view, typically from a nib.
15 | }
16 | @IBAction func pop(_ sender: Any) {
17 | self.dismiss(animated: true) {
18 |
19 | }
20 | }
21 |
22 | override func viewDidAppear(_ animated: Bool) {
23 |
24 | }
25 | override func didReceiveMemoryWarning() {
26 | super.didReceiveMemoryWarning()
27 | // Dispose of any resources that can be recreated.
28 | }
29 |
30 |
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo.xcodeproj/xcuserdata/gyjrong.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | AD_Demo.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | D28E87A11E495B7E00EE86E6
16 |
17 | primary
18 |
19 |
20 | D28E87B51E495B7E00EE86E6
21 |
22 | primary
23 |
24 |
25 | D28E87C01E495B7E00EE86E6
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 3行代码
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/AD_Demo/fastlane/Fastfile:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | fastlane_version "2.14.2"
6 |
7 | default_platform :ios
8 |
9 | platform :ios do
10 |
11 | # 创建证书
12 | desc "Creating a code signing certificate and provisioning profile"
13 | #
14 | lane :provision do
15 | #
16 | produce(
17 | app_name: 'AD_Demo',
18 | language: 'zh-Hans',
19 | app_version: '1.0',
20 | sku: 'com.3code.ADDemo.Test'
21 | )
22 | #
23 | cert
24 | #
25 | sigh(force: true)
26 | end
27 |
28 | error do |lane, exception|
29 | # This block is called if there was an error running a lane.
30 | end
31 |
32 | # 拍照
33 | desc "Take screenshots"
34 | lane :screenshot do
35 | snapshot
36 | end
37 |
38 | desc "Create ipa"
39 | lane :build do
40 | increment_build_number
41 | gym
42 | end
43 |
44 |
45 | # 提交
46 | desc "Upload to App Store and submit for review"
47 | lane :upload do
48 | deliver(
49 | submit_for_review: true
50 | )
51 | end
52 |
53 | # 一键搞定
54 | desc "Provision, take screenshots, build and upload to App Store"
55 | lane :do_everything do
56 | provision
57 | screenshot
58 | build
59 | upload
60 | end
61 |
62 |
63 | end
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | zh_CN
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 11
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/AD_Demo/AD_DemoUITests/AD_DemoUITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AD_DemoUITests.swift
3 | // AD_DemoUITests
4 | //
5 | // https://github.com/mythkiven/AD_Fastlane
6 |
7 | import XCTest
8 |
9 | class AD_DemoUITests: XCTestCase {
10 |
11 | // override func setUp() {
12 | // super.setUp()
13 | //
14 | // // Put setup code here. This method is called before the invocation of each test method in the class.
15 | //
16 | // // In UI tests it is usually best to stop immediately when a failure occurs.
17 | // continueAfterFailure = false
18 | // // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
19 | // XCUIApplication().launch()
20 | //
21 | // // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
22 | // }
23 |
24 | // override func tearDown() {
25 | // // Put teardown code here. This method is called after the invocation of each test method in the class.
26 | // super.tearDown()
27 | // }
28 |
29 | func testExample() {
30 | // Use recording to get started writing UI tests.
31 | // Use XCTAssert and related functions to verify your tests produce the correct results.
32 |
33 | let app = XCUIApplication()
34 | setupSnapshot(app)
35 | app.launch()
36 |
37 | app.buttons["next"].tap()
38 | snapshot("01firstPage")
39 |
40 | app.buttons["back"].tap()
41 | snapshot("02secondPage")
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo.xcodeproj/project.xcworkspace/xcshareddata/AD_Demo.xcscmblueprint:
--------------------------------------------------------------------------------
1 | {
2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "CD74132223D2F2D21B638C19DC987CD1E8B30F5F",
3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
4 |
5 | },
6 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
7 | "CD74132223D2F2D21B638C19DC987CD1E8B30F5F" : 9223372036854775807,
8 | "EFFC378D676A8C7D60853A9DC05B16B17EA9AA82" : 9223372036854775807
9 | },
10 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "8A5E74E6-C8BC-4EF5-9C8F-8C095CF2611A",
11 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
12 | "CD74132223D2F2D21B638C19DC987CD1E8B30F5F" : "AD_Fastlane\/",
13 | "EFFC378D676A8C7D60853A9DC05B16B17EA9AA82" : ""
14 | },
15 | "DVTSourceControlWorkspaceBlueprintNameKey" : "AD_Demo",
16 | "DVTSourceControlWorkspaceBlueprintVersion" : 204,
17 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "AD_Demo\/AD_Demo.xcodeproj",
18 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
19 | {
20 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/mythkiven\/AD_Fastlane.git",
21 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
22 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "CD74132223D2F2D21B638C19DC987CD1E8B30F5F"
23 | },
24 | {
25 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/mythkiven\/getFund.git",
26 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
27 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "EFFC378D676A8C7D60853A9DC05B16B17EA9AA82"
28 | }
29 | ]
30 | }
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/AD_Demo/fastlane/README.md:
--------------------------------------------------------------------------------
1 | fastlane documentation
2 | ================
3 | # Installation
4 |
5 | Make sure you have the latest version of the Xcode command line tools installed:
6 |
7 | ```
8 | xcode-select --install
9 | ```
10 |
11 | ## Choose your installation method:
12 |
13 |
14 |
15 | | Homebrew
16 | | Installer Script
17 | | Rubygems
18 | |
19 |
20 | | macOS |
21 | macOS |
22 | macOS or Linux with Ruby 2.0.0 or above |
23 |
24 |
25 | brew cask install fastlane |
26 | Download the zip file. Then double click on the install script (or run it in a terminal window). |
27 | sudo gem install fastlane -NV |
28 |
29 |
30 | # Available Actions
31 | ## iOS
32 | ### ios provision
33 | ```
34 | fastlane ios provision
35 | ```
36 | Creating a code signing certificate and provisioning profile
37 | ### ios screenshot
38 | ```
39 | fastlane ios screenshot
40 | ```
41 | Take screenshots
42 | ### ios build
43 | ```
44 | fastlane ios build
45 | ```
46 | Create ipa
47 | ### ios upload
48 | ```
49 | fastlane ios upload
50 | ```
51 | Upload to App Store and submit for review
52 | ### ios do_everything
53 | ```
54 | fastlane ios do_everything
55 | ```
56 | Provision, take screenshots, build and upload to App Store
57 |
58 | ----
59 |
60 | This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run.
61 | More information about fastlane can be found on [fastlane.tools](https://fastlane.tools).
62 | The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
63 |
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // AD_Demo
4 | //
5 | // https://github.com/mythkiven/AD_Fastlane
6 |
7 | import UIKit
8 |
9 |
10 | @UIApplicationMain
11 | class AppDelegate: UIResponder, UIApplicationDelegate {
12 |
13 | var window: UIWindow?
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
17 |
18 | // let app = XCUIApplication()
19 | // setupSnapshot(app)
20 | // app.launch()
21 |
22 | return true
23 | }
24 |
25 | func applicationWillResignActive(_ application: UIApplication) {
26 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
27 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
28 | }
29 |
30 | func applicationDidEnterBackground(_ application: UIApplication) {
31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
33 | }
34 |
35 | func applicationWillEnterForeground(_ application: UIApplication) {
36 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
37 | }
38 |
39 | func applicationDidBecomeActive(_ application: UIApplication) {
40 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
41 | }
42 |
43 | func applicationWillTerminate(_ application: UIApplication) {
44 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
45 | }
46 |
47 |
48 | }
49 |
50 |
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "size" : "29x29",
15 | "idiom" : "iphone",
16 | "filename" : "AppIcon-129x29@2x.png",
17 | "scale" : "2x"
18 | },
19 | {
20 | "size" : "29x29",
21 | "idiom" : "iphone",
22 | "filename" : "AppIcon-129x29@3x.png",
23 | "scale" : "3x"
24 | },
25 | {
26 | "size" : "40x40",
27 | "idiom" : "iphone",
28 | "filename" : "AppIcon-140x40@2x.png",
29 | "scale" : "2x"
30 | },
31 | {
32 | "size" : "40x40",
33 | "idiom" : "iphone",
34 | "filename" : "AppIcon-140x40@3x.png",
35 | "scale" : "3x"
36 | },
37 | {
38 | "size" : "60x60",
39 | "idiom" : "iphone",
40 | "filename" : "AppIcon-160x60@2x.png",
41 | "scale" : "2x"
42 | },
43 | {
44 | "size" : "60x60",
45 | "idiom" : "iphone",
46 | "filename" : "AppIcon-160x60@3x.png",
47 | "scale" : "3x"
48 | },
49 | {
50 | "idiom" : "ipad",
51 | "size" : "20x20",
52 | "scale" : "1x"
53 | },
54 | {
55 | "idiom" : "ipad",
56 | "size" : "20x20",
57 | "scale" : "2x"
58 | },
59 | {
60 | "idiom" : "ipad",
61 | "size" : "29x29",
62 | "scale" : "1x"
63 | },
64 | {
65 | "size" : "29x29",
66 | "idiom" : "ipad",
67 | "filename" : "AppIcon-129x29@2x~ipad.png",
68 | "scale" : "2x"
69 | },
70 | {
71 | "size" : "40x40",
72 | "idiom" : "ipad",
73 | "filename" : "AppIcon-140x40~ipad.png",
74 | "scale" : "1x"
75 | },
76 | {
77 | "size" : "40x40",
78 | "idiom" : "ipad",
79 | "filename" : "AppIcon-140x40@2x~ipad.png",
80 | "scale" : "2x"
81 | },
82 | {
83 | "size" : "76x76",
84 | "idiom" : "ipad",
85 | "filename" : "AppIcon-176x76~ipad.png",
86 | "scale" : "1x"
87 | },
88 | {
89 | "size" : "76x76",
90 | "idiom" : "ipad",
91 | "filename" : "AppIcon-176x76@2x~ipad.png",
92 | "scale" : "2x"
93 | },
94 | {
95 | "size" : "83.5x83.5",
96 | "idiom" : "ipad",
97 | "filename" : "AppIcon-160x60@3x-1.png",
98 | "scale" : "2x"
99 | }
100 | ],
101 | "info" : {
102 | "version" : 1,
103 | "author" : "xcode"
104 | }
105 | }
--------------------------------------------------------------------------------
/AD_Demo/fastlane/Deliverfile:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #######################----by https://github.com/mythkiven-#######################
5 | #######################----by https://github.com/mythkiven-#######################
6 |
7 | # 本文件的设置,可以参考官方文档
8 | # 官方文档:https://github.com/fastlane/fastlane/blob/master/deliver/Deliverfile.md
9 | # 官方文档:https://github.com/fastlane/fastlane/blob/master/spaceship/docs/iTunesConnect.md
10 |
11 | #######################----by https://github.com/mythkiven-#######################
12 | #######################----by https://github.com/mythkiven-#######################
13 |
14 |
15 | ############################# 基本信息 ####################################
16 |
17 |
18 | # 1 app_identifier
19 | app_identifier "com.3code.ADDemo"
20 |
21 | # 2 用户名,Apple ID电子邮件地址
22 | username "Apple ID电子邮件地址"
23 |
24 |
25 | # 3 copyright
26 | copyright "#{Time.now.year} 3code"
27 |
28 | # 4 支持语言
29 | supportedLanguages = {
30 | "cmn-Hans" => "zh-Hans"
31 | }
32 |
33 | # 5 app 名称
34 | name({
35 | 'zh-Hans' => "ADDemo"
36 | })
37 |
38 | # 6 本地化
39 | description({
40 | 'zh-Hans' => "简体中文版"
41 | })
42 |
43 |
44 |
45 | # AppStore 信息设置
46 | # 也可以使用 txt 文本的形式
47 |
48 | ################################### 类别配置 ###################################
49 |
50 | # 类别列表设置参见 https://github.com/fastlane/fastlane/blob/master/deliver/Reference.md
51 | # 设置 App 的类别.这里可以设置一个主要类别,一个次要类别.
52 |
53 | # 主要类别
54 | primary_category "Games"
55 |
56 | # 主要类别第一个子类别,游戏会有
57 | primary_first_sub_category "Card"
58 | # 主要类别第二个子类别,游戏会有
59 | primary_second_sub_category "Casino"
60 |
61 | # 要设置的次要类别 无
62 | # secondary_category
63 | # 设置的次要第一个子类别 无
64 | # secondary_first_sub_category
65 | # 设置的次要第二个子类别 无
66 | # secondary_second_sub_category
67 |
68 |
69 |
70 | ################################## 关键字\描述等信息 ###################################
71 |
72 | # 1 设置 app 检索关键字
73 | keywords(
74 | "zh-Hans" => "mythkiven,mythkiven2"
75 | )
76 |
77 | # 2 网址设置
78 | support_url({
79 | 'zh-Hans' => "https://github.com/mythkiven"
80 | })
81 | marketing_url({
82 | 'zh-Hans' => "https://github.com/mythkiven"
83 | })
84 | privacy_url({
85 | 'zh-Hans' => "https://github.com/mythkiven"
86 | })
87 |
88 | # 3 版本描述
89 | release_notes({
90 | 'zh-Hans' => "这是第一个版本哦"
91 | })
92 |
93 | # 4 app 描述
94 | description({
95 | 'zh-Hans' => "这是一个测试 App"
96 | })
97 |
98 |
99 |
100 |
101 | ################################## 分级 ########################################
102 |
103 | app_rating_config_path "./fastlane/metadata/itunes_rating_config.json"
104 |
105 |
106 | ################################# 提交信息等 #########################################
107 |
108 | # 1 提交审核信息:加密, idfa 等
109 | submission_information({
110 | export_compliance_encryption_updated: false,
111 | export_compliance_uses_encryption: false,
112 | content_rights_contains_third_party_content: false,
113 | add_id_info_uses_idfa: false
114 | })
115 |
116 | # 2 应用审核小组的联系信息 app 审核信息
117 | app_review_information(
118 | first_name: "myth",
119 | last_name: "kiven",
120 | phone_number: "手机号",
121 | email_address: "mythkiven@qq.com",
122 | demo_user: "测试账号",
123 | demo_password: "测试密码",
124 | notes: "No demo account needed"
125 | )
126 |
127 | ####################################### 其他信息 ###################################
128 |
129 | # 1 自动发布 app: false,则需要手动发布
130 | automatic_release false
131 |
132 | # 2 价格
133 | price_tier 0
134 |
135 | # 3 图标
136 | app_icon './fastlane/metadata/AppIcon.png'
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo.xcodeproj/xcuserdata/gyjrong.xcuserdatad/xcschemes/AD_Demo.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
43 |
49 |
50 |
51 |
52 |
53 |
59 |
60 |
61 |
62 |
63 |
64 |
74 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
95 |
101 |
102 |
103 |
104 |
106 |
107 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/AD_Demo/AD_DemoUITests/SnapshotHelper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapshotHelper.swift
3 | // Example
4 | //
5 | // Created by Felix Krause on 10/8/15.
6 | // Copyright © 2015 Felix Krause. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | var deviceLanguage = ""
13 | var locale = ""
14 |
15 | @available(*, deprecated, message: "use setupSnapshot: instead")
16 | func setLanguage(_ app: XCUIApplication) {
17 | setupSnapshot(app)
18 | }
19 |
20 | func setupSnapshot(_ app: XCUIApplication) {
21 | Snapshot.setupSnapshot(app)
22 | }
23 |
24 | func snapshot(_ name: String, waitForLoadingIndicator: Bool = true) {
25 | Snapshot.snapshot(name, waitForLoadingIndicator: waitForLoadingIndicator)
26 | }
27 |
28 | open class Snapshot: NSObject {
29 |
30 | open class func setupSnapshot(_ app: XCUIApplication) {
31 | setLanguage(app)
32 | setLocale(app)
33 | setLaunchArguments(app)
34 | }
35 |
36 | class func setLanguage(_ app: XCUIApplication) {
37 | guard let prefix = pathPrefix() else {
38 | return
39 | }
40 |
41 | let path = prefix.appendingPathComponent("language.txt")
42 |
43 | do {
44 | let trimCharacterSet = CharacterSet.whitespacesAndNewlines
45 | deviceLanguage = try NSString(contentsOfFile: path, encoding: String.Encoding.utf8.rawValue).trimmingCharacters(in: trimCharacterSet) as String
46 | app.launchArguments += ["-AppleLanguages", "(\(deviceLanguage))"]
47 | } catch {
48 | print("Couldn't detect/set language...")
49 | }
50 | }
51 |
52 | class func setLocale(_ app: XCUIApplication) {
53 | guard let prefix = pathPrefix() else {
54 | return
55 | }
56 |
57 | let path = prefix.appendingPathComponent("locale.txt")
58 |
59 | do {
60 | let trimCharacterSet = CharacterSet.whitespacesAndNewlines
61 | locale = try NSString(contentsOfFile: path, encoding: String.Encoding.utf8.rawValue).trimmingCharacters(in: trimCharacterSet) as String
62 | } catch {
63 | print("Couldn't detect/set locale...")
64 | }
65 | if locale.isEmpty {
66 | locale = Locale(identifier: deviceLanguage).identifier
67 | }
68 | app.launchArguments += ["-AppleLocale", "\"\(locale)\""]
69 | }
70 |
71 | class func setLaunchArguments(_ app: XCUIApplication) {
72 | guard let prefix = pathPrefix() else {
73 | return
74 | }
75 |
76 | let path = prefix.appendingPathComponent("snapshot-launch_arguments.txt")
77 | app.launchArguments += ["-FASTLANE_SNAPSHOT", "YES", "-ui_testing"]
78 |
79 | do {
80 | let launchArguments = try NSString(contentsOfFile: path, encoding: String.Encoding.utf8.rawValue) as String
81 | let regex = try NSRegularExpression(pattern: "(\\\".+?\\\"|\\S+)", options: [])
82 | let matches = regex.matches(in: launchArguments, options: [], range: NSRange(location:0, length:launchArguments.characters.count))
83 | let results = matches.map { result -> String in
84 | (launchArguments as NSString).substring(with: result.range)
85 | }
86 | app.launchArguments += results
87 | } catch {
88 | print("Couldn't detect/set launch_arguments...")
89 | }
90 | }
91 |
92 | open class func snapshot(_ name: String, waitForLoadingIndicator: Bool = true) {
93 | if waitForLoadingIndicator {
94 | waitForLoadingIndicatorToDisappear()
95 | }
96 |
97 | print("snapshot: \(name)") // more information about this, check out https://github.com/fastlane/fastlane/tree/master/snapshot#how-does-it-work
98 |
99 | sleep(1) // Waiting for the animation to be finished (kind of)
100 |
101 | #if os(tvOS)
102 | XCUIApplication().childrenMatchingType(.Browser).count
103 | #else
104 | XCUIDevice.shared().orientation = .unknown
105 | #endif
106 | }
107 |
108 | class func waitForLoadingIndicatorToDisappear() {
109 | #if os(tvOS)
110 | return
111 | #endif
112 |
113 | let query = XCUIApplication().statusBars.children(matching: .other).element(boundBy: 1).children(matching: .other)
114 |
115 | while (0.. NSString? {
122 | if let path = ProcessInfo().environment["SIMULATOR_HOST_HOME"] as NSString? {
123 | return path.appendingPathComponent("Library/Caches/tools.fastlane") as NSString?
124 | }
125 | print("Couldn't find Snapshot configuration files at ~/Library/Caches/tools.fastlane")
126 | return nil
127 | }
128 | }
129 |
130 | extension XCUIElement {
131 | var isLoadingIndicator: Bool {
132 | return self.frame.size == CGSize(width: 10, height: 20)
133 | }
134 | }
135 |
136 | // Please don't remove the lines below
137 | // They are used to detect outdated configuration files
138 | // SnapshotHelperVersion [1.2]
139 |
--------------------------------------------------------------------------------
/AD_Demo/fastlane/SnapshotHelper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapshotHelper.swift
3 | // Example
4 | //
5 | // Created by Felix Krause on 10/8/15.
6 | // Copyright © 2015 Felix Krause. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | var deviceLanguage = ""
13 | var locale = ""
14 |
15 | @available(*, deprecated, message: "use setupSnapshot: instead")
16 | func setLanguage(_ app: XCUIApplication) {
17 | setupSnapshot(app)
18 | }
19 |
20 | func setupSnapshot(_ app: XCUIApplication) {
21 | Snapshot.setupSnapshot(app)
22 | }
23 |
24 | func snapshot(_ name: String, waitForLoadingIndicator: Bool = true) {
25 | Snapshot.snapshot(name, waitForLoadingIndicator: waitForLoadingIndicator)
26 | }
27 |
28 | open class Snapshot: NSObject {
29 |
30 | open class func setupSnapshot(_ app: XCUIApplication) {
31 | setLanguage(app)
32 | setLocale(app)
33 | setLaunchArguments(app)
34 | }
35 |
36 | class func setLanguage(_ app: XCUIApplication) {
37 | guard let prefix = pathPrefix() else {
38 | return
39 | }
40 |
41 | let path = prefix.appendingPathComponent("language.txt")
42 |
43 | do {
44 | let trimCharacterSet = CharacterSet.whitespacesAndNewlines
45 | deviceLanguage = try NSString(contentsOfFile: path, encoding: String.Encoding.utf8.rawValue).trimmingCharacters(in: trimCharacterSet) as String
46 | app.launchArguments += ["-AppleLanguages", "(\(deviceLanguage))"]
47 | } catch {
48 | print("Couldn't detect/set language...")
49 | }
50 | }
51 |
52 | class func setLocale(_ app: XCUIApplication) {
53 | guard let prefix = pathPrefix() else {
54 | return
55 | }
56 |
57 | let path = prefix.appendingPathComponent("locale.txt")
58 |
59 | do {
60 | let trimCharacterSet = CharacterSet.whitespacesAndNewlines
61 | locale = try NSString(contentsOfFile: path, encoding: String.Encoding.utf8.rawValue).trimmingCharacters(in: trimCharacterSet) as String
62 | } catch {
63 | print("Couldn't detect/set locale...")
64 | }
65 | if locale.isEmpty {
66 | locale = Locale(identifier: deviceLanguage).identifier
67 | }
68 | app.launchArguments += ["-AppleLocale", "\"\(locale)\""]
69 | }
70 |
71 | class func setLaunchArguments(_ app: XCUIApplication) {
72 | guard let prefix = pathPrefix() else {
73 | return
74 | }
75 |
76 | let path = prefix.appendingPathComponent("snapshot-launch_arguments.txt")
77 | app.launchArguments += ["-FASTLANE_SNAPSHOT", "YES", "-ui_testing"]
78 |
79 | do {
80 | let launchArguments = try NSString(contentsOfFile: path, encoding: String.Encoding.utf8.rawValue) as String
81 | let regex = try NSRegularExpression(pattern: "(\\\".+?\\\"|\\S+)", options: [])
82 | let matches = regex.matches(in: launchArguments, options: [], range: NSRange(location:0, length:launchArguments.characters.count))
83 | let results = matches.map { result -> String in
84 | (launchArguments as NSString).substring(with: result.range)
85 | }
86 | app.launchArguments += results
87 | } catch {
88 | print("Couldn't detect/set launch_arguments...")
89 | }
90 | }
91 |
92 | open class func snapshot(_ name: String, waitForLoadingIndicator: Bool = true) {
93 | if waitForLoadingIndicator {
94 | waitForLoadingIndicatorToDisappear()
95 | }
96 |
97 | print("snapshot: \(name)") // more information about this, check out https://github.com/fastlane/fastlane/tree/master/snapshot#how-does-it-work
98 |
99 | sleep(1) // Waiting for the animation to be finished (kind of)
100 |
101 | #if os(tvOS)
102 | XCUIApplication().childrenMatchingType(.Browser).count
103 | #else
104 | XCUIDevice.shared().orientation = .unknown
105 | #endif
106 | }
107 |
108 | class func waitForLoadingIndicatorToDisappear() {
109 | #if os(tvOS)
110 | return
111 | #endif
112 |
113 | let query = XCUIApplication().statusBars.children(matching: .other).element(boundBy: 1).children(matching: .other)
114 |
115 | while (0.. NSString? {
122 | if let path = ProcessInfo().environment["SIMULATOR_HOST_HOME"] as NSString? {
123 | return path.appendingPathComponent("Library/Caches/tools.fastlane") as NSString?
124 | }
125 | print("Couldn't find Snapshot configuration files at ~/Library/Caches/tools.fastlane")
126 | return nil
127 | }
128 | }
129 |
130 | extension XCUIElement {
131 | var isLoadingIndicator: Bool {
132 | let whiteListedLoaders = ["GeofenceLocationTrackingOn", "StandardLocationTrackingOn"]
133 | if whiteListedLoaders.contains(self.identifier) {
134 | return false
135 | }
136 | return self.frame.size == CGSize(width: 10, height: 20)
137 | }
138 | }
139 |
140 | // Please don't remove the lines below
141 | // They are used to detect outdated configuration files
142 | // SnapshotHelperVersion [1.2]
143 |
--------------------------------------------------------------------------------
/AD_Demo/fastlane/SnapshotHelper2-3.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapshotHelper.swift
3 | // Example
4 | //
5 | // Created by Felix Krause on 10/8/15.
6 | // Copyright © 2015 Felix Krause. All rights reserved.
7 | //
8 |
9 | // This file should be used if your UI Tests are written in Swift 2.3
10 |
11 | import Foundation
12 | import XCTest
13 |
14 | var deviceLanguage = ""
15 | var locale = ""
16 |
17 | @available(*, deprecated, message="use setupSnapshot: instead")
18 | func setLanguage(app: XCUIApplication) {
19 | setupSnapshot(app)
20 | }
21 |
22 | func setupSnapshot(app: XCUIApplication) {
23 | Snapshot.setupSnapshot(app)
24 | }
25 |
26 | func snapshot(name: String, waitForLoadingIndicator: Bool = true) {
27 | Snapshot.snapshot(name, waitForLoadingIndicator: waitForLoadingIndicator)
28 | }
29 |
30 | public class Snapshot: NSObject {
31 |
32 | public class func setupSnapshot(app: XCUIApplication) {
33 | setLanguage(app)
34 | setLocale(app)
35 | setLaunchArguments(app)
36 | }
37 |
38 | class func setLanguage(app: XCUIApplication) {
39 | guard let prefix = pathPrefix() else {
40 | return
41 | }
42 |
43 | let path = prefix.stringByAppendingPathComponent("language.txt")
44 |
45 | do {
46 | let trimCharacterSet = NSCharacterSet.whitespaceAndNewlineCharacterSet()
47 | deviceLanguage = try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding).stringByTrimmingCharactersInSet(trimCharacterSet) as String
48 | app.launchArguments += ["-AppleLanguages", "(\(deviceLanguage))"]
49 | } catch {
50 | print("Couldn't detect/set language...")
51 | }
52 | }
53 |
54 | class func setLocale(app: XCUIApplication) {
55 | guard let prefix = pathPrefix() else {
56 | return
57 | }
58 |
59 | let path = prefix.stringByAppendingPathComponent("locale.txt")
60 |
61 | do {
62 | let trimCharacterSet = NSCharacterSet.whitespaceAndNewlineCharacterSet()
63 | locale = try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding).stringByTrimmingCharactersInSet(trimCharacterSet) as String
64 | } catch {
65 | print("Couldn't detect/set locale...")
66 | }
67 | if locale.isEmpty {
68 | locale = NSLocale(localeIdentifier: deviceLanguage).localeIdentifier
69 | }
70 | app.launchArguments += ["-AppleLocale", "\"\(locale)\""]
71 | }
72 |
73 | class func setLaunchArguments(app: XCUIApplication) {
74 | guard let prefix = pathPrefix() else {
75 | return
76 | }
77 |
78 | let path = prefix.stringByAppendingPathComponent("snapshot-launch_arguments.txt")
79 | app.launchArguments += ["-FASTLANE_SNAPSHOT", "YES", "-ui_testing"]
80 |
81 | do {
82 | let launchArguments = try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding) as String
83 | let regex = try NSRegularExpression(pattern: "(\\\".+?\\\"|\\S+)", options: [])
84 | let matches = regex.matchesInString(launchArguments, options: [], range: NSRange(location:0, length:launchArguments.characters.count))
85 | let results = matches.map { result -> String in
86 | (launchArguments as NSString).substringWithRange(result.range)
87 | }
88 | app.launchArguments += results
89 | } catch {
90 | print("Couldn't detect/set launch_arguments...")
91 | }
92 | }
93 |
94 | public class func snapshot(name: String, waitForLoadingIndicator: Bool = true) {
95 | if waitForLoadingIndicator {
96 | waitForLoadingIndicatorToDisappear()
97 | }
98 |
99 | print("snapshot: \(name)") // more information about this, check out https://github.com/fastlane/fastlane/tree/master/snapshot#how-does-it-work
100 |
101 | sleep(1) // Waiting for the animation to be finished (kind of)
102 |
103 | #if os(tvOS)
104 | XCUIApplication().childrenMatchingType(.Browser).count
105 | #else
106 | XCUIDevice.sharedDevice().orientation = .Unknown
107 | #endif
108 | }
109 |
110 | class func waitForLoadingIndicatorToDisappear() {
111 | #if os(tvOS)
112 | return
113 | #endif
114 |
115 | let query = XCUIApplication().statusBars.childrenMatchingType(.Other).elementBoundByIndex(1).childrenMatchingType(.Other)
116 |
117 | while (0.. NSString? {
124 | if let path = NSProcessInfo().environment["SIMULATOR_HOST_HOME"] as NSString? {
125 | return path.stringByAppendingPathComponent("Library/Caches/tools.fastlane")
126 | }
127 | print("Couldn't find Snapshot configuration files at ~/Library/Caches/tools.fastlane")
128 | return nil
129 | }
130 | }
131 |
132 | extension XCUIElement {
133 | var isLoadingIndicator: Bool {
134 | let whiteListedLoaders = ["GeofenceLocationTrackingOn", "StandardLocationTrackingOn"]
135 | if whiteListedLoaders.contains(self.identifier) {
136 | return false
137 | }
138 | return self.frame.size == CGSize(width: 10, height: 20)
139 | }
140 | }
141 |
142 | // Please don't remove the lines below
143 | // They are used to detect outdated configuration files
144 | // SnapshotHelperVersion [1.2]
145 |
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/AD_Demo/fastlane/screenshots/screenshots.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | fastlane/snapshot
5 |
6 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | en-US
75 |
76 |
77 |
78 |
79 | |
80 | iPhone5 (4-Inch)
81 | |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
95 |
96 | |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
108 |
109 | |
110 |
111 |
112 |
113 |
114 | |
115 | iPhone6 (4.7-Inch)
116 | |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
130 |
131 | |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
143 |
144 | |
145 |
146 |
147 |
148 |
149 | |
150 | iPhone6Plus (5.5-Inch)
151 | |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
165 |
166 | |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
178 |
179 | |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
![]()
187 |
188 |
189 |
288 |
289 |
290 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | ## Fastlane 入门实战教程
3 |
4 | >有关神器 Fastlane 持续集成\部署的文章网上挺多,本文定位是入门教程,针对 iOS 应用的持续部署,**只需一条命令就可实现从 Xcode 项目到 编译\打包\构建\提交审核**
5 | >
6 | >文章稍微有点长,涵盖内容为:fastlane 简介\安装\配置 + Snapshot 截图 + XCTest + 一键上传App Store
7 | >
8 | >说明:本文将 Apple Dev Center 简称为 ADC; iTunes Connect 简称为 ITC
9 | >
10 |
11 | 先放图看 fastlane 实现自动上传功能:
12 |
13 | 提交进度:
14 |
15 | 
16 |
17 | 提交成功,等待审核
18 | 
19 |
20 |
21 | ## Fastlane 简介
22 |
23 | fastlane 是一个完全开源的项目,包含一组 Ruby 实现的工具集,能完成 iOS 和 Android 工程 的自动化构建\测试和发布等功能,[现被Twitter收购,是Fabric的一部分](https://krausefx.com/blog/fastlane-is-now-part-of-fabric).fastlane 强大之处就在于其提供的工具全,基本可以覆盖打包测试发布的所有流程,如下图:
24 |
25 | 
26 |
27 |
28 | fastlane 的每一个工具都对应一个 Ruby 脚本,用来执行某一特定的任务,而最妙的是可以通过配置文件将不同的工具灵活的结合在一起,从而形成一个完整的自动化流程,实现一键上传 ITC,从而缩短用于构建发布的时间.
29 |
30 |
31 | ##### 1.主要使用场:
32 |
33 | - 提交时执行测试(包括单元测试和集成测试)
34 | - 构建并分发内部测试\公开测试版本
35 | - 构建生产版本并上传至 ITC(包括更新配置文件,创建新的屏幕截图,上传应用并提交审核)
36 | - ...
37 |
38 | ##### 2.工具集
39 |
40 | fastlane 将如下的工具套件有机地结合起来,从管理证书到单元测试,从编译打包到上传发布,都能通过命令行轻松完成.该套件支持与 Jenkins 和 CocoaPods,xctools 等其他第三方工具的集成,并且能够定义多个通道(lanes)以支持不同的部署目标.
41 |
42 | - deliver: 将应用在 ITC 上所需数据提交至 ITC (包括:截图,配置文件,ipa包)
43 | - snapshot: 依靠 UI Test 完成截图
44 | - frameit: 快速地把应用截图放入设备框里
45 | - pem: 可以自动化地生成和更新应用推送通知描述文件
46 | - sigh: 创建\更新\下载和修复 provisioning profiles,支持App Store, Ad Hoc, Development和企业profiles
47 | - gym: 编译\打包iOS app,生成签名的ipa文件
48 | - ...
49 |
50 | ##### 3.常见命令
51 |
52 | fastlane 命令中,个人觉得下面两个较为常用:
53 |
54 | - 列出所有的 fastlane 的 actions:
55 |
56 | ```
57 | $ fastlane actions
58 | ```
59 |
60 | - fastlane action [action_name]: 显示某一个 action 的详细配置
61 |
62 | ```
63 | $ fastlane action match
64 | ```
65 |
66 |
67 | ## fastlane 入门实战
68 |
69 |
70 | ### 1.安装 fastlane
71 |
72 | ##### 1.1 创建App ID\描述文件
73 |
74 | - 本教程目标是上传 ITC ,因此需要提前在 ADC 和 ITC 中创建 App ID\描述文件\App
75 | - 这里使用的项目是 AD Demo,代码见 [GitHub](https://github.com/mythkiven/AD_Fastlane)
76 |
77 | 
78 | 
79 |
80 | ##### 1.2 安装
81 |
82 | 查看 Ruby 版本,低于2.0最好升级
83 |
84 | ```
85 | $ ruby -v
86 | ```
87 |
88 | 检查 Xcode CLT 是否安装
89 |
90 | ```
91 | $ xcode-select --install
92 | ```
93 |
94 | 安装 fastlane
95 |
96 | ```
97 | $ sudo gem install -n /usr/local/bin fastlane
98 | ```
99 |
100 | 检查版本 fastlane
101 |
102 | ```
103 | $ fastlane --version
104 | fastlane installation at path:
105 | /Library/Ruby/Gems/2.0.0/gems/fastlane-2.14.2/bin/fastlane
106 | -----------------------------
107 | fastlane 2.14.2
108 | ```
109 |
110 | OK,安装完成
111 |
112 | ##### 1.3 为项目配置 fastlane
113 |
114 | ```
115 | $ cd 项目目录
116 | $ fastlane init
117 | ```
118 |
119 | 如果期间报错 `Connection reset by peer - SSL_Connect`,就需要执行:
120 |
121 | ```
122 | $ brew update && brew install ruby
123 | // 重装
124 | $ sudo gem install -n /usr/local/bin fastlane
125 | ```
126 |
127 | 然后重新执行
128 | ```
129 | $ fastlane init
130 | ```
131 |
132 | - 期间会让你输入 Apple ID 账号密码(这个信息会存在钥匙串中,后续使用无需再输入密码)
133 | - 会检测当前的 app identifier 是否在 ADC 中
134 | - 会检测当前 app 是否在 ITC 中
135 | - 如果已经在 ADC 和 ITC 中创建相应的信息,那么过程会很顺利,如下图:
136 |
137 | 
138 |
139 | 并在 Xcode 项目目录中生成如下文件:
140 |
141 | 
142 |
143 | 注意:如果没有在 ITC 中创建 App ,也就不会创建上述两个文件夹;当然也可以后续创建,执行如下操作即可:
144 |
145 | ```
146 | $ fastlane produce init
147 | ```
148 |
149 | ### 2.fastlane 文件配置
150 |
151 | fastlane 的各文件解释如下:
152 |
153 | - Appfile:用于存储应用程序标识符和Apple ID 等信息
154 | - Fastfile:配置管理 lane
155 | - Deliverfile:将应用在 ITC 中的信息,统一配置在一个Deliverfile文件中,详见2.1
156 | - metadata:功能同上也是配置应用在ITC中的信息,只不过是独立文本的形式配置的
157 | - screenshots:包含截图数据
158 |
159 | 需要注意的是,metadata 和 Deliverfile,都可以配置 ITC 的数据,但后者优先级高.正如下图:
160 |
161 | 
162 |
163 | 
164 |
165 | 下文先在 metadata 文件夹中进行配置用于演示,在文末会删除 metadata 中的配置文本,全部配置在 Deliverfile 中.
166 |
167 | ##### 2.1 配置 metadata 文件夹
168 |
169 | 修改 App 描述:
170 |
171 | ```
172 | $ cd metadata
173 | $ cd zh-Hans
174 | $ vim description.txt
175 | ```
176 |
177 | 修改关键字:
178 |
179 | ```
180 | $ vim keywords.txt
181 | ```
182 |
183 | 修改 support_url:
184 |
185 | ```
186 | $ vim support_url.txt
187 | ```
188 |
189 | 修改 copyright:
190 |
191 | ```
192 | $ vim copyright.txt
193 | ```
194 |
195 | 等等,其他信息的修改类似.
196 |
197 | 然后创建分级文件:itunes_rating_config.json
198 |
199 | ``` json
200 | {"CARTOON_FANTASY_VIOLENCE": 0,
201 | "REALISTIC_VIOLENCE": 0,
202 | "PROLONGED_GRAPHIC_SADISTIC_REALISTIC_VIOLENCE": 0,
203 | "PROFANITY_CRUDE_HUMOR": 0,
204 | "MATURE_SUGGESTIVE": 0,
205 | "HORROR": 2,
206 | "MEDICAL_TREATMENT_INFO": 0,
207 | "ALCOHOL_TOBACCO_DRUGS": 0,
208 | "GAMBLING": 0,
209 | "SEXUAL_CONTENT_NUDITY": 0,
210 | "GRAPHIC_SEXUAL_CONTENT_NUDITY": 0,
211 | "UNRESTRICTED_WEB_ACCESS": 0,
212 | "GAMBLING_CONTESTS": 0
213 | }
214 | ```
215 |
216 | 此处配置参见[官方文档](https://github.com/fastlane/fastlane/blob/master/deliver/Reference.md)
217 |
218 | 然后将 App 图标添加至文件夹中,接下来要创建证书:
219 |
220 | ##### 2.2 配置证书
221 |
222 | 修改 Fastfile:
223 |
224 | ```
225 | $ vim Fastfile
226 | ```
227 |
228 | 修改内容如下:
229 |
230 | ```
231 | fastlane_version "2.14.2"
232 |
233 | default_platform :ios
234 |
235 | platform :ios do
236 |
237 | # 当前任务的描述
238 | desc "Creating a code signing certificate and provisioning profile"
239 | # 任务名称
240 | lane :provision do
241 | # 创建 ITC 中的 App 信息
242 | produce(
243 | app_name: 'AD_Demo',
244 | language: 'zh-Hans',
245 | app_version: '1.0',
246 | sku: 'com.3code.ADDemo.Test'
247 | )
248 | # 使用证书创建私钥及签名
249 | cert
250 | # 每次运行时创建新的配置文件
251 | sigh(force: true)
252 | end
253 |
254 | error do |lane, exception|
255 |
256 | end
257 |
258 | end
259 | ```
260 |
261 | 如果想创建 ad hoc 配置文件,需要指定sigh(adhoc: true).更多的信息参见:
262 |
263 | - [官方文档](https://github.com/fastlane/fastlane/tree/master/fastlane/docs)
264 | - [fastlane actions](https://docs.fastlane.tools/actions/)
265 |
266 | ##### 2.3 将 fastlane 本地配置上传至 ITC
267 |
268 | 重新进入项目目录,执行如下操作:
269 |
270 | ```
271 | $ fastlane provision
272 | ```
273 |
274 | 等待一小会儿,终端提示成功创建证书配置:
275 |
276 | ```
277 | fastlane.tools finished successfully 🎉
278 | ```
279 |
280 | 打开 ITC 网页,会发现本地的配置,已经成功上传.
281 |
282 | ### 3.Xcode 配置
283 |
284 | xcode 配置也简单,只需要将项目修改至生产状态即可(描述文件).其它像构建版本号之类的不用理会, fastlane 会处理的.
285 |
286 | ### 4.Snapshot 截图和 XCTest
287 |
288 | snapshot 需要和 XCTest 配合使用,关于 XCTest,我的博客中[有一篇文章](www.3code.info/2017/01/23/AD-XCTest/)做了简单介绍.
289 |
290 | ```
291 | $ fastlane snapshot init
292 | ```
293 |
294 | 目录中会生成一个 Snapfile 文件,用于配置截图信息,修改内容如下:
295 |
296 | ```
297 | # 图片尺寸
298 | devices([
299 | "iPhone 5",
300 | "iPhone 6",
301 | "iPhone 6 Plus"
302 | ])
303 |
304 | # 支持语言
305 | languages([
306 | 'zh-Hans'
307 | ])
308 |
309 | # 储存位置
310 | output_directory "./fastlane/screenshots"
311 |
312 | # 删除之前图片
313 | clear_previous_screenshots true
314 | ```
315 |
316 | 然后打开 Xcode 工程,添加截图设置(需要增加 UI Test, 因为截图是在 UI Test 时截取的):
317 |
318 | ```
319 | \\ 1)在项目添加UI测试,已经添加略过
320 | \\ 2)将./fastlane/SnapshotHelper.swift 添加到UI测试中
321 | \\ 3)打开 AD_DemoUITests.swift ,删除setUp和tearDown方法,然后在其中添加以下代码testExample:
322 |
323 | let app = XCUIApplication()
324 | setupSnapshot(app)
325 | app.launch()
326 |
327 | app.buttons["next"].tap()
328 | snapshot("01firstPage") // 此处截图
329 |
330 | app.buttons["back"].tap()
331 | snapshot("02secondPage") // 此处截图
332 |
333 | ```
334 |
335 | 打开 Fastfile ,并添加如下信息,用于配置截图
336 |
337 | ```
338 | desc "Take screenshots"
339 | lane :screenshot do
340 | snapshot
341 | end
342 | ```
343 |
344 | 执行 `$ fastlane screenshot`, fastlane 会自动调用模拟器,执行测试并生成快照,可能会由于模拟器启动慢而导致时间稍微有点长.
345 |
346 | 成功截图的提示:
347 |
348 | 
349 |
350 | ### 5.创建 IPA 文件
351 |
352 | 打开 fastfile,加入如下代码,配置创建 ipa
353 |
354 | ```
355 | desc "Create ipa"
356 | lane :build do
357 | increment_build_number
358 | gym
359 | end
360 | ```
361 |
362 | 保存并执行如下操作,将自动创建 IPA 包
363 |
364 | ```
365 | $ fastlane build
366 | ```
367 |
368 |
369 | 如果出现错误: `There does not seem to be a CURRENT_PROJECT_VERSION key set for this project. Add this key to your target's expert build settings.`
370 | [请查阅此处](https://developer.apple.com/library/content/qa/qa1827/_index.html)
371 |
372 | 这是一个自动增加构建版本号的设置,需要手动修改.
373 |
374 | ### 6.上传 IPA 文件到 ITC
375 |
376 | 打开 Fastfile ,添加如下代码:
377 |
378 | ```
379 | desc "Upload to App Store"
380 | lane :upload do
381 | deliver
382 | end
383 | ```
384 |
385 | 然后执行命令,上传到 ITC :
386 |
387 | ```
388 | $ fastlane upload
389 | ```
390 |
391 | 期间,会创建一个 html 形式的预览文件,确认没问题输入 y;
392 |
393 | 当然最有可能的错误就是网络链接的问题: `Please use diagnostic mode to check connectivity. You need to have outbound access to TCP port 443.` 重新配置代理即可.
394 |
395 | ### 7.配置 Deliverfile
396 |
397 | 其实上传 ITC 最主要的文件是 Deliverfile,配置好 Deliverfile 后,可以删除 metadata 文件夹中的文本配置.最终配置如下图:
398 |
399 | 
400 |
401 | 以下是主要的配置,更多更详细的[请戳文件](https://github.com/mythkiven/AD_Fastlane/blob/master/AD_Demo/fastlane/Deliverfile),里面有详细的注释,拿来即可使用
402 |
403 | ```
404 |
405 | # 1 app_identifier
406 | app_identifier "com.3code.ADDemo"
407 |
408 | # 2 用户名,Apple ID电子邮件地址
409 | username "Apple ID电子邮件地址"
410 |
411 | # 3 支持语言
412 | supportedLanguages = {
413 | "cmn-Hans" => "zh-Hans"
414 | }
415 |
416 | # 4 app 名称
417 | name({
418 | 'zh-Hans' => "ADDemo"
419 | })
420 |
421 | # 5 描述
422 | description({
423 | 'zh-Hans' => "简体中文版"
424 | })
425 |
426 | # 6 提交审核信息
427 | submission_information({
428 | export_compliance_encryption_updated: false,
429 | export_compliance_uses_encryption: false,
430 | content_rights_contains_third_party_content: false,
431 | add_id_info_uses_idfa: false
432 | })
433 |
434 | # 7 应用审核小组的联系信息 app 审核信息
435 | app_review_information(
436 | first_name: "name",
437 | last_name: "name",
438 | phone_number: "手机号",
439 | email_address: "email",
440 | demo_user: "测试账号用户名",
441 | demo_password: "测试账号密码",
442 | notes: "noting"
443 | )
444 |
445 | # 8 copyright
446 | copyright "#{Time.now.year} 3code"
447 |
448 | #
449 | ```
450 |
451 |
452 | ### 8.提交 AppStore 审核
453 |
454 | 继续打开 Fastfile,修改如下代码:
455 |
456 | ```
457 | desc "Upload to App Store and submit for review"
458 | lane :upload do
459 | deliver(
460 | submit_for_review: true
461 | )
462 | end
463 | ```
464 |
465 | 然后执行命令,提交审核 :
466 |
467 | ```
468 | $ fastlane upload
469 | ```
470 |
471 |
472 | ### 9.使用一键命令
473 |
474 | 添加如下的代码,可以一步搞定所有的操作:
475 |
476 | ```
477 | desc "Provision, take screenshots, build and upload to App Store"
478 | lane :do_everything do
479 | provision
480 | screenshot
481 | build
482 | upload
483 | end
484 | ```
485 |
486 | 对应的命令是:
487 |
488 | ```
489 | $ fastlane do_everything
490 | ```
491 |
492 | - 代码下载之后是不能直接执行一键上传 ITC ,需要自行在 ADC 配置 App ID\证书\描述文件,ITC 增加 App, 然后方可一键上传 App
493 |
494 | - 本文只是简单的介绍了 fastlane 的使用,更多的资料还请参考文末的链接
495 |
496 | - 如果你对 ITC 不了解,或者很少发布 App ,建议看看官方文档,要知道发布 App 也有[官方指南哦](https://developer.apple.com/library/content/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide_SCh/Appendices/Properties.html)
497 |
498 | - 本文是系列文章,后续文章会陆续在这里以及我的[博客](http://3code.info)中发布,喜欢请给个✨吧
499 |
500 | ### 10.参考
501 |
502 |
503 | - [官网](https://fastlane.tools/)
504 | - [github](https://github.com/fastlane/fastlane)
505 | - [文档](https://docs.fastlane.tools/getting-started/ios/setup/)
506 |
507 | 最后给点小建议:如果遇到错误首选就是查 issues,你遇到的问题,基本前人都遇到过了.我能在2天里快速入门 fastlane 全靠看 issues 😁😁
508 |
509 |
510 |
511 |
--------------------------------------------------------------------------------
/AD_Demo/AD_Demo.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | D28E87A61E495B7E00EE86E6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28E87A51E495B7E00EE86E6 /* AppDelegate.swift */; };
11 | D28E87A81E495B7E00EE86E6 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28E87A71E495B7E00EE86E6 /* ViewController.swift */; };
12 | D28E87AB1E495B7E00EE86E6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D28E87A91E495B7E00EE86E6 /* Main.storyboard */; };
13 | D28E87B01E495B7E00EE86E6 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D28E87AE1E495B7E00EE86E6 /* LaunchScreen.storyboard */; };
14 | D28E87C61E495B7E00EE86E6 /* AD_DemoUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28E87C51E495B7E00EE86E6 /* AD_DemoUITests.swift */; };
15 | D28E87DD1E4971D200EE86E6 /* SnapshotHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28E87DB1E4971D200EE86E6 /* SnapshotHelper.swift */; };
16 | D28E87E01E49763D00EE86E6 /* ViewControllerSecond.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28E87DF1E49763D00EE86E6 /* ViewControllerSecond.swift */; };
17 | D28E87E21E49957100EE86E6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D28E87E11E49957100EE86E6 /* Assets.xcassets */; };
18 | /* End PBXBuildFile section */
19 |
20 | /* Begin PBXContainerItemProxy section */
21 | D28E87C21E495B7E00EE86E6 /* PBXContainerItemProxy */ = {
22 | isa = PBXContainerItemProxy;
23 | containerPortal = D28E879A1E495B7E00EE86E6 /* Project object */;
24 | proxyType = 1;
25 | remoteGlobalIDString = D28E87A11E495B7E00EE86E6;
26 | remoteInfo = AD_Demo;
27 | };
28 | /* End PBXContainerItemProxy section */
29 |
30 | /* Begin PBXFileReference section */
31 | D28E87A21E495B7E00EE86E6 /* AD_Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AD_Demo.app; sourceTree = BUILT_PRODUCTS_DIR; };
32 | D28E87A51E495B7E00EE86E6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
33 | D28E87A71E495B7E00EE86E6 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
34 | D28E87AA1E495B7E00EE86E6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
35 | D28E87AF1E495B7E00EE86E6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
36 | D28E87B11E495B7E00EE86E6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
37 | D28E87C11E495B7E00EE86E6 /* AD_DemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AD_DemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
38 | D28E87C51E495B7E00EE86E6 /* AD_DemoUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AD_DemoUITests.swift; sourceTree = ""; };
39 | D28E87C71E495B7E00EE86E6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
40 | D28E87DB1E4971D200EE86E6 /* SnapshotHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SnapshotHelper.swift; sourceTree = ""; };
41 | D28E87DF1E49763D00EE86E6 /* ViewControllerSecond.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewControllerSecond.swift; sourceTree = ""; };
42 | D28E87E11E49957100EE86E6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
43 | /* End PBXFileReference section */
44 |
45 | /* Begin PBXFrameworksBuildPhase section */
46 | D28E879F1E495B7E00EE86E6 /* Frameworks */ = {
47 | isa = PBXFrameworksBuildPhase;
48 | buildActionMask = 2147483647;
49 | files = (
50 | );
51 | runOnlyForDeploymentPostprocessing = 0;
52 | };
53 | D28E87BE1E495B7E00EE86E6 /* Frameworks */ = {
54 | isa = PBXFrameworksBuildPhase;
55 | buildActionMask = 2147483647;
56 | files = (
57 | );
58 | runOnlyForDeploymentPostprocessing = 0;
59 | };
60 | /* End PBXFrameworksBuildPhase section */
61 |
62 | /* Begin PBXGroup section */
63 | D28E87991E495B7E00EE86E6 = {
64 | isa = PBXGroup;
65 | children = (
66 | D28E87A41E495B7E00EE86E6 /* AD_Demo */,
67 | D28E87C41E495B7E00EE86E6 /* AD_DemoUITests */,
68 | D28E87A31E495B7E00EE86E6 /* Products */,
69 | );
70 | sourceTree = "";
71 | };
72 | D28E87A31E495B7E00EE86E6 /* Products */ = {
73 | isa = PBXGroup;
74 | children = (
75 | D28E87A21E495B7E00EE86E6 /* AD_Demo.app */,
76 | D28E87C11E495B7E00EE86E6 /* AD_DemoUITests.xctest */,
77 | );
78 | name = Products;
79 | sourceTree = "";
80 | };
81 | D28E87A41E495B7E00EE86E6 /* AD_Demo */ = {
82 | isa = PBXGroup;
83 | children = (
84 | D28E87A51E495B7E00EE86E6 /* AppDelegate.swift */,
85 | D28E87A71E495B7E00EE86E6 /* ViewController.swift */,
86 | D28E87DF1E49763D00EE86E6 /* ViewControllerSecond.swift */,
87 | D28E87E11E49957100EE86E6 /* Assets.xcassets */,
88 | D28E87A91E495B7E00EE86E6 /* Main.storyboard */,
89 | D28E87AE1E495B7E00EE86E6 /* LaunchScreen.storyboard */,
90 | D28E87B11E495B7E00EE86E6 /* Info.plist */,
91 | );
92 | path = AD_Demo;
93 | sourceTree = "";
94 | };
95 | D28E87C41E495B7E00EE86E6 /* AD_DemoUITests */ = {
96 | isa = PBXGroup;
97 | children = (
98 | D28E87DB1E4971D200EE86E6 /* SnapshotHelper.swift */,
99 | D28E87C51E495B7E00EE86E6 /* AD_DemoUITests.swift */,
100 | D28E87C71E495B7E00EE86E6 /* Info.plist */,
101 | );
102 | path = AD_DemoUITests;
103 | sourceTree = "";
104 | };
105 | /* End PBXGroup section */
106 |
107 | /* Begin PBXNativeTarget section */
108 | D28E87A11E495B7E00EE86E6 /* AD_Demo */ = {
109 | isa = PBXNativeTarget;
110 | buildConfigurationList = D28E87CA1E495B7E00EE86E6 /* Build configuration list for PBXNativeTarget "AD_Demo" */;
111 | buildPhases = (
112 | D28E879E1E495B7E00EE86E6 /* Sources */,
113 | D28E879F1E495B7E00EE86E6 /* Frameworks */,
114 | D28E87A01E495B7E00EE86E6 /* Resources */,
115 | );
116 | buildRules = (
117 | );
118 | dependencies = (
119 | );
120 | name = AD_Demo;
121 | productName = AD_Demo;
122 | productReference = D28E87A21E495B7E00EE86E6 /* AD_Demo.app */;
123 | productType = "com.apple.product-type.application";
124 | };
125 | D28E87C01E495B7E00EE86E6 /* AD_DemoUITests */ = {
126 | isa = PBXNativeTarget;
127 | buildConfigurationList = D28E87D01E495B7E00EE86E6 /* Build configuration list for PBXNativeTarget "AD_DemoUITests" */;
128 | buildPhases = (
129 | D28E87BD1E495B7E00EE86E6 /* Sources */,
130 | D28E87BE1E495B7E00EE86E6 /* Frameworks */,
131 | D28E87BF1E495B7E00EE86E6 /* Resources */,
132 | );
133 | buildRules = (
134 | );
135 | dependencies = (
136 | D28E87C31E495B7E00EE86E6 /* PBXTargetDependency */,
137 | );
138 | name = AD_DemoUITests;
139 | productName = AD_DemoUITests;
140 | productReference = D28E87C11E495B7E00EE86E6 /* AD_DemoUITests.xctest */;
141 | productType = "com.apple.product-type.bundle.ui-testing";
142 | };
143 | /* End PBXNativeTarget section */
144 |
145 | /* Begin PBXProject section */
146 | D28E879A1E495B7E00EE86E6 /* Project object */ = {
147 | isa = PBXProject;
148 | attributes = {
149 | LastSwiftUpdateCheck = 0820;
150 | LastUpgradeCheck = 0820;
151 | ORGANIZATIONNAME = mythkiven;
152 | TargetAttributes = {
153 | D28E87A11E495B7E00EE86E6 = {
154 | CreatedOnToolsVersion = 8.2.1;
155 | DevelopmentTeam = 28W82NWSCE;
156 | ProvisioningStyle = Manual;
157 | };
158 | D28E87C01E495B7E00EE86E6 = {
159 | CreatedOnToolsVersion = 8.2.1;
160 | DevelopmentTeam = 28W82NWSCE;
161 | ProvisioningStyle = Automatic;
162 | TestTargetID = D28E87A11E495B7E00EE86E6;
163 | };
164 | };
165 | };
166 | buildConfigurationList = D28E879D1E495B7E00EE86E6 /* Build configuration list for PBXProject "AD_Demo" */;
167 | compatibilityVersion = "Xcode 3.2";
168 | developmentRegion = English;
169 | hasScannedForEncodings = 0;
170 | knownRegions = (
171 | en,
172 | Base,
173 | );
174 | mainGroup = D28E87991E495B7E00EE86E6;
175 | productRefGroup = D28E87A31E495B7E00EE86E6 /* Products */;
176 | projectDirPath = "";
177 | projectRoot = "";
178 | targets = (
179 | D28E87A11E495B7E00EE86E6 /* AD_Demo */,
180 | D28E87C01E495B7E00EE86E6 /* AD_DemoUITests */,
181 | );
182 | };
183 | /* End PBXProject section */
184 |
185 | /* Begin PBXResourcesBuildPhase section */
186 | D28E87A01E495B7E00EE86E6 /* Resources */ = {
187 | isa = PBXResourcesBuildPhase;
188 | buildActionMask = 2147483647;
189 | files = (
190 | D28E87B01E495B7E00EE86E6 /* LaunchScreen.storyboard in Resources */,
191 | D28E87E21E49957100EE86E6 /* Assets.xcassets in Resources */,
192 | D28E87AB1E495B7E00EE86E6 /* Main.storyboard in Resources */,
193 | );
194 | runOnlyForDeploymentPostprocessing = 0;
195 | };
196 | D28E87BF1E495B7E00EE86E6 /* Resources */ = {
197 | isa = PBXResourcesBuildPhase;
198 | buildActionMask = 2147483647;
199 | files = (
200 | );
201 | runOnlyForDeploymentPostprocessing = 0;
202 | };
203 | /* End PBXResourcesBuildPhase section */
204 |
205 | /* Begin PBXSourcesBuildPhase section */
206 | D28E879E1E495B7E00EE86E6 /* Sources */ = {
207 | isa = PBXSourcesBuildPhase;
208 | buildActionMask = 2147483647;
209 | files = (
210 | D28E87A81E495B7E00EE86E6 /* ViewController.swift in Sources */,
211 | D28E87E01E49763D00EE86E6 /* ViewControllerSecond.swift in Sources */,
212 | D28E87A61E495B7E00EE86E6 /* AppDelegate.swift in Sources */,
213 | );
214 | runOnlyForDeploymentPostprocessing = 0;
215 | };
216 | D28E87BD1E495B7E00EE86E6 /* Sources */ = {
217 | isa = PBXSourcesBuildPhase;
218 | buildActionMask = 2147483647;
219 | files = (
220 | D28E87C61E495B7E00EE86E6 /* AD_DemoUITests.swift in Sources */,
221 | D28E87DD1E4971D200EE86E6 /* SnapshotHelper.swift in Sources */,
222 | );
223 | runOnlyForDeploymentPostprocessing = 0;
224 | };
225 | /* End PBXSourcesBuildPhase section */
226 |
227 | /* Begin PBXTargetDependency section */
228 | D28E87C31E495B7E00EE86E6 /* PBXTargetDependency */ = {
229 | isa = PBXTargetDependency;
230 | target = D28E87A11E495B7E00EE86E6 /* AD_Demo */;
231 | targetProxy = D28E87C21E495B7E00EE86E6 /* PBXContainerItemProxy */;
232 | };
233 | /* End PBXTargetDependency section */
234 |
235 | /* Begin PBXVariantGroup section */
236 | D28E87A91E495B7E00EE86E6 /* Main.storyboard */ = {
237 | isa = PBXVariantGroup;
238 | children = (
239 | D28E87AA1E495B7E00EE86E6 /* Base */,
240 | );
241 | name = Main.storyboard;
242 | sourceTree = "";
243 | };
244 | D28E87AE1E495B7E00EE86E6 /* LaunchScreen.storyboard */ = {
245 | isa = PBXVariantGroup;
246 | children = (
247 | D28E87AF1E495B7E00EE86E6 /* Base */,
248 | );
249 | name = LaunchScreen.storyboard;
250 | sourceTree = "";
251 | };
252 | /* End PBXVariantGroup section */
253 |
254 | /* Begin XCBuildConfiguration section */
255 | D28E87C81E495B7E00EE86E6 /* Debug */ = {
256 | isa = XCBuildConfiguration;
257 | buildSettings = {
258 | ALWAYS_SEARCH_USER_PATHS = NO;
259 | CLANG_ANALYZER_NONNULL = YES;
260 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
261 | CLANG_CXX_LIBRARY = "libc++";
262 | CLANG_ENABLE_MODULES = YES;
263 | CLANG_ENABLE_OBJC_ARC = YES;
264 | CLANG_WARN_BOOL_CONVERSION = YES;
265 | CLANG_WARN_CONSTANT_CONVERSION = YES;
266 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
267 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
268 | CLANG_WARN_EMPTY_BODY = YES;
269 | CLANG_WARN_ENUM_CONVERSION = YES;
270 | CLANG_WARN_INFINITE_RECURSION = YES;
271 | CLANG_WARN_INT_CONVERSION = YES;
272 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
273 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
274 | CLANG_WARN_UNREACHABLE_CODE = YES;
275 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
276 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
277 | COPY_PHASE_STRIP = NO;
278 | DEBUG_INFORMATION_FORMAT = dwarf;
279 | ENABLE_STRICT_OBJC_MSGSEND = YES;
280 | ENABLE_TESTABILITY = YES;
281 | GCC_C_LANGUAGE_STANDARD = gnu99;
282 | GCC_DYNAMIC_NO_PIC = NO;
283 | GCC_NO_COMMON_BLOCKS = YES;
284 | GCC_OPTIMIZATION_LEVEL = 0;
285 | GCC_PREPROCESSOR_DEFINITIONS = (
286 | "DEBUG=1",
287 | "$(inherited)",
288 | );
289 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
290 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
291 | GCC_WARN_UNDECLARED_SELECTOR = YES;
292 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
293 | GCC_WARN_UNUSED_FUNCTION = YES;
294 | GCC_WARN_UNUSED_VARIABLE = YES;
295 | IPHONEOS_DEPLOYMENT_TARGET = 10.2;
296 | MTL_ENABLE_DEBUG_INFO = YES;
297 | ONLY_ACTIVE_ARCH = YES;
298 | SDKROOT = iphoneos;
299 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
300 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
301 | TARGETED_DEVICE_FAMILY = "1,2";
302 | };
303 | name = Debug;
304 | };
305 | D28E87C91E495B7E00EE86E6 /* Release */ = {
306 | isa = XCBuildConfiguration;
307 | buildSettings = {
308 | ALWAYS_SEARCH_USER_PATHS = NO;
309 | CLANG_ANALYZER_NONNULL = YES;
310 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
311 | CLANG_CXX_LIBRARY = "libc++";
312 | CLANG_ENABLE_MODULES = YES;
313 | CLANG_ENABLE_OBJC_ARC = YES;
314 | CLANG_WARN_BOOL_CONVERSION = YES;
315 | CLANG_WARN_CONSTANT_CONVERSION = YES;
316 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
317 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
318 | CLANG_WARN_EMPTY_BODY = YES;
319 | CLANG_WARN_ENUM_CONVERSION = YES;
320 | CLANG_WARN_INFINITE_RECURSION = YES;
321 | CLANG_WARN_INT_CONVERSION = YES;
322 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
323 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
324 | CLANG_WARN_UNREACHABLE_CODE = YES;
325 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
326 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
327 | COPY_PHASE_STRIP = NO;
328 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
329 | ENABLE_NS_ASSERTIONS = NO;
330 | ENABLE_STRICT_OBJC_MSGSEND = YES;
331 | GCC_C_LANGUAGE_STANDARD = gnu99;
332 | GCC_NO_COMMON_BLOCKS = YES;
333 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
334 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
335 | GCC_WARN_UNDECLARED_SELECTOR = YES;
336 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
337 | GCC_WARN_UNUSED_FUNCTION = YES;
338 | GCC_WARN_UNUSED_VARIABLE = YES;
339 | IPHONEOS_DEPLOYMENT_TARGET = 10.2;
340 | MTL_ENABLE_DEBUG_INFO = NO;
341 | SDKROOT = iphoneos;
342 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
343 | TARGETED_DEVICE_FAMILY = "1,2";
344 | VALIDATE_PRODUCT = YES;
345 | };
346 | name = Release;
347 | };
348 | D28E87CB1E495B7E00EE86E6 /* Debug */ = {
349 | isa = XCBuildConfiguration;
350 | buildSettings = {
351 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
352 | CODE_SIGN_IDENTITY = "iPhone Distribution: Shanghai TanNuo Information Technology Co., Ltd. (28W82NWSCE)";
353 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: Shanghai TanNuo Information Technology Co., Ltd. (28W82NWSCE)";
354 | CURRENT_PROJECT_VERSION = 11;
355 | DEVELOPMENT_TEAM = 28W82NWSCE;
356 | INFOPLIST_FILE = AD_Demo/Info.plist;
357 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
358 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
359 | PRODUCT_BUNDLE_IDENTIFIER = com.3code.ADDemo;
360 | PRODUCT_NAME = "$(TARGET_NAME)";
361 | PROVISIONING_PROFILE = "f0e98cae-f4d5-4b47-8dee-84c52f1f9d1f";
362 | PROVISIONING_PROFILE_SPECIFIER = "com.3code.ADDemo AppStore";
363 | SWIFT_VERSION = 3.0;
364 | TARGETED_DEVICE_FAMILY = 1;
365 | VERSIONING_SYSTEM = "apple-generic";
366 | };
367 | name = Debug;
368 | };
369 | D28E87CC1E495B7E00EE86E6 /* Release */ = {
370 | isa = XCBuildConfiguration;
371 | buildSettings = {
372 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
373 | CODE_SIGN_IDENTITY = "iPhone Distribution: Shanghai TanNuo Information Technology Co., Ltd. (28W82NWSCE)";
374 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: Shanghai TanNuo Information Technology Co., Ltd. (28W82NWSCE)";
375 | CURRENT_PROJECT_VERSION = 11;
376 | DEVELOPMENT_TEAM = 28W82NWSCE;
377 | INFOPLIST_FILE = AD_Demo/Info.plist;
378 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
379 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
380 | PRODUCT_BUNDLE_IDENTIFIER = com.3code.ADDemo;
381 | PRODUCT_NAME = "$(TARGET_NAME)";
382 | PROVISIONING_PROFILE = "f0e98cae-f4d5-4b47-8dee-84c52f1f9d1f";
383 | PROVISIONING_PROFILE_SPECIFIER = "com.3code.ADDemo AppStore";
384 | SWIFT_VERSION = 3.0;
385 | TARGETED_DEVICE_FAMILY = 1;
386 | VERSIONING_SYSTEM = "apple-generic";
387 | };
388 | name = Release;
389 | };
390 | D28E87D11E495B7E00EE86E6 /* Debug */ = {
391 | isa = XCBuildConfiguration;
392 | buildSettings = {
393 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
394 | DEVELOPMENT_TEAM = 28W82NWSCE;
395 | INFOPLIST_FILE = AD_DemoUITests/Info.plist;
396 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
397 | PRODUCT_BUNDLE_IDENTIFIER = "com.github.mythkiven.AD-DemoUITests";
398 | PRODUCT_NAME = "$(TARGET_NAME)";
399 | SWIFT_VERSION = 3.0;
400 | TEST_TARGET_NAME = AD_Demo;
401 | };
402 | name = Debug;
403 | };
404 | D28E87D21E495B7E00EE86E6 /* Release */ = {
405 | isa = XCBuildConfiguration;
406 | buildSettings = {
407 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
408 | DEVELOPMENT_TEAM = 28W82NWSCE;
409 | INFOPLIST_FILE = AD_DemoUITests/Info.plist;
410 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
411 | PRODUCT_BUNDLE_IDENTIFIER = "com.github.mythkiven.AD-DemoUITests";
412 | PRODUCT_NAME = "$(TARGET_NAME)";
413 | SWIFT_VERSION = 3.0;
414 | TEST_TARGET_NAME = AD_Demo;
415 | };
416 | name = Release;
417 | };
418 | /* End XCBuildConfiguration section */
419 |
420 | /* Begin XCConfigurationList section */
421 | D28E879D1E495B7E00EE86E6 /* Build configuration list for PBXProject "AD_Demo" */ = {
422 | isa = XCConfigurationList;
423 | buildConfigurations = (
424 | D28E87C81E495B7E00EE86E6 /* Debug */,
425 | D28E87C91E495B7E00EE86E6 /* Release */,
426 | );
427 | defaultConfigurationIsVisible = 0;
428 | defaultConfigurationName = Release;
429 | };
430 | D28E87CA1E495B7E00EE86E6 /* Build configuration list for PBXNativeTarget "AD_Demo" */ = {
431 | isa = XCConfigurationList;
432 | buildConfigurations = (
433 | D28E87CB1E495B7E00EE86E6 /* Debug */,
434 | D28E87CC1E495B7E00EE86E6 /* Release */,
435 | );
436 | defaultConfigurationIsVisible = 0;
437 | defaultConfigurationName = Release;
438 | };
439 | D28E87D01E495B7E00EE86E6 /* Build configuration list for PBXNativeTarget "AD_DemoUITests" */ = {
440 | isa = XCConfigurationList;
441 | buildConfigurations = (
442 | D28E87D11E495B7E00EE86E6 /* Debug */,
443 | D28E87D21E495B7E00EE86E6 /* Release */,
444 | );
445 | defaultConfigurationIsVisible = 0;
446 | defaultConfigurationName = Release;
447 | };
448 | /* End XCConfigurationList section */
449 | };
450 | rootObject = D28E879A1E495B7E00EE86E6 /* Project object */;
451 | }
452 |
--------------------------------------------------------------------------------