├── .editorconfig ├── .github └── FUNDING.yml ├── .gitignore ├── AppTemplate.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ ├── MultiPlatformApp.xcscheme │ └── ShareExtension.xcscheme ├── CODE_OF_CONDUCT.md ├── Configurations ├── MultiPlatform.xcconfig ├── MultiPlatformApp.xcconfig ├── MultiPlatformAppTests.xcconfig ├── Project-Debug.xcconfig ├── Project.xcconfig ├── ShareExtension.xcconfig └── SharedFramework.xcconfig ├── LICENSE ├── MultiPlatformApp ├── AppTemplateApp.swift ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── ContentView.swift ├── Info.plist ├── MultiPlatformApp.entitlements └── Preview Content │ └── Preview Assets.xcassets │ └── Contents.json ├── MultiPlatformAppTests └── MultiPlatformAppTests.swift ├── MultiPlatformAppUITests ├── MultiPlatformAppUITests.swift └── MultiPlatformAppUITestsLaunchTests.swift ├── README.md ├── ShareExtension ├── Base.lproj │ └── MainInterface.storyboard ├── Info.plist └── ShareViewController.swift ├── SharedFramework ├── SharedFramework.docc │ └── SharedFramework.md └── SharedFramework.h ├── SharedFrameworkTests └── SharedFrameworkTests.swift └── User.xcconfig.template /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = tab 5 | indent_size = 4 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [mattmassicotte] 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /User.xcconfig 3 | -------------------------------------------------------------------------------- /AppTemplate.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 56; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C923F3612AD2E95B0041D01D /* SharedFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9C2131B2AD1EDB500C60282 /* SharedFramework.framework */; }; 11 | C94722D92AD1859C006DE096 /* AppTemplateApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C94722D82AD1859C006DE096 /* AppTemplateApp.swift */; }; 12 | C94722DB2AD1859C006DE096 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C94722DA2AD1859C006DE096 /* ContentView.swift */; }; 13 | C94722DD2AD1859D006DE096 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C94722DC2AD1859D006DE096 /* Assets.xcassets */; }; 14 | C94722E12AD1859D006DE096 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C94722E02AD1859D006DE096 /* Preview Assets.xcassets */; }; 15 | C94722EB2AD1859E006DE096 /* MultiPlatformAppTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C94722EA2AD1859E006DE096 /* MultiPlatformAppTests.swift */; }; 16 | C94722F52AD1859E006DE096 /* MultiPlatformAppUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C94722F42AD1859E006DE096 /* MultiPlatformAppUITests.swift */; }; 17 | C94722F72AD1859E006DE096 /* MultiPlatformAppUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C94722F62AD1859E006DE096 /* MultiPlatformAppUITestsLaunchTests.swift */; }; 18 | C9C2131F2AD1EDB500C60282 /* SharedFramework.docc in Sources */ = {isa = PBXBuildFile; fileRef = C9C2131E2AD1EDB500C60282 /* SharedFramework.docc */; }; 19 | C9C213252AD1EDB500C60282 /* SharedFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9C2131B2AD1EDB500C60282 /* SharedFramework.framework */; }; 20 | C9C2132C2AD1EDB500C60282 /* SharedFrameworkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C2132B2AD1EDB500C60282 /* SharedFrameworkTests.swift */; }; 21 | C9C2132D2AD1EDB500C60282 /* SharedFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = C9C2131D2AD1EDB500C60282 /* SharedFramework.h */; settings = {ATTRIBUTES = (Public, ); }; }; 22 | C9C213302AD1EDB500C60282 /* SharedFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9C2131B2AD1EDB500C60282 /* SharedFramework.framework */; }; 23 | C9C213312AD1EDB500C60282 /* SharedFramework.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C9C2131B2AD1EDB500C60282 /* SharedFramework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 24 | C9C213422AD2E43E00C60282 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C213412AD2E43E00C60282 /* ShareViewController.swift */; }; 25 | C9C213452AD2E43E00C60282 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C9C213432AD2E43E00C60282 /* MainInterface.storyboard */; }; 26 | C9C2134A2AD2E43E00C60282 /* ShareExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = C9C2133F2AD2E43E00C60282 /* ShareExtension.appex */; platformFilters = (ios, tvos, ); settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXContainerItemProxy section */ 30 | C94722E72AD1859E006DE096 /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = C94722CD2AD1859C006DE096 /* Project object */; 33 | proxyType = 1; 34 | remoteGlobalIDString = C94722D42AD1859C006DE096; 35 | remoteInfo = AppTemplate; 36 | }; 37 | C94722F12AD1859E006DE096 /* PBXContainerItemProxy */ = { 38 | isa = PBXContainerItemProxy; 39 | containerPortal = C94722CD2AD1859C006DE096 /* Project object */; 40 | proxyType = 1; 41 | remoteGlobalIDString = C94722D42AD1859C006DE096; 42 | remoteInfo = AppTemplate; 43 | }; 44 | C9C213262AD1EDB500C60282 /* PBXContainerItemProxy */ = { 45 | isa = PBXContainerItemProxy; 46 | containerPortal = C94722CD2AD1859C006DE096 /* Project object */; 47 | proxyType = 1; 48 | remoteGlobalIDString = C9C2131A2AD1EDB500C60282; 49 | remoteInfo = SharedFramework; 50 | }; 51 | C9C213282AD1EDB500C60282 /* PBXContainerItemProxy */ = { 52 | isa = PBXContainerItemProxy; 53 | containerPortal = C94722CD2AD1859C006DE096 /* Project object */; 54 | proxyType = 1; 55 | remoteGlobalIDString = C94722D42AD1859C006DE096; 56 | remoteInfo = MultiPlatformApp; 57 | }; 58 | C9C2132E2AD1EDB500C60282 /* PBXContainerItemProxy */ = { 59 | isa = PBXContainerItemProxy; 60 | containerPortal = C94722CD2AD1859C006DE096 /* Project object */; 61 | proxyType = 1; 62 | remoteGlobalIDString = C9C2131A2AD1EDB500C60282; 63 | remoteInfo = SharedFramework; 64 | }; 65 | C9C213472AD2E43E00C60282 /* PBXContainerItemProxy */ = { 66 | isa = PBXContainerItemProxy; 67 | containerPortal = C94722CD2AD1859C006DE096 /* Project object */; 68 | proxyType = 1; 69 | remoteGlobalIDString = C9C2133E2AD2E43E00C60282; 70 | remoteInfo = "ShareExtension-iOS"; 71 | }; 72 | C9C2134F2AD2E6BB00C60282 /* PBXContainerItemProxy */ = { 73 | isa = PBXContainerItemProxy; 74 | containerPortal = C94722CD2AD1859C006DE096 /* Project object */; 75 | proxyType = 1; 76 | remoteGlobalIDString = C9C2131A2AD1EDB500C60282; 77 | remoteInfo = SharedFramework; 78 | }; 79 | /* End PBXContainerItemProxy section */ 80 | 81 | /* Begin PBXCopyFilesBuildPhase section */ 82 | C9C213322AD1EDB500C60282 /* Embed Frameworks */ = { 83 | isa = PBXCopyFilesBuildPhase; 84 | buildActionMask = 2147483647; 85 | dstPath = ""; 86 | dstSubfolderSpec = 10; 87 | files = ( 88 | C9C213312AD1EDB500C60282 /* SharedFramework.framework in Embed Frameworks */, 89 | ); 90 | name = "Embed Frameworks"; 91 | runOnlyForDeploymentPostprocessing = 0; 92 | }; 93 | C9C213492AD2E43E00C60282 /* Embed Foundation Extensions */ = { 94 | isa = PBXCopyFilesBuildPhase; 95 | buildActionMask = 2147483647; 96 | dstPath = ""; 97 | dstSubfolderSpec = 13; 98 | files = ( 99 | C9C2134A2AD2E43E00C60282 /* ShareExtension.appex in Embed Foundation Extensions */, 100 | ); 101 | name = "Embed Foundation Extensions"; 102 | runOnlyForDeploymentPostprocessing = 0; 103 | }; 104 | /* End PBXCopyFilesBuildPhase section */ 105 | 106 | /* Begin PBXFileReference section */ 107 | C923F3622AD2EE250041D01D /* MultiPlatform.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = MultiPlatform.xcconfig; sourceTree = ""; }; 108 | C93791A22AD5DD1200665F50 /* Project-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Project-Debug.xcconfig"; sourceTree = ""; }; 109 | C94722D52AD1859C006DE096 /* MultiPlatformApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MultiPlatformApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 110 | C94722D82AD1859C006DE096 /* AppTemplateApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppTemplateApp.swift; sourceTree = ""; }; 111 | C94722DA2AD1859C006DE096 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 112 | C94722DC2AD1859D006DE096 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 113 | C94722DE2AD1859D006DE096 /* MultiPlatformApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MultiPlatformApp.entitlements; sourceTree = ""; }; 114 | C94722E02AD1859D006DE096 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 115 | C94722E62AD1859E006DE096 /* MultiPlatformAppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MultiPlatformAppTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 116 | C94722EA2AD1859E006DE096 /* MultiPlatformAppTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiPlatformAppTests.swift; sourceTree = ""; }; 117 | C94722F02AD1859E006DE096 /* MultiPlatformAppUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MultiPlatformAppUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 118 | C94722F42AD1859E006DE096 /* MultiPlatformAppUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiPlatformAppUITests.swift; sourceTree = ""; }; 119 | C94722F62AD1859E006DE096 /* MultiPlatformAppUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiPlatformAppUITestsLaunchTests.swift; sourceTree = ""; }; 120 | C94723042AD185FB006DE096 /* Project.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Project.xcconfig; sourceTree = ""; }; 121 | C94723052AD1870A006DE096 /* MultiPlatformApp.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = MultiPlatformApp.xcconfig; sourceTree = ""; }; 122 | C94723062AD1AC9E006DE096 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 123 | C9C213152AD1EB8900C60282 /* MultiPlatformAppTests.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = MultiPlatformAppTests.xcconfig; sourceTree = ""; }; 124 | C9C2131B2AD1EDB500C60282 /* SharedFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SharedFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 125 | C9C2131D2AD1EDB500C60282 /* SharedFramework.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SharedFramework.h; sourceTree = ""; }; 126 | C9C2131E2AD1EDB500C60282 /* SharedFramework.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = SharedFramework.docc; sourceTree = ""; }; 127 | C9C213242AD1EDB500C60282 /* SharedFrameworkTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SharedFrameworkTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 128 | C9C2132B2AD1EDB500C60282 /* SharedFrameworkTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharedFrameworkTests.swift; sourceTree = ""; }; 129 | C9C213392AD1EDD500C60282 /* SharedFramework.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = SharedFramework.xcconfig; sourceTree = ""; }; 130 | C9C2133F2AD2E43E00C60282 /* ShareExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 131 | C9C213412AD2E43E00C60282 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = ""; }; 132 | C9C213442AD2E43E00C60282 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = ""; }; 133 | C9C213462AD2E43E00C60282 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 134 | C9C2134E2AD2E4CC00C60282 /* ShareExtension.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = ShareExtension.xcconfig; sourceTree = ""; }; 135 | /* End PBXFileReference section */ 136 | 137 | /* Begin PBXFrameworksBuildPhase section */ 138 | C94722D22AD1859C006DE096 /* Frameworks */ = { 139 | isa = PBXFrameworksBuildPhase; 140 | buildActionMask = 2147483647; 141 | files = ( 142 | C9C213302AD1EDB500C60282 /* SharedFramework.framework in Frameworks */, 143 | ); 144 | runOnlyForDeploymentPostprocessing = 0; 145 | }; 146 | C94722E32AD1859E006DE096 /* Frameworks */ = { 147 | isa = PBXFrameworksBuildPhase; 148 | buildActionMask = 2147483647; 149 | files = ( 150 | ); 151 | runOnlyForDeploymentPostprocessing = 0; 152 | }; 153 | C94722ED2AD1859E006DE096 /* Frameworks */ = { 154 | isa = PBXFrameworksBuildPhase; 155 | buildActionMask = 2147483647; 156 | files = ( 157 | ); 158 | runOnlyForDeploymentPostprocessing = 0; 159 | }; 160 | C9C213182AD1EDB500C60282 /* Frameworks */ = { 161 | isa = PBXFrameworksBuildPhase; 162 | buildActionMask = 2147483647; 163 | files = ( 164 | ); 165 | runOnlyForDeploymentPostprocessing = 0; 166 | }; 167 | C9C213212AD1EDB500C60282 /* Frameworks */ = { 168 | isa = PBXFrameworksBuildPhase; 169 | buildActionMask = 2147483647; 170 | files = ( 171 | C9C213252AD1EDB500C60282 /* SharedFramework.framework in Frameworks */, 172 | ); 173 | runOnlyForDeploymentPostprocessing = 0; 174 | }; 175 | C9C2133C2AD2E43E00C60282 /* Frameworks */ = { 176 | isa = PBXFrameworksBuildPhase; 177 | buildActionMask = 2147483647; 178 | files = ( 179 | C923F3612AD2E95B0041D01D /* SharedFramework.framework in Frameworks */, 180 | ); 181 | runOnlyForDeploymentPostprocessing = 0; 182 | }; 183 | /* End PBXFrameworksBuildPhase section */ 184 | 185 | /* Begin PBXGroup section */ 186 | C923F3602AD2E95B0041D01D /* Frameworks */ = { 187 | isa = PBXGroup; 188 | children = ( 189 | ); 190 | name = Frameworks; 191 | sourceTree = ""; 192 | }; 193 | C94722CC2AD1859C006DE096 = { 194 | isa = PBXGroup; 195 | children = ( 196 | C94723032AD185ED006DE096 /* Configurations */, 197 | C94722D72AD1859C006DE096 /* MultiPlatformApp */, 198 | C94722E92AD1859E006DE096 /* MultiPlatformAppTests */, 199 | C94722F32AD1859E006DE096 /* MultiPlatformAppUITests */, 200 | C9C2131C2AD1EDB500C60282 /* SharedFramework */, 201 | C9C2132A2AD1EDB500C60282 /* SharedFrameworkTests */, 202 | C9C213402AD2E43E00C60282 /* ShareExtension */, 203 | C94722D62AD1859C006DE096 /* Products */, 204 | C923F3602AD2E95B0041D01D /* Frameworks */, 205 | ); 206 | sourceTree = ""; 207 | }; 208 | C94722D62AD1859C006DE096 /* Products */ = { 209 | isa = PBXGroup; 210 | children = ( 211 | C94722D52AD1859C006DE096 /* MultiPlatformApp.app */, 212 | C94722E62AD1859E006DE096 /* MultiPlatformAppTests.xctest */, 213 | C94722F02AD1859E006DE096 /* MultiPlatformAppUITests.xctest */, 214 | C9C2131B2AD1EDB500C60282 /* SharedFramework.framework */, 215 | C9C213242AD1EDB500C60282 /* SharedFrameworkTests.xctest */, 216 | C9C2133F2AD2E43E00C60282 /* ShareExtension.appex */, 217 | ); 218 | name = Products; 219 | sourceTree = ""; 220 | }; 221 | C94722D72AD1859C006DE096 /* MultiPlatformApp */ = { 222 | isa = PBXGroup; 223 | children = ( 224 | C94722D82AD1859C006DE096 /* AppTemplateApp.swift */, 225 | C94722DA2AD1859C006DE096 /* ContentView.swift */, 226 | C94722DC2AD1859D006DE096 /* Assets.xcassets */, 227 | C94722DE2AD1859D006DE096 /* MultiPlatformApp.entitlements */, 228 | C94722DF2AD1859D006DE096 /* Preview Content */, 229 | C94723062AD1AC9E006DE096 /* Info.plist */, 230 | ); 231 | path = MultiPlatformApp; 232 | sourceTree = ""; 233 | }; 234 | C94722DF2AD1859D006DE096 /* Preview Content */ = { 235 | isa = PBXGroup; 236 | children = ( 237 | C94722E02AD1859D006DE096 /* Preview Assets.xcassets */, 238 | ); 239 | path = "Preview Content"; 240 | sourceTree = ""; 241 | }; 242 | C94722E92AD1859E006DE096 /* MultiPlatformAppTests */ = { 243 | isa = PBXGroup; 244 | children = ( 245 | C94722EA2AD1859E006DE096 /* MultiPlatformAppTests.swift */, 246 | ); 247 | path = MultiPlatformAppTests; 248 | sourceTree = ""; 249 | }; 250 | C94722F32AD1859E006DE096 /* MultiPlatformAppUITests */ = { 251 | isa = PBXGroup; 252 | children = ( 253 | C94722F42AD1859E006DE096 /* MultiPlatformAppUITests.swift */, 254 | C94722F62AD1859E006DE096 /* MultiPlatformAppUITestsLaunchTests.swift */, 255 | ); 256 | path = MultiPlatformAppUITests; 257 | sourceTree = ""; 258 | }; 259 | C94723032AD185ED006DE096 /* Configurations */ = { 260 | isa = PBXGroup; 261 | children = ( 262 | C923F3622AD2EE250041D01D /* MultiPlatform.xcconfig */, 263 | C94723052AD1870A006DE096 /* MultiPlatformApp.xcconfig */, 264 | C9C213152AD1EB8900C60282 /* MultiPlatformAppTests.xcconfig */, 265 | C93791A22AD5DD1200665F50 /* Project-Debug.xcconfig */, 266 | C94723042AD185FB006DE096 /* Project.xcconfig */, 267 | C9C213392AD1EDD500C60282 /* SharedFramework.xcconfig */, 268 | C9C2134E2AD2E4CC00C60282 /* ShareExtension.xcconfig */, 269 | ); 270 | path = Configurations; 271 | sourceTree = ""; 272 | }; 273 | C9C2131C2AD1EDB500C60282 /* SharedFramework */ = { 274 | isa = PBXGroup; 275 | children = ( 276 | C9C2131D2AD1EDB500C60282 /* SharedFramework.h */, 277 | C9C2131E2AD1EDB500C60282 /* SharedFramework.docc */, 278 | ); 279 | path = SharedFramework; 280 | sourceTree = ""; 281 | }; 282 | C9C2132A2AD1EDB500C60282 /* SharedFrameworkTests */ = { 283 | isa = PBXGroup; 284 | children = ( 285 | C9C2132B2AD1EDB500C60282 /* SharedFrameworkTests.swift */, 286 | ); 287 | path = SharedFrameworkTests; 288 | sourceTree = ""; 289 | }; 290 | C9C213402AD2E43E00C60282 /* ShareExtension */ = { 291 | isa = PBXGroup; 292 | children = ( 293 | C9C213412AD2E43E00C60282 /* ShareViewController.swift */, 294 | C9C213432AD2E43E00C60282 /* MainInterface.storyboard */, 295 | C9C213462AD2E43E00C60282 /* Info.plist */, 296 | ); 297 | path = ShareExtension; 298 | sourceTree = ""; 299 | }; 300 | /* End PBXGroup section */ 301 | 302 | /* Begin PBXHeadersBuildPhase section */ 303 | C9C213162AD1EDB500C60282 /* Headers */ = { 304 | isa = PBXHeadersBuildPhase; 305 | buildActionMask = 2147483647; 306 | files = ( 307 | C9C2132D2AD1EDB500C60282 /* SharedFramework.h in Headers */, 308 | ); 309 | runOnlyForDeploymentPostprocessing = 0; 310 | }; 311 | /* End PBXHeadersBuildPhase section */ 312 | 313 | /* Begin PBXNativeTarget section */ 314 | C94722D42AD1859C006DE096 /* MultiPlatformApp */ = { 315 | isa = PBXNativeTarget; 316 | buildConfigurationList = C94722FA2AD1859E006DE096 /* Build configuration list for PBXNativeTarget "MultiPlatformApp" */; 317 | buildPhases = ( 318 | C94722D12AD1859C006DE096 /* Sources */, 319 | C94722D22AD1859C006DE096 /* Frameworks */, 320 | C94722D32AD1859C006DE096 /* Resources */, 321 | C9C213322AD1EDB500C60282 /* Embed Frameworks */, 322 | C9C213492AD2E43E00C60282 /* Embed Foundation Extensions */, 323 | ); 324 | buildRules = ( 325 | ); 326 | dependencies = ( 327 | C9C2132F2AD1EDB500C60282 /* PBXTargetDependency */, 328 | C9C213482AD2E43E00C60282 /* PBXTargetDependency */, 329 | ); 330 | name = MultiPlatformApp; 331 | productName = AppTemplate; 332 | productReference = C94722D52AD1859C006DE096 /* MultiPlatformApp.app */; 333 | productType = "com.apple.product-type.application"; 334 | }; 335 | C94722E52AD1859E006DE096 /* MultiPlatformAppTests */ = { 336 | isa = PBXNativeTarget; 337 | buildConfigurationList = C94722FD2AD1859E006DE096 /* Build configuration list for PBXNativeTarget "MultiPlatformAppTests" */; 338 | buildPhases = ( 339 | C94722E22AD1859E006DE096 /* Sources */, 340 | C94722E32AD1859E006DE096 /* Frameworks */, 341 | C94722E42AD1859E006DE096 /* Resources */, 342 | ); 343 | buildRules = ( 344 | ); 345 | dependencies = ( 346 | C94722E82AD1859E006DE096 /* PBXTargetDependency */, 347 | ); 348 | name = MultiPlatformAppTests; 349 | productName = AppTemplateTests; 350 | productReference = C94722E62AD1859E006DE096 /* MultiPlatformAppTests.xctest */; 351 | productType = "com.apple.product-type.bundle.unit-test"; 352 | }; 353 | C94722EF2AD1859E006DE096 /* MultiPlatformAppUITests */ = { 354 | isa = PBXNativeTarget; 355 | buildConfigurationList = C94723002AD1859E006DE096 /* Build configuration list for PBXNativeTarget "MultiPlatformAppUITests" */; 356 | buildPhases = ( 357 | C94722EC2AD1859E006DE096 /* Sources */, 358 | C94722ED2AD1859E006DE096 /* Frameworks */, 359 | C94722EE2AD1859E006DE096 /* Resources */, 360 | ); 361 | buildRules = ( 362 | ); 363 | dependencies = ( 364 | C94722F22AD1859E006DE096 /* PBXTargetDependency */, 365 | ); 366 | name = MultiPlatformAppUITests; 367 | productName = AppTemplateUITests; 368 | productReference = C94722F02AD1859E006DE096 /* MultiPlatformAppUITests.xctest */; 369 | productType = "com.apple.product-type.bundle.ui-testing"; 370 | }; 371 | C9C2131A2AD1EDB500C60282 /* SharedFramework */ = { 372 | isa = PBXNativeTarget; 373 | buildConfigurationList = C9C213372AD1EDB500C60282 /* Build configuration list for PBXNativeTarget "SharedFramework" */; 374 | buildPhases = ( 375 | C9C213162AD1EDB500C60282 /* Headers */, 376 | C9C213172AD1EDB500C60282 /* Sources */, 377 | C9C213182AD1EDB500C60282 /* Frameworks */, 378 | C9C213192AD1EDB500C60282 /* Resources */, 379 | ); 380 | buildRules = ( 381 | ); 382 | dependencies = ( 383 | ); 384 | name = SharedFramework; 385 | productName = SharedFramework; 386 | productReference = C9C2131B2AD1EDB500C60282 /* SharedFramework.framework */; 387 | productType = "com.apple.product-type.framework"; 388 | }; 389 | C9C213232AD1EDB500C60282 /* SharedFrameworkTests */ = { 390 | isa = PBXNativeTarget; 391 | buildConfigurationList = C9C213382AD1EDB500C60282 /* Build configuration list for PBXNativeTarget "SharedFrameworkTests" */; 392 | buildPhases = ( 393 | C9C213202AD1EDB500C60282 /* Sources */, 394 | C9C213212AD1EDB500C60282 /* Frameworks */, 395 | C9C213222AD1EDB500C60282 /* Resources */, 396 | ); 397 | buildRules = ( 398 | ); 399 | dependencies = ( 400 | C9C213272AD1EDB500C60282 /* PBXTargetDependency */, 401 | C9C213292AD1EDB500C60282 /* PBXTargetDependency */, 402 | ); 403 | name = SharedFrameworkTests; 404 | productName = SharedFrameworkTests; 405 | productReference = C9C213242AD1EDB500C60282 /* SharedFrameworkTests.xctest */; 406 | productType = "com.apple.product-type.bundle.unit-test"; 407 | }; 408 | C9C2133E2AD2E43E00C60282 /* ShareExtension */ = { 409 | isa = PBXNativeTarget; 410 | buildConfigurationList = C9C2134B2AD2E43E00C60282 /* Build configuration list for PBXNativeTarget "ShareExtension" */; 411 | buildPhases = ( 412 | C9C2133B2AD2E43E00C60282 /* Sources */, 413 | C9C2133C2AD2E43E00C60282 /* Frameworks */, 414 | C9C2133D2AD2E43E00C60282 /* Resources */, 415 | ); 416 | buildRules = ( 417 | ); 418 | dependencies = ( 419 | C9C213502AD2E6BB00C60282 /* PBXTargetDependency */, 420 | ); 421 | name = ShareExtension; 422 | productName = "ShareExtension-iOS"; 423 | productReference = C9C2133F2AD2E43E00C60282 /* ShareExtension.appex */; 424 | productType = "com.apple.product-type.app-extension"; 425 | }; 426 | /* End PBXNativeTarget section */ 427 | 428 | /* Begin PBXProject section */ 429 | C94722CD2AD1859C006DE096 /* Project object */ = { 430 | isa = PBXProject; 431 | attributes = { 432 | BuildIndependentTargetsInParallel = 1; 433 | LastSwiftUpdateCheck = 1510; 434 | LastUpgradeCheck = 1510; 435 | TargetAttributes = { 436 | C94722D42AD1859C006DE096 = { 437 | CreatedOnToolsVersion = 15.1; 438 | }; 439 | C94722E52AD1859E006DE096 = { 440 | CreatedOnToolsVersion = 15.1; 441 | TestTargetID = C94722D42AD1859C006DE096; 442 | }; 443 | C94722EF2AD1859E006DE096 = { 444 | CreatedOnToolsVersion = 15.1; 445 | TestTargetID = C94722D42AD1859C006DE096; 446 | }; 447 | C9C2131A2AD1EDB500C60282 = { 448 | CreatedOnToolsVersion = 15.1; 449 | }; 450 | C9C213232AD1EDB500C60282 = { 451 | CreatedOnToolsVersion = 15.1; 452 | TestTargetID = C94722D42AD1859C006DE096; 453 | }; 454 | C9C2133E2AD2E43E00C60282 = { 455 | CreatedOnToolsVersion = 15.1; 456 | }; 457 | }; 458 | }; 459 | buildConfigurationList = C94722D02AD1859C006DE096 /* Build configuration list for PBXProject "AppTemplate" */; 460 | compatibilityVersion = "Xcode 14.0"; 461 | developmentRegion = en; 462 | hasScannedForEncodings = 0; 463 | knownRegions = ( 464 | en, 465 | Base, 466 | ); 467 | mainGroup = C94722CC2AD1859C006DE096; 468 | productRefGroup = C94722D62AD1859C006DE096 /* Products */; 469 | projectDirPath = ""; 470 | projectRoot = ""; 471 | targets = ( 472 | C94722D42AD1859C006DE096 /* MultiPlatformApp */, 473 | C94722E52AD1859E006DE096 /* MultiPlatformAppTests */, 474 | C94722EF2AD1859E006DE096 /* MultiPlatformAppUITests */, 475 | C9C2131A2AD1EDB500C60282 /* SharedFramework */, 476 | C9C213232AD1EDB500C60282 /* SharedFrameworkTests */, 477 | C9C2133E2AD2E43E00C60282 /* ShareExtension */, 478 | ); 479 | }; 480 | /* End PBXProject section */ 481 | 482 | /* Begin PBXResourcesBuildPhase section */ 483 | C94722D32AD1859C006DE096 /* Resources */ = { 484 | isa = PBXResourcesBuildPhase; 485 | buildActionMask = 2147483647; 486 | files = ( 487 | C94722E12AD1859D006DE096 /* Preview Assets.xcassets in Resources */, 488 | C94722DD2AD1859D006DE096 /* Assets.xcassets in Resources */, 489 | ); 490 | runOnlyForDeploymentPostprocessing = 0; 491 | }; 492 | C94722E42AD1859E006DE096 /* Resources */ = { 493 | isa = PBXResourcesBuildPhase; 494 | buildActionMask = 2147483647; 495 | files = ( 496 | ); 497 | runOnlyForDeploymentPostprocessing = 0; 498 | }; 499 | C94722EE2AD1859E006DE096 /* Resources */ = { 500 | isa = PBXResourcesBuildPhase; 501 | buildActionMask = 2147483647; 502 | files = ( 503 | ); 504 | runOnlyForDeploymentPostprocessing = 0; 505 | }; 506 | C9C213192AD1EDB500C60282 /* Resources */ = { 507 | isa = PBXResourcesBuildPhase; 508 | buildActionMask = 2147483647; 509 | files = ( 510 | ); 511 | runOnlyForDeploymentPostprocessing = 0; 512 | }; 513 | C9C213222AD1EDB500C60282 /* Resources */ = { 514 | isa = PBXResourcesBuildPhase; 515 | buildActionMask = 2147483647; 516 | files = ( 517 | ); 518 | runOnlyForDeploymentPostprocessing = 0; 519 | }; 520 | C9C2133D2AD2E43E00C60282 /* Resources */ = { 521 | isa = PBXResourcesBuildPhase; 522 | buildActionMask = 2147483647; 523 | files = ( 524 | C9C213452AD2E43E00C60282 /* MainInterface.storyboard in Resources */, 525 | ); 526 | runOnlyForDeploymentPostprocessing = 0; 527 | }; 528 | /* End PBXResourcesBuildPhase section */ 529 | 530 | /* Begin PBXSourcesBuildPhase section */ 531 | C94722D12AD1859C006DE096 /* Sources */ = { 532 | isa = PBXSourcesBuildPhase; 533 | buildActionMask = 2147483647; 534 | files = ( 535 | C94722DB2AD1859C006DE096 /* ContentView.swift in Sources */, 536 | C94722D92AD1859C006DE096 /* AppTemplateApp.swift in Sources */, 537 | ); 538 | runOnlyForDeploymentPostprocessing = 0; 539 | }; 540 | C94722E22AD1859E006DE096 /* Sources */ = { 541 | isa = PBXSourcesBuildPhase; 542 | buildActionMask = 2147483647; 543 | files = ( 544 | C94722EB2AD1859E006DE096 /* MultiPlatformAppTests.swift in Sources */, 545 | ); 546 | runOnlyForDeploymentPostprocessing = 0; 547 | }; 548 | C94722EC2AD1859E006DE096 /* Sources */ = { 549 | isa = PBXSourcesBuildPhase; 550 | buildActionMask = 2147483647; 551 | files = ( 552 | C94722F72AD1859E006DE096 /* MultiPlatformAppUITestsLaunchTests.swift in Sources */, 553 | C94722F52AD1859E006DE096 /* MultiPlatformAppUITests.swift in Sources */, 554 | ); 555 | runOnlyForDeploymentPostprocessing = 0; 556 | }; 557 | C9C213172AD1EDB500C60282 /* Sources */ = { 558 | isa = PBXSourcesBuildPhase; 559 | buildActionMask = 2147483647; 560 | files = ( 561 | C9C2131F2AD1EDB500C60282 /* SharedFramework.docc in Sources */, 562 | ); 563 | runOnlyForDeploymentPostprocessing = 0; 564 | }; 565 | C9C213202AD1EDB500C60282 /* Sources */ = { 566 | isa = PBXSourcesBuildPhase; 567 | buildActionMask = 2147483647; 568 | files = ( 569 | C9C2132C2AD1EDB500C60282 /* SharedFrameworkTests.swift in Sources */, 570 | ); 571 | runOnlyForDeploymentPostprocessing = 0; 572 | }; 573 | C9C2133B2AD2E43E00C60282 /* Sources */ = { 574 | isa = PBXSourcesBuildPhase; 575 | buildActionMask = 2147483647; 576 | files = ( 577 | C9C213422AD2E43E00C60282 /* ShareViewController.swift in Sources */, 578 | ); 579 | runOnlyForDeploymentPostprocessing = 0; 580 | }; 581 | /* End PBXSourcesBuildPhase section */ 582 | 583 | /* Begin PBXTargetDependency section */ 584 | C94722E82AD1859E006DE096 /* PBXTargetDependency */ = { 585 | isa = PBXTargetDependency; 586 | target = C94722D42AD1859C006DE096 /* MultiPlatformApp */; 587 | targetProxy = C94722E72AD1859E006DE096 /* PBXContainerItemProxy */; 588 | }; 589 | C94722F22AD1859E006DE096 /* PBXTargetDependency */ = { 590 | isa = PBXTargetDependency; 591 | target = C94722D42AD1859C006DE096 /* MultiPlatformApp */; 592 | targetProxy = C94722F12AD1859E006DE096 /* PBXContainerItemProxy */; 593 | }; 594 | C9C213272AD1EDB500C60282 /* PBXTargetDependency */ = { 595 | isa = PBXTargetDependency; 596 | target = C9C2131A2AD1EDB500C60282 /* SharedFramework */; 597 | targetProxy = C9C213262AD1EDB500C60282 /* PBXContainerItemProxy */; 598 | }; 599 | C9C213292AD1EDB500C60282 /* PBXTargetDependency */ = { 600 | isa = PBXTargetDependency; 601 | target = C94722D42AD1859C006DE096 /* MultiPlatformApp */; 602 | targetProxy = C9C213282AD1EDB500C60282 /* PBXContainerItemProxy */; 603 | }; 604 | C9C2132F2AD1EDB500C60282 /* PBXTargetDependency */ = { 605 | isa = PBXTargetDependency; 606 | target = C9C2131A2AD1EDB500C60282 /* SharedFramework */; 607 | targetProxy = C9C2132E2AD1EDB500C60282 /* PBXContainerItemProxy */; 608 | }; 609 | C9C213482AD2E43E00C60282 /* PBXTargetDependency */ = { 610 | isa = PBXTargetDependency; 611 | platformFilters = ( 612 | ios, 613 | tvos, 614 | ); 615 | target = C9C2133E2AD2E43E00C60282 /* ShareExtension */; 616 | targetProxy = C9C213472AD2E43E00C60282 /* PBXContainerItemProxy */; 617 | }; 618 | C9C213502AD2E6BB00C60282 /* PBXTargetDependency */ = { 619 | isa = PBXTargetDependency; 620 | target = C9C2131A2AD1EDB500C60282 /* SharedFramework */; 621 | targetProxy = C9C2134F2AD2E6BB00C60282 /* PBXContainerItemProxy */; 622 | }; 623 | /* End PBXTargetDependency section */ 624 | 625 | /* Begin PBXVariantGroup section */ 626 | C9C213432AD2E43E00C60282 /* MainInterface.storyboard */ = { 627 | isa = PBXVariantGroup; 628 | children = ( 629 | C9C213442AD2E43E00C60282 /* Base */, 630 | ); 631 | name = MainInterface.storyboard; 632 | sourceTree = ""; 633 | }; 634 | /* End PBXVariantGroup section */ 635 | 636 | /* Begin XCBuildConfiguration section */ 637 | C94722F82AD1859E006DE096 /* Debug */ = { 638 | isa = XCBuildConfiguration; 639 | baseConfigurationReference = C93791A22AD5DD1200665F50 /* Project-Debug.xcconfig */; 640 | buildSettings = { 641 | ALWAYS_SEARCH_USER_PATHS = NO; 642 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 643 | CLANG_ANALYZER_NONNULL = YES; 644 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 645 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 646 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 647 | CLANG_WARN_BOOL_CONVERSION = YES; 648 | CLANG_WARN_COMMA = YES; 649 | CLANG_WARN_CONSTANT_CONVERSION = YES; 650 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 651 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 652 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 653 | CLANG_WARN_EMPTY_BODY = YES; 654 | CLANG_WARN_ENUM_CONVERSION = YES; 655 | CLANG_WARN_INFINITE_RECURSION = YES; 656 | CLANG_WARN_INT_CONVERSION = YES; 657 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 658 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 659 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 660 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 661 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 662 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 663 | CLANG_WARN_STRICT_PROTOTYPES = YES; 664 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 665 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 666 | CLANG_WARN_UNREACHABLE_CODE = YES; 667 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 668 | COPY_PHASE_STRIP = NO; 669 | DEBUG_INFORMATION_FORMAT = dwarf; 670 | ENABLE_STRICT_OBJC_MSGSEND = YES; 671 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 672 | GCC_C_LANGUAGE_STANDARD = gnu17; 673 | GCC_DYNAMIC_NO_PIC = NO; 674 | GCC_NO_COMMON_BLOCKS = YES; 675 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 676 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 677 | GCC_WARN_UNDECLARED_SELECTOR = YES; 678 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 679 | GCC_WARN_UNUSED_FUNCTION = YES; 680 | GCC_WARN_UNUSED_VARIABLE = YES; 681 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 682 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 683 | MTL_FAST_MATH = YES; 684 | ONLY_ACTIVE_ARCH = YES; 685 | }; 686 | name = Debug; 687 | }; 688 | C94722F92AD1859E006DE096 /* Release */ = { 689 | isa = XCBuildConfiguration; 690 | baseConfigurationReference = C94723042AD185FB006DE096 /* Project.xcconfig */; 691 | buildSettings = { 692 | ALWAYS_SEARCH_USER_PATHS = NO; 693 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 694 | CLANG_ANALYZER_NONNULL = YES; 695 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 696 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 697 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 698 | CLANG_WARN_BOOL_CONVERSION = YES; 699 | CLANG_WARN_COMMA = YES; 700 | CLANG_WARN_CONSTANT_CONVERSION = YES; 701 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 702 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 703 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 704 | CLANG_WARN_EMPTY_BODY = YES; 705 | CLANG_WARN_ENUM_CONVERSION = YES; 706 | CLANG_WARN_INFINITE_RECURSION = YES; 707 | CLANG_WARN_INT_CONVERSION = YES; 708 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 709 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 710 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 711 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 712 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 713 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 714 | CLANG_WARN_STRICT_PROTOTYPES = YES; 715 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 716 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 717 | CLANG_WARN_UNREACHABLE_CODE = YES; 718 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 719 | COPY_PHASE_STRIP = NO; 720 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 721 | ENABLE_NS_ASSERTIONS = NO; 722 | ENABLE_STRICT_OBJC_MSGSEND = YES; 723 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 724 | GCC_C_LANGUAGE_STANDARD = gnu17; 725 | GCC_NO_COMMON_BLOCKS = YES; 726 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 727 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 728 | GCC_WARN_UNDECLARED_SELECTOR = YES; 729 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 730 | GCC_WARN_UNUSED_FUNCTION = YES; 731 | GCC_WARN_UNUSED_VARIABLE = YES; 732 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 733 | MTL_ENABLE_DEBUG_INFO = NO; 734 | MTL_FAST_MATH = YES; 735 | }; 736 | name = Release; 737 | }; 738 | C94722FB2AD1859E006DE096 /* Debug */ = { 739 | isa = XCBuildConfiguration; 740 | baseConfigurationReference = C94723052AD1870A006DE096 /* MultiPlatformApp.xcconfig */; 741 | buildSettings = { 742 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 743 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 744 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 745 | ENABLE_PREVIEWS = YES; 746 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; 747 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; 748 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; 749 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES; 750 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES; 751 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES; 752 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault; 753 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault; 754 | SDKROOT = auto; 755 | SWIFT_EMIT_LOC_STRINGS = YES; 756 | }; 757 | name = Debug; 758 | }; 759 | C94722FC2AD1859E006DE096 /* Release */ = { 760 | isa = XCBuildConfiguration; 761 | baseConfigurationReference = C94723052AD1870A006DE096 /* MultiPlatformApp.xcconfig */; 762 | buildSettings = { 763 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 764 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 765 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 766 | ENABLE_PREVIEWS = YES; 767 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; 768 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; 769 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; 770 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES; 771 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES; 772 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES; 773 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault; 774 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault; 775 | SDKROOT = auto; 776 | SWIFT_EMIT_LOC_STRINGS = YES; 777 | }; 778 | name = Release; 779 | }; 780 | C94722FE2AD1859E006DE096 /* Debug */ = { 781 | isa = XCBuildConfiguration; 782 | baseConfigurationReference = C9C213152AD1EB8900C60282 /* MultiPlatformAppTests.xcconfig */; 783 | buildSettings = { 784 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 785 | BUNDLE_LOADER = "$(TEST_HOST)"; 786 | GENERATE_INFOPLIST_FILE = YES; 787 | PRODUCT_NAME = "$(TARGET_NAME)"; 788 | SDKROOT = auto; 789 | SWIFT_EMIT_LOC_STRINGS = NO; 790 | }; 791 | name = Debug; 792 | }; 793 | C94722FF2AD1859E006DE096 /* Release */ = { 794 | isa = XCBuildConfiguration; 795 | baseConfigurationReference = C9C213152AD1EB8900C60282 /* MultiPlatformAppTests.xcconfig */; 796 | buildSettings = { 797 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 798 | BUNDLE_LOADER = "$(TEST_HOST)"; 799 | GENERATE_INFOPLIST_FILE = YES; 800 | PRODUCT_NAME = "$(TARGET_NAME)"; 801 | SDKROOT = auto; 802 | SWIFT_EMIT_LOC_STRINGS = NO; 803 | }; 804 | name = Release; 805 | }; 806 | C94723012AD1859E006DE096 /* Debug */ = { 807 | isa = XCBuildConfiguration; 808 | buildSettings = { 809 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 810 | GENERATE_INFOPLIST_FILE = YES; 811 | PRODUCT_BUNDLE_IDENTIFIER = org.massicotte.AppTemplateUITests; 812 | PRODUCT_NAME = "$(TARGET_NAME)"; 813 | SDKROOT = auto; 814 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; 815 | SWIFT_EMIT_LOC_STRINGS = NO; 816 | TARGETED_DEVICE_FAMILY = "1,2"; 817 | TEST_TARGET_NAME = AppTemplate; 818 | }; 819 | name = Debug; 820 | }; 821 | C94723022AD1859E006DE096 /* Release */ = { 822 | isa = XCBuildConfiguration; 823 | buildSettings = { 824 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 825 | GENERATE_INFOPLIST_FILE = YES; 826 | PRODUCT_BUNDLE_IDENTIFIER = org.massicotte.AppTemplateUITests; 827 | PRODUCT_NAME = "$(TARGET_NAME)"; 828 | SDKROOT = auto; 829 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; 830 | SWIFT_EMIT_LOC_STRINGS = NO; 831 | TARGETED_DEVICE_FAMILY = "1,2"; 832 | TEST_TARGET_NAME = AppTemplate; 833 | }; 834 | name = Release; 835 | }; 836 | C9C213332AD1EDB500C60282 /* Debug */ = { 837 | isa = XCBuildConfiguration; 838 | baseConfigurationReference = C9C213392AD1EDD500C60282 /* SharedFramework.xcconfig */; 839 | buildSettings = { 840 | CLANG_ENABLE_MODULES = YES; 841 | CLANG_ENABLE_OBJC_ARC = YES; 842 | CLANG_ENABLE_OBJC_WEAK = YES; 843 | CODE_SIGN_STYLE = Automatic; 844 | DEFINES_MODULE = YES; 845 | DYLIB_CURRENT_VERSION = 1; 846 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 847 | ENABLE_MODULE_VERIFIER = YES; 848 | GCC_PREPROCESSOR_DEFINITIONS = ( 849 | "DEBUG=1", 850 | "$(inherited)", 851 | ); 852 | GENERATE_INFOPLIST_FILE = YES; 853 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 854 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 855 | MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; 856 | MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; 857 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 858 | SDKROOT = auto; 859 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; 860 | SWIFT_EMIT_LOC_STRINGS = YES; 861 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 862 | SWIFT_VERSION = 5.0; 863 | VERSIONING_SYSTEM = "apple-generic"; 864 | VERSION_INFO_PREFIX = ""; 865 | }; 866 | name = Debug; 867 | }; 868 | C9C213342AD1EDB500C60282 /* Release */ = { 869 | isa = XCBuildConfiguration; 870 | baseConfigurationReference = C9C213392AD1EDD500C60282 /* SharedFramework.xcconfig */; 871 | buildSettings = { 872 | CLANG_ENABLE_MODULES = YES; 873 | CLANG_ENABLE_OBJC_ARC = YES; 874 | CLANG_ENABLE_OBJC_WEAK = YES; 875 | CODE_SIGN_STYLE = Automatic; 876 | DEFINES_MODULE = YES; 877 | DYLIB_CURRENT_VERSION = 1; 878 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 879 | ENABLE_MODULE_VERIFIER = YES; 880 | GENERATE_INFOPLIST_FILE = YES; 881 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 882 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 883 | MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; 884 | MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; 885 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 886 | SDKROOT = auto; 887 | SWIFT_COMPILATION_MODE = wholemodule; 888 | SWIFT_EMIT_LOC_STRINGS = YES; 889 | SWIFT_VERSION = 5.0; 890 | VERSIONING_SYSTEM = "apple-generic"; 891 | VERSION_INFO_PREFIX = ""; 892 | }; 893 | name = Release; 894 | }; 895 | C9C213352AD1EDB500C60282 /* Debug */ = { 896 | isa = XCBuildConfiguration; 897 | buildSettings = { 898 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 899 | CLANG_ENABLE_MODULES = YES; 900 | CLANG_ENABLE_OBJC_ARC = YES; 901 | CLANG_ENABLE_OBJC_WEAK = YES; 902 | CODE_SIGN_STYLE = Automatic; 903 | CURRENT_PROJECT_VERSION = 1; 904 | DEVELOPMENT_TEAM = 77X93NZ3G2; 905 | GCC_PREPROCESSOR_DEFINITIONS = ( 906 | "DEBUG=1", 907 | "$(inherited)", 908 | ); 909 | GENERATE_INFOPLIST_FILE = YES; 910 | IPHONEOS_DEPLOYMENT_TARGET = 17.0; 911 | MACOSX_DEPLOYMENT_TARGET = 14.0; 912 | MARKETING_VERSION = 1.0; 913 | PRODUCT_BUNDLE_IDENTIFIER = org.massicotte.SharedFrameworkTests; 914 | PRODUCT_NAME = "$(TARGET_NAME)"; 915 | SDKROOT = auto; 916 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; 917 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; 918 | SWIFT_EMIT_LOC_STRINGS = NO; 919 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 920 | SWIFT_VERSION = 5.0; 921 | TARGETED_DEVICE_FAMILY = "1,2"; 922 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MultiPlatformApp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/MultiPlatformApp"; 923 | }; 924 | name = Debug; 925 | }; 926 | C9C213362AD1EDB500C60282 /* Release */ = { 927 | isa = XCBuildConfiguration; 928 | buildSettings = { 929 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 930 | CLANG_ENABLE_MODULES = YES; 931 | CLANG_ENABLE_OBJC_ARC = YES; 932 | CLANG_ENABLE_OBJC_WEAK = YES; 933 | CODE_SIGN_STYLE = Automatic; 934 | CURRENT_PROJECT_VERSION = 1; 935 | DEVELOPMENT_TEAM = 77X93NZ3G2; 936 | GENERATE_INFOPLIST_FILE = YES; 937 | IPHONEOS_DEPLOYMENT_TARGET = 17.0; 938 | MACOSX_DEPLOYMENT_TARGET = 14.0; 939 | MARKETING_VERSION = 1.0; 940 | PRODUCT_BUNDLE_IDENTIFIER = org.massicotte.SharedFrameworkTests; 941 | PRODUCT_NAME = "$(TARGET_NAME)"; 942 | SDKROOT = auto; 943 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; 944 | SWIFT_COMPILATION_MODE = wholemodule; 945 | SWIFT_EMIT_LOC_STRINGS = NO; 946 | SWIFT_VERSION = 5.0; 947 | TARGETED_DEVICE_FAMILY = "1,2"; 948 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MultiPlatformApp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/MultiPlatformApp"; 949 | }; 950 | name = Release; 951 | }; 952 | C9C2134C2AD2E43E00C60282 /* Debug */ = { 953 | isa = XCBuildConfiguration; 954 | baseConfigurationReference = C9C2134E2AD2E4CC00C60282 /* ShareExtension.xcconfig */; 955 | buildSettings = { 956 | CLANG_ENABLE_MODULES = YES; 957 | GENERATE_INFOPLIST_FILE = YES; 958 | INFOPLIST_KEY_CFBundleDisplayName = "ShareExtension-iOS"; 959 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 960 | LD_RUNPATH_SEARCH_PATHS = ( 961 | "$(inherited)", 962 | "@executable_path/Frameworks", 963 | "@executable_path/../../Frameworks", 964 | ); 965 | SDKROOT = iphoneos; 966 | SWIFT_EMIT_LOC_STRINGS = YES; 967 | TARGETED_DEVICE_FAMILY = "1,2"; 968 | }; 969 | name = Debug; 970 | }; 971 | C9C2134D2AD2E43E00C60282 /* Release */ = { 972 | isa = XCBuildConfiguration; 973 | baseConfigurationReference = C9C2134E2AD2E4CC00C60282 /* ShareExtension.xcconfig */; 974 | buildSettings = { 975 | CLANG_ENABLE_MODULES = YES; 976 | GENERATE_INFOPLIST_FILE = YES; 977 | INFOPLIST_KEY_CFBundleDisplayName = "ShareExtension-iOS"; 978 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 979 | LD_RUNPATH_SEARCH_PATHS = ( 980 | "$(inherited)", 981 | "@executable_path/Frameworks", 982 | "@executable_path/../../Frameworks", 983 | ); 984 | SDKROOT = iphoneos; 985 | SWIFT_EMIT_LOC_STRINGS = YES; 986 | TARGETED_DEVICE_FAMILY = "1,2"; 987 | VALIDATE_PRODUCT = YES; 988 | }; 989 | name = Release; 990 | }; 991 | /* End XCBuildConfiguration section */ 992 | 993 | /* Begin XCConfigurationList section */ 994 | C94722D02AD1859C006DE096 /* Build configuration list for PBXProject "AppTemplate" */ = { 995 | isa = XCConfigurationList; 996 | buildConfigurations = ( 997 | C94722F82AD1859E006DE096 /* Debug */, 998 | C94722F92AD1859E006DE096 /* Release */, 999 | ); 1000 | defaultConfigurationIsVisible = 0; 1001 | defaultConfigurationName = Release; 1002 | }; 1003 | C94722FA2AD1859E006DE096 /* Build configuration list for PBXNativeTarget "MultiPlatformApp" */ = { 1004 | isa = XCConfigurationList; 1005 | buildConfigurations = ( 1006 | C94722FB2AD1859E006DE096 /* Debug */, 1007 | C94722FC2AD1859E006DE096 /* Release */, 1008 | ); 1009 | defaultConfigurationIsVisible = 0; 1010 | defaultConfigurationName = Release; 1011 | }; 1012 | C94722FD2AD1859E006DE096 /* Build configuration list for PBXNativeTarget "MultiPlatformAppTests" */ = { 1013 | isa = XCConfigurationList; 1014 | buildConfigurations = ( 1015 | C94722FE2AD1859E006DE096 /* Debug */, 1016 | C94722FF2AD1859E006DE096 /* Release */, 1017 | ); 1018 | defaultConfigurationIsVisible = 0; 1019 | defaultConfigurationName = Release; 1020 | }; 1021 | C94723002AD1859E006DE096 /* Build configuration list for PBXNativeTarget "MultiPlatformAppUITests" */ = { 1022 | isa = XCConfigurationList; 1023 | buildConfigurations = ( 1024 | C94723012AD1859E006DE096 /* Debug */, 1025 | C94723022AD1859E006DE096 /* Release */, 1026 | ); 1027 | defaultConfigurationIsVisible = 0; 1028 | defaultConfigurationName = Release; 1029 | }; 1030 | C9C213372AD1EDB500C60282 /* Build configuration list for PBXNativeTarget "SharedFramework" */ = { 1031 | isa = XCConfigurationList; 1032 | buildConfigurations = ( 1033 | C9C213332AD1EDB500C60282 /* Debug */, 1034 | C9C213342AD1EDB500C60282 /* Release */, 1035 | ); 1036 | defaultConfigurationIsVisible = 0; 1037 | defaultConfigurationName = Release; 1038 | }; 1039 | C9C213382AD1EDB500C60282 /* Build configuration list for PBXNativeTarget "SharedFrameworkTests" */ = { 1040 | isa = XCConfigurationList; 1041 | buildConfigurations = ( 1042 | C9C213352AD1EDB500C60282 /* Debug */, 1043 | C9C213362AD1EDB500C60282 /* Release */, 1044 | ); 1045 | defaultConfigurationIsVisible = 0; 1046 | defaultConfigurationName = Release; 1047 | }; 1048 | C9C2134B2AD2E43E00C60282 /* Build configuration list for PBXNativeTarget "ShareExtension" */ = { 1049 | isa = XCConfigurationList; 1050 | buildConfigurations = ( 1051 | C9C2134C2AD2E43E00C60282 /* Debug */, 1052 | C9C2134D2AD2E43E00C60282 /* Release */, 1053 | ); 1054 | defaultConfigurationIsVisible = 0; 1055 | defaultConfigurationName = Release; 1056 | }; 1057 | /* End XCConfigurationList section */ 1058 | }; 1059 | rootObject = C94722CD2AD1859C006DE096 /* Project object */; 1060 | } 1061 | -------------------------------------------------------------------------------- /AppTemplate.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /AppTemplate.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /AppTemplate.xcodeproj/xcshareddata/xcschemes/MultiPlatformApp.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 35 | 41 | 42 | 43 | 46 | 52 | 53 | 54 | 57 | 63 | 64 | 65 | 66 | 67 | 77 | 79 | 85 | 86 | 87 | 88 | 94 | 96 | 102 | 103 | 104 | 105 | 107 | 108 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /AppTemplate.xcodeproj/xcshareddata/xcschemes/ShareExtension.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 6 | 9 | 10 | 16 | 22 | 23 | 24 | 30 | 36 | 37 | 38 | 39 | 40 | 46 | 47 | 59 | 61 | 67 | 68 | 69 | 70 | 78 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | # Contributor Covenant Code of Conduct 3 | 4 | ## Our Pledge 5 | 6 | We as members, contributors, and leaders pledge to make participation in our 7 | community a harassment-free experience for everyone, regardless of age, body 8 | size, visible or invisible disability, ethnicity, sex characteristics, gender 9 | identity and expression, level of experience, education, socio-economic status, 10 | nationality, personal appearance, race, caste, color, religion, or sexual 11 | identity and orientation. 12 | 13 | We pledge to act and interact in ways that contribute to an open, welcoming, 14 | diverse, inclusive, and healthy community. 15 | 16 | ## Our Standards 17 | 18 | Examples of behavior that contributes to a positive environment for our 19 | community include: 20 | 21 | * Demonstrating empathy and kindness toward other people 22 | * Being respectful of differing opinions, viewpoints, and experiences 23 | * Giving and gracefully accepting constructive feedback 24 | * Accepting responsibility and apologizing to those affected by our mistakes, 25 | and learning from the experience 26 | * Focusing on what is best not just for us as individuals, but for the overall 27 | community 28 | 29 | Examples of unacceptable behavior include: 30 | 31 | * The use of sexualized language or imagery, and sexual attention or advances of 32 | any kind 33 | * Trolling, insulting or derogatory comments, and personal or political attacks 34 | * Public or private harassment 35 | * Publishing others' private information, such as a physical or email address, 36 | without their explicit permission 37 | * Other conduct which could reasonably be considered inappropriate in a 38 | professional setting 39 | 40 | ## Enforcement Responsibilities 41 | 42 | Community leaders are responsible for clarifying and enforcing our standards of 43 | acceptable behavior and will take appropriate and fair corrective action in 44 | response to any behavior that they deem inappropriate, threatening, offensive, 45 | or harmful. 46 | 47 | Community leaders have the right and responsibility to remove, edit, or reject 48 | comments, commits, code, wiki edits, issues, and other contributions that are 49 | not aligned to this Code of Conduct, and will communicate reasons for moderation 50 | decisions when appropriate. 51 | 52 | ## Scope 53 | 54 | This Code of Conduct applies within all community spaces, and also applies when 55 | an individual is officially representing the community in public spaces. 56 | Examples of representing our community include using an official e-mail address, 57 | posting via an official social media account, or acting as an appointed 58 | representative at an online or offline event. 59 | 60 | ## Enforcement 61 | 62 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 63 | reported to the community leaders responsible for enforcement at 64 | support@chimehq.com. 65 | All complaints will be reviewed and investigated promptly and fairly. 66 | 67 | All community leaders are obligated to respect the privacy and security of the 68 | reporter of any incident. 69 | 70 | ## Enforcement Guidelines 71 | 72 | Community leaders will follow these Community Impact Guidelines in determining 73 | the consequences for any action they deem in violation of this Code of Conduct: 74 | 75 | ### 1. Correction 76 | 77 | **Community Impact**: Use of inappropriate language or other behavior deemed 78 | unprofessional or unwelcome in the community. 79 | 80 | **Consequence**: A private, written warning from community leaders, providing 81 | clarity around the nature of the violation and an explanation of why the 82 | behavior was inappropriate. A public apology may be requested. 83 | 84 | ### 2. Warning 85 | 86 | **Community Impact**: A violation through a single incident or series of 87 | actions. 88 | 89 | **Consequence**: A warning with consequences for continued behavior. No 90 | interaction with the people involved, including unsolicited interaction with 91 | those enforcing the Code of Conduct, for a specified period of time. This 92 | includes avoiding interactions in community spaces as well as external channels 93 | like social media. Violating these terms may lead to a temporary or permanent 94 | ban. 95 | 96 | ### 3. Temporary Ban 97 | 98 | **Community Impact**: A serious violation of community standards, including 99 | sustained inappropriate behavior. 100 | 101 | **Consequence**: A temporary ban from any sort of interaction or public 102 | communication with the community for a specified period of time. No public or 103 | private interaction with the people involved, including unsolicited interaction 104 | with those enforcing the Code of Conduct, is allowed during this period. 105 | Violating these terms may lead to a permanent ban. 106 | 107 | ### 4. Permanent Ban 108 | 109 | **Community Impact**: Demonstrating a pattern of violation of community 110 | standards, including sustained inappropriate behavior, harassment of an 111 | individual, or aggression toward or disparagement of classes of individuals. 112 | 113 | **Consequence**: A permanent ban from any sort of public interaction within the 114 | community. 115 | 116 | ## Attribution 117 | 118 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 119 | version 2.1, available at 120 | [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. 121 | 122 | Community Impact Guidelines were inspired by 123 | [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. 124 | 125 | For answers to common questions about this code of conduct, see the FAQ at 126 | [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at 127 | [https://www.contributor-covenant.org/translations][translations]. 128 | 129 | [homepage]: https://www.contributor-covenant.org 130 | [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html 131 | [Mozilla CoC]: https://github.com/mozilla/diversity 132 | [FAQ]: https://www.contributor-covenant.org/faq 133 | [translations]: https://www.contributor-covenant.org/translations 134 | -------------------------------------------------------------------------------- /Configurations/MultiPlatform.xcconfig: -------------------------------------------------------------------------------- 1 | // add support for all platforms 2 | SUPPORTED_PLATFORMS = macosx iphonesimulator iphoneos appletvsimulator appletvos xrsimulator xros watchsimulator watchos 3 | 4 | // support all devices types: 5 | // 1: iPhone 6 | // 2: iPad 7 | // 3: TV 8 | // 4: Watch 9 | // 5: ??? 10 | // 6: Unscaled Catalyst 11 | // 7: Vision 12 | TARGETED_DEVICE_FAMILY = 1,2,3,4,6,7 13 | 14 | //:configuration = Debug 15 | INFOPLIST_KEY_UISupportedInterfaceOrientations[sdk=watch*] = UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown 16 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad[sdk=iphone*] = UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight 17 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone[sdk=iphone*] = UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight 18 | 19 | SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES 20 | SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES 21 | -------------------------------------------------------------------------------- /Configurations/MultiPlatformApp.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Configurations/MultiPlatform.xcconfig" 2 | 3 | INFOPLIST_FILE = ${TARGET_NAME}/Info.plist 4 | CODE_SIGN_ENTITLEMENTS = ${TARGET_NAME}/${TARGET_NAME}.entitlements 5 | GENERATE_INFOPLIST_FILE = YES 6 | 7 | DEVELOPMENT_ASSET_PATHS = ${TARGET_NAME}/Preview\ Content 8 | 9 | SKIP_INSTALL = NO 10 | 11 | // note that the bundle layout of macOS apps is slightly different 12 | LD_RUNPATH_SEARCH_PATHS = @executable_path/Frameworks 13 | LD_RUNPATH_SEARCH_PATHS[sdk=macosx*] = @executable_path/../Frameworks 14 | 15 | // customize this info.plist key for watchOS 16 | INFOPLIST_KEY_WKWatchOnly[sdk=watch*] = YES 17 | -------------------------------------------------------------------------------- /Configurations/MultiPlatformAppTests.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Configurations/MultiPlatform.xcconfig" 2 | 3 | TEST_HOST = $(BUILT_PRODUCTS_DIR)/MultiPlatformApp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/MultiPlatformApp 4 | -------------------------------------------------------------------------------- /Configurations/Project-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Project.xcconfig" 2 | 3 | GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1 4 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG 5 | SWIFT_OPTIMIZATION_LEVEL = -Onone 6 | SWIFT_COMPILATION_MODE = $(inherited) 7 | GCC_OPTIMIZATION_LEVEL = 0 8 | ENABLE_TESTABILITY = YES 9 | -------------------------------------------------------------------------------- /Configurations/Project.xcconfig: -------------------------------------------------------------------------------- 1 | #include "User.xcconfig" 2 | 3 | // Primary behaviors 4 | MACOSX_DEPLOYMENT_TARGET = 14.0 5 | IPHONEOS_DEPLOYMENT_TARGET = 17.0 6 | TVOS_DEPLOYMENT_TARGET = 17.0 7 | WATCHOS_DEPLOYMENT_TARGET = 10.0 8 | VISIONOS_DEPLOYMENT_TARGET = 1.0 9 | ENABLE_HARDENED_RUNTIME = YES 10 | DEAD_CODE_STRIPPING = YES 11 | SWIFT_STRICT_CONCURRENCY = complete 12 | SWIFT_VERSION = 5.0 13 | CODE_SIGN_STYLE = Automatic 14 | CODE_SIGN_IDENTITY = Apple Development 15 | PRODUCT_NAME = $(TARGET_NAME) 16 | 17 | // Version information 18 | CURRENT_PROJECT_VERSION = 1 19 | CURRENT_PROJECT_DISPLAY_VERSION = 1.0.0 20 | MARKETING_VERSION = $CURRENT_PROJECT_DISPLAY_VERSION 21 | 22 | // Secondary behaviors 23 | SWIFT_COMPILATION_MODE = wholemodule 24 | 25 | // Modern recommendations, but not critical 26 | ALWAYS_SEARCH_USER_PATHS = NO 27 | CLANG_ENABLE_MODULES = YES 28 | CLANG_ENABLE_OBJC_ARC = YES 29 | CLANG_ENABLE_OBJC_WEAK = YES 30 | 31 | // Default target settings 32 | PRODUCT_NAME = ${TARGET_NAME} 33 | PRODUCT_MODULE_NAME = ${TARGET_NAME} 34 | PRODUCT_BUNDLE_IDENTIFIER = $(BUNDLE_ID_PREFIX)org.massicotte.${PRODUCT_MODULE_NAME} 35 | SKIP_INSTALL = YES 36 | -------------------------------------------------------------------------------- /Configurations/ShareExtension.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Configurations/MultiPlatform.xcconfig" 2 | 3 | INFOPLIST_FILE = ${TARGET_NAME}/Info.plist 4 | PRODUCT_BUNDLE_IDENTIFIER = $(BUNDLE_ID_PREFIX)org.massicotte.MultiPlatformApp.${TARGET_NAME} 5 | 6 | // must override platforms to remove macOS, share extension aren't supported there 7 | // and, the social default doesn't work on xros 8 | SUPPORTED_PLATFORMS = iphonesimulator iphoneos appletvsimulator appletvos 9 | -------------------------------------------------------------------------------- /Configurations/SharedFramework.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Configurations/MultiPlatform.xcconfig" 2 | 3 | // note that the bundle layout of macOS apps is slightly different 4 | LD_RUNPATH_SEARCH_PATHS = @executable_path/Frameworks @loader_path/Frameworks 5 | LD_RUNPATH_SEARCH_PATHS[sdk=macosx*] = @executable_path/../Frameworks @loader_path/Frameworks 6 | 7 | DYLIB_COMPATIBILITY_VERSION = 1 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2023, Matt Massicotte 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /MultiPlatformApp/AppTemplateApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppTemplateApp.swift 3 | // AppTemplate 4 | // 5 | // Created by Matthew Massicotte on 2023-10-07. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct AppTemplateApp: App { 12 | var body: some Scene { 13 | WindowGroup { 14 | ContentView() 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /MultiPlatformApp/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MultiPlatformApp/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "1x", 11 | "size" : "16x16" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "scale" : "2x", 16 | "size" : "16x16" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "scale" : "1x", 21 | "size" : "32x32" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "scale" : "2x", 26 | "size" : "32x32" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "scale" : "1x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "scale" : "2x", 36 | "size" : "128x128" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "scale" : "1x", 41 | "size" : "256x256" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "scale" : "2x", 46 | "size" : "256x256" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "scale" : "1x", 51 | "size" : "512x512" 52 | }, 53 | { 54 | "idiom" : "mac", 55 | "scale" : "2x", 56 | "size" : "512x512" 57 | } 58 | ], 59 | "info" : { 60 | "author" : "xcode", 61 | "version" : 1 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /MultiPlatformApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /MultiPlatformApp/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // AppTemplate 4 | // 5 | // Created by Matthew Massicotte on 2023-10-07. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ContentView: View { 11 | var body: some View { 12 | VStack { 13 | Image(systemName: "globe") 14 | .imageScale(.large) 15 | .foregroundStyle(.tint) 16 | Text("Hello, world!") 17 | } 18 | .padding() 19 | } 20 | } 21 | 22 | #Preview { 23 | ContentView() 24 | } 25 | -------------------------------------------------------------------------------- /MultiPlatformApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /MultiPlatformApp/MultiPlatformApp.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MultiPlatformApp/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /MultiPlatformAppTests/MultiPlatformAppTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | final class MultiPlatformAppTests: XCTestCase { 4 | 5 | override func setUpWithError() throws { 6 | // Put setup code here. This method is called before the invocation of each test method in the class. 7 | } 8 | 9 | override func tearDownWithError() throws { 10 | // Put teardown code here. This method is called after the invocation of each test method in the class. 11 | } 12 | 13 | func testExample() throws { 14 | // This is an example of a functional test case. 15 | // Use XCTAssert and related functions to verify your tests produce the correct results. 16 | // Any test you write for XCTest can be annotated as throws and async. 17 | // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error. 18 | // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards. 19 | } 20 | 21 | func testPerformanceExample() throws { 22 | // This is an example of a performance test case. 23 | measure { 24 | // Put the code you want to measure the time of here. 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /MultiPlatformAppUITests/MultiPlatformAppUITests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | final class MultiPlatformAppUITests: XCTestCase { 4 | 5 | override func setUpWithError() throws { 6 | // Put setup code here. This method is called before the invocation of each test method in the class. 7 | 8 | // In UI tests it is usually best to stop immediately when a failure occurs. 9 | continueAfterFailure = false 10 | 11 | // 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. 12 | } 13 | 14 | override func tearDownWithError() throws { 15 | // Put teardown code here. This method is called after the invocation of each test method in the class. 16 | } 17 | 18 | func testExample() throws { 19 | // UI tests must launch the application that they test. 20 | let app = XCUIApplication() 21 | app.launch() 22 | 23 | // Use XCTAssert and related functions to verify your tests produce the correct results. 24 | } 25 | 26 | func testLaunchPerformance() throws { 27 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) { 28 | // This measures how long it takes to launch your application. 29 | measure(metrics: [XCTApplicationLaunchMetric()]) { 30 | XCUIApplication().launch() 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /MultiPlatformAppUITests/MultiPlatformAppUITestsLaunchTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | final class MultiPlatformAppUITestsLaunchTests: XCTestCase { 4 | 5 | override class var runsForEachTargetApplicationUIConfiguration: Bool { 6 | true 7 | } 8 | 9 | override func setUpWithError() throws { 10 | continueAfterFailure = false 11 | } 12 | 13 | func testLaunch() throws { 14 | let app = XCUIApplication() 15 | app.launch() 16 | 17 | // Insert steps here to perform after app launch but before taking a screenshot, 18 | // such as logging into a test account or navigating somewhere in the app 19 | 20 | let attachment = XCTAttachment(screenshot: app.screenshot()) 21 | attachment.name = "Launch Screen" 22 | attachment.lifetime = .keepAlways 23 | add(attachment) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AppTemplate 2 | A template for building apps with Xcode 3 | 4 | Getting set up to build apps in Xcode might seem easy, since it comes with templates. However, Xcode is complex and those templates don't always set things up as I'd like. So, I thought I'd share a slightly opinionated approach to structuring an Xcode project. This follows a similar pattern I've used for [packages](https://github.com/mattmassicotte/PackageTemplate). 5 | 6 | By no means is this a one-size-fits-all kind of problem. Projects can be tremendously complex, with all kinds of different needs. But, I still think what's here is at least a good starting point. If you have ideas for ways to improve this, please open an issue or PR! 7 | 8 | ## Overall Project Organization 9 | 10 | This Xcode project makes use of [xcconfig](https://developer.apple.com/documentation/xcode/adding-a-build-configuration-file-to-your-project) files. I've been using these for a while, and I find it difficult to control my target settings without these. I don't always migrate every setting in, but I always use them when I need to change something. 11 | 12 | `User.xcconfig`: a special config file that holds per-user settings. This comes in really handy for open source apps, but is unnecessary for any app that shares a single development team. 13 | `Project.xcconfig`: global settings that apply to all targets within the project. Occasionally it does make sense to override these defaults, but that's rare. `User.xcconfig` is included here. 14 | 15 | This was all set up with Xcode 15.1. 16 | 17 | ## Building 18 | 19 | This project separates out signing and bundle identifier details. This makes sense for a project that may have collaborators that do not share code signing information. 20 | 21 | - clone the repo 22 | - `cp User.xcconfig.template User.xcconfig` 23 | - update `User.xcconfig` with your personal information 24 | - build/run with Xcode 25 | 26 | ## Targets 27 | 28 | Because there can be such a variety of targets, I thought it would be useful to create a bunch. Your project almost certainly doesn't need them all. 29 | 30 | ### MultiPlatformApp 31 | 32 | This is a standard application target that builds for all Apple platforms: macOS, iOS, tvOS, visionOS, watchOS, and catalyst. Multi-platform targets are kind of amazing, and used to be extremely difficult to pull off. I **absolutely** love supporting multiple platforms, even if you don't intend on shipping to all. Especially macOS, since it doesn't require a simulator, and can build/test with much less overhead. 33 | 34 | This app also includes two related test targets: `MultiPlatformAppTests` and `MultiPlatformAppUITests`. 35 | 36 | Note that supporting watchOS is a little special, since there are multiple types of watchOS apps. This is a true standalone app, with no iOS companion. I have a feeling this isn't what most people would want, but its possible so I included it. It's also a little strange to support both macOS and catalyst, but again, possible so why not. 37 | 38 | ### SharedFramework 39 | 40 | This is a shared framework target, also built for all platforms. This is a really useful structure for storing common code between an app and other bundled executables, like a widget extension. I've chosen to use a dynamic library here. This is a trade-off between app launch and app size. A dynamic library will require a little more work at launch time. But in exchange, there's only one copy of the shared code within the app. 41 | 42 | A static library, which is the default for SPM packages, will improve launch times. But, you'll have to pay a size penalty for each executable that needs the shared code. Increased binary sizes can also hurt launch times, so this isn't a trivial thing to compare. 43 | 44 | I wouldn't overthink this too much. Especially since a framework also is a logical organizational structure. 45 | 46 | ### ShareExtension 47 | 48 | This is an extension target. It depends on and links against `SharedFramework`, and is embedded within `MultiPlatformApp`. However! macOS and watchOS do not support share extensions, so the embedding build phase has to be filtered by platform. This is a very powerful Xcode feature, and definitely something worth knowing about when building for multiple platforms. 49 | 50 | Also, note that this target has to customize its bundle identifier because extension bundle ids have to be prefixed with their container app. 51 | 52 | ## Contributing and Collaboration 53 | 54 | I'd love to hear from you! Get in touch via [mastodon](https://mastodon.social/@mattiem), an issue, or a pull request. 55 | 56 | I prefer collaboration, and would love to find ways to work together if you have a similar project. 57 | 58 | I prefer indentation with tabs for improved accessibility. But, I'd rather you use the system you want and make a PR than hesitate because of whitespace. 59 | 60 | By participating in this project you agree to abide by the [Contributor Code of Conduct](CODE_OF_CONDUCT.md). 61 | -------------------------------------------------------------------------------- /ShareExtension/Base.lproj/MainInterface.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 | -------------------------------------------------------------------------------- /ShareExtension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSExtension 6 | 7 | NSExtensionAttributes 8 | 9 | NSExtensionActivationRule 10 | TRUEPREDICATE 11 | 12 | NSExtensionMainStoryboard 13 | MainInterface 14 | NSExtensionPointIdentifier 15 | com.apple.share-services 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /ShareExtension/ShareViewController.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Social 3 | 4 | class ShareViewController: SLComposeServiceViewController { 5 | 6 | override func isContentValid() -> Bool { 7 | // Do validation of contentText and/or NSExtensionContext attachments here 8 | return true 9 | } 10 | 11 | override func didSelectPost() { 12 | // This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments. 13 | 14 | // Inform the host that we're done, so it un-blocks its UI. Note: Alternatively you could call super's -didSelectPost, which will similarly complete the extension context. 15 | self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil) 16 | } 17 | 18 | override func configurationItems() -> [Any]! { 19 | // To add configuration options via table cells at the bottom of the sheet, return an array of SLComposeSheetConfigurationItem here. 20 | return [] 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /SharedFramework/SharedFramework.docc/SharedFramework.md: -------------------------------------------------------------------------------- 1 | # ``SharedFramework`` 2 | 3 | Summary 4 | 5 | ## Overview 6 | 7 | Text 8 | 9 | ## Topics 10 | 11 | ### Group 12 | 13 | - ``Symbol`` -------------------------------------------------------------------------------- /SharedFramework/SharedFramework.h: -------------------------------------------------------------------------------- 1 | // 2 | // SharedFramework.h 3 | // SharedFramework 4 | // 5 | // Created by Matthew Massicotte on 2023-10-07. 6 | // 7 | 8 | #import 9 | 10 | //! Project version number for SharedFramework. 11 | FOUNDATION_EXPORT double SharedFrameworkVersionNumber; 12 | 13 | //! Project version string for SharedFramework. 14 | FOUNDATION_EXPORT const unsigned char SharedFrameworkVersionString[]; 15 | 16 | // In this header, you should import all the public headers of your framework using statements like #import 17 | 18 | 19 | -------------------------------------------------------------------------------- /SharedFrameworkTests/SharedFrameworkTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SharedFrameworkTests.swift 3 | // SharedFrameworkTests 4 | // 5 | // Created by Matthew Massicotte on 2023-10-07. 6 | // 7 | 8 | import XCTest 9 | @testable import SharedFramework 10 | 11 | class SharedFrameworkTests: XCTestCase { 12 | 13 | override func setUpWithError() throws { 14 | // Put setup code here. This method is called before the invocation of each test method in the class. 15 | } 16 | 17 | override func tearDownWithError() throws { 18 | // Put teardown code here. This method is called after the invocation of each test method in the class. 19 | } 20 | 21 | func testExample() throws { 22 | // This is an example of a functional test case. 23 | // Use XCTAssert and related functions to verify your tests produce the correct results. 24 | // Any test you write for XCTest can be annotated as throws and async. 25 | // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error. 26 | // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards. 27 | } 28 | 29 | func testPerformanceExample() throws { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /User.xcconfig.template: -------------------------------------------------------------------------------- 1 | DEVELOPMENT_TEAM = YOUR_TEAM_ID 2 | BUNDLE_ID_PREFIX = com.yourcompany 3 | --------------------------------------------------------------------------------