-
-
Notifications
You must be signed in to change notification settings - Fork 508
/
InfoPlistContentProvider.swift
151 lines (134 loc) · 5.44 KB
/
InfoPlistContentProvider.swift
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
29
30
31
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import Foundation
/// Defines the interface to obtain the content to generate derived Info.plist files for the targets.
protocol InfoPlistContentProviding {
/// It returns the content that should be used to generate an Info.plist file
/// for the given target. It uses default values that specific to the target's platform
/// and product, and extends them with the values provided by the user.
///
/// - Parameters:
/// - target: Target whose Info.plist content will be returned.
/// - extendedWith: Values provided by the user to extend the default ones.
/// - Returns: Content to generate the Info.plist file.
func content(target: Target, extendedWith: [String: InfoPlist.Value]) -> [String: Any]?
}
final class InfoPlistContentProvider: InfoPlistContentProviding {
/// It returns the content that should be used to generate an Info.plist file
/// for the given target. It uses default values that specific to the target's platform
/// and product, and extends them with the values provided by the user.
///
/// - Parameters:
/// - target: Target whose Info.plist content will be returned.
/// - extendedWith: Values provided by the user to extend the default ones.
/// - Returns: Content to generate the Info.plist file.
func content(target: Target, extendedWith: [String: InfoPlist.Value]) -> [String: Any]? {
if target.product == .staticLibrary || target.product == .dynamicLibrary {
return nil
}
var content = base()
// Bundle package type
extend(&content, with: bundlePackageType(target))
// iOS app
if target.product == .app, target.platform == .iOS {
extend(&content, with: iosApp())
}
// macOS app
if target.product == .app, target.platform == .iOS {
extend(&content, with: macosApp())
}
// macOS
if target.platform == .macOS {
extend(&content, with: macos())
}
extend(&content, with: extendedWith.unwrappingValues())
return content
}
/// Returns a dictionary that contains the base content that all Info.plist
/// files should have regardless of the platform or product.
///
/// - Returns: Base content.
func base() -> [String: Any] {
return [
"CFBundleDevelopmentRegion": "$(DEVELOPMENT_LANGUAGE)",
"CFBundleExecutable": "$(EXECUTABLE_NAME)",
"CFBundleIdentifier": "$(PRODUCT_BUNDLE_IDENTIFIER)",
"CFBundleInfoDictionaryVersion": "6.0",
"CFBundleName": "$(PRODUCT_NAME)",
"CFBundleShortVersionString": "1.0",
"CFBundleVersion": "1",
]
}
/// Returns the Info.plist content that includes the CFBundlePackageType
/// attribute depending on the target product type.
///
/// - Parameter target: Target whose Info.plist's CFBundlePackageType will be returned.
/// - Returns: Dictionary with the CFBundlePackageType attribute.
func bundlePackageType(_ target: Target) -> [String: Any] {
var packageType: String?
switch target.product {
case .app:
packageType = "APPL"
case .staticLibrary, .dynamicLibrary:
packageType = nil
case .uiTests, .unitTests, .bundle:
packageType = "BNDL"
case .staticFramework, .framework:
packageType = "FMWK"
}
if let packageType = packageType {
return ["CFBundlePackageType": packageType]
} else {
return [:]
}
}
/// Returns the default Info.plist content that iOS apps should have.
///
/// - Returns: Info.plist content.
func iosApp() -> [String: Any] {
return [
"LSRequiresIPhoneOS": true,
"UILaunchStoryboardName": "LaunchScreen",
"UIMainStoryboardFile": "Main",
"UIRequiredDeviceCapabilities": [
"armv7",
],
"UISupportedInterfaceOrientations": [
"UIInterfaceOrientationPortrait",
"UIInterfaceOrientationLandscapeLeft",
"UIInterfaceOrientationLandscapeRight",
],
"UISupportedInterfaceOrientations~ipad": [
"UIInterfaceOrientationPortrait",
"UIInterfaceOrientationPortraitUpsideDown",
"UIInterfaceOrientationLandscapeLeft",
"UIInterfaceOrientationLandscapeRight",
],
]
}
/// Returns the default Info.plist content that macOS apps should have.
///
/// - Returns: Info.plist content.
func macosApp() -> [String: Any] {
return [
"CFBundleIconFile": "",
"LSMinimumSystemVersion": "$(MACOSX_DEPLOYMENT_TARGET)",
"NSMainStoryboardFile": "Main",
"NSPrincipalClass": "NSApplication",
]
}
/// Returns the default Info.plist content that macOS targets should have.
///
/// - Returns: Info.plist content.
func macos() -> [String: Any] {
return [
"NSHumanReadableCopyright": "Copyright ©. All rights reserved.",
]
}
/// Given a dictionary, it extends it with another dictionary.
///
/// - Parameters:
/// - base: Dictionary to be extended.
/// - with: The content to extend the dictionary with.
fileprivate func extend(_ base: inout [String: Any], with: [String: Any]) {
with.forEach { base[$0.key] = $0.value }
}
}