diff --git a/Examples/Combine using GitHub API/.gitignore b/Examples/Combine using GitHub API/.gitignore deleted file mode 100755 index 704641d..0000000 --- a/Examples/Combine using GitHub API/.gitignore +++ /dev/null @@ -1,21 +0,0 @@ -.DS_Store -*/build/* -*.pbxuser -!default.pbxuser -*.mode1v3 -!default.mode1v3 -*.mode2v3 -!default.mode2v3 -*.perspectivev3 -!default.perspectivev3 -xcuserdata -profile -*.moved-aside -DerivedData -.idea/ -*.hmap -*.xccheckout -*.xcuserstate -xcuserdata/ -*.moved-aside -*.xcuserstate diff --git a/Examples/Combine using GitHub API/LICENSE b/Examples/Combine using GitHub API/LICENSE deleted file mode 100755 index 6af96ad..0000000 --- a/Examples/Combine using GitHub API/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2019 ra1028 - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/Examples/Combine using GitHub API/README.md b/Examples/Combine using GitHub API/README.md deleted file mode 100755 index 5d2c3e3..0000000 --- a/Examples/Combine using GitHub API/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# SwiftUI-Combine-Example -This is an example project of [SwiftUI](https://developer.apple.com/xcode/swiftui) and [Combine](https://developer.apple.com/documentation/combine) using GitHub `GET /search/users` API. - -

- -

- -## :clipboard: Requirements -- Swift5.1 Beta -- Xcode11.0 Beta -- iOS 13.0 Beta - -## :warning: GitHub API Rate Limiting -GitHub search API has a [rate limit rules](https://developer.github.com/v3/search/#rate-limit). -For unauthenticated requests, the rate limit allows you to make up to 10 requests per minute. - -## :books: Credit -- [Official SwiftUI Tutorial](https://developer.apple.com/tutorials/swiftui) -- [Combine Apple Developer Document](https://developer.apple.com/documentation/combine) diff --git a/Examples/Combine using GitHub API/assets/sample.png b/Examples/Combine using GitHub API/assets/sample.png deleted file mode 100755 index 278656c..0000000 Binary files a/Examples/Combine using GitHub API/assets/sample.png and /dev/null differ diff --git a/Examples/Example To-Do App/.gitignore b/Examples/Example To-Do App/.gitignore deleted file mode 100755 index 5518329..0000000 --- a/Examples/Example To-Do App/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -.DS_Store -.bundle - -**/xcuserdata -*.pbxuser -*.mode1v3 - -Pods/ -Carthage/ -vendor/ - -fastlane/report.xml -*.ipa -*.dSYM.zip diff --git a/Examples/Example To-Do App/LICENSE b/Examples/Example To-Do App/LICENSE deleted file mode 100755 index b907ae9..0000000 --- a/Examples/Example To-Do App/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2019 Suyeol Jeon (xoul.kr) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/Examples/Example To-Do App/README.md b/Examples/Example To-Do App/README.md deleted file mode 100755 index 2fb8bf1..0000000 --- a/Examples/Example To-Do App/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# SwiftUITodo - -SwiftUITodo is an example to-do list application using [SwiftUI](https://developer.apple.com/xcode/swiftui/) which is first introduced in WWDC19 keynote. - -![screenshot](https://user-images.githubusercontent.com/931655/58843349-f6dbf400-8626-11e9-8227-fbd369c29515.png) - -## Requirements - -* Xcode 11 Beta -* Swift 5.1 - -## License - -SwiftUITodo is under MIT license. See the [LICENSE](LICENSE) file for more info. diff --git a/Examples/GitHub Search/.gitignore b/Examples/GitHub Search/.gitignore deleted file mode 100755 index 8b7a3dd..0000000 --- a/Examples/GitHub Search/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# Xcode -# -# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore - -.DS_Store - -## Build generated -build/ -DerivedData/ - -## Various settings -*.pbxuser -!default.pbxuser -*.mode1v3 -!default.mode1v3 -*.mode2v3 -!default.mode2v3 -*.perspectivev3 -!default.perspectivev3 -xcuserdata/ - -## Other -*.moved-aside -*.xccheckout -*.xcscmblueprint - -## Obj-C/Swift specific -*.hmap -*.ipa -*.dSYM.zip -*.dSYM - -## Playgrounds -timeline.xctimeline -playground.xcworkspace - -# Swift Package Manager -# -# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. -# Packages/ -# Package.pins -# Package.resolved -.build/ - -# CocoaPods -# -# We recommend against adding the Pods directory to your .gitignore. However -# you should judge for yourself, the pros and cons are mentioned at: -# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control -# -# Pods/ - -# Carthage -# -# Add this line if you want to avoid checking in source code from Carthage dependencies. -# Carthage/Checkouts - -Carthage/Build - -# fastlane -# -# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the -# screenshots whenever they are needed. -# For more information about the recommended setup visit: -# https://docs.fastlane.tools/best-practices/source-control/#source-control - -fastlane/report.xml -fastlane/Preview.html -fastlane/screenshots/**/*.png -fastlane/test_output diff --git a/Examples/GitHub Search/LICENSE b/Examples/GitHub Search/LICENSE deleted file mode 100755 index 4f28152..0000000 --- a/Examples/GitHub Search/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 Taiki Suzuki - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/Examples/GitHub Search/README.md b/Examples/GitHub Search/README.md deleted file mode 100755 index 5e86d09..0000000 --- a/Examples/GitHub Search/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# GitHubSearchWithSwiftUI - -GitHubSearchWithSwiftUI is an example that using [SwiftUI ](https://developer.apple.com/xcode/swiftui/) - - - -## TODO - -- [x] Search with TextField's text -- [x] Reflect API responses to List -- [X] Separate API access from BindableObject -- [X] Use Combine with API access -- [ ] Reflect responses in MainThread via Combine - -## Requirements - -- Xcode 11 Beta -- Swift 5.1 -- iOS 13 Beta - -## References - -- https://developer.apple.com/tutorials/swiftui/tutorials -- https://developer.apple.com/documentation/swiftui -- https://developer.apple.com/documentation/combine -- https://developer.apple.com/design/human-interface-guidelines/sf-symbols/overview/ - -## License - -GitHubSearchWithSwiftUI is under MIT license. See the [LICENSE](./LICENSE) file for more info. diff --git a/Examples/TimeTravel/.gitignore b/Examples/TimeTravel/.gitignore deleted file mode 100755 index 2b5f284..0000000 --- a/Examples/TimeTravel/.gitignore +++ /dev/null @@ -1,82 +0,0 @@ -# Xcode -# -# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore - -## Build generated -build/ -DerivedData/ - -## Various settings -*.pbxuser -!default.pbxuser -*.mode1v3 -!default.mode1v3 -*.mode2v3 -!default.mode2v3 -*.perspectivev3 -!default.perspectivev3 -xcuserdata/ - -## Other -*.moved-aside -*.xccheckout -*.xcscmblueprint - -## Obj-C/Swift specific -*.hmap -*.ipa -*.dSYM.zip -*.dSYM - -## Playgrounds -timeline.xctimeline -playground.xcworkspace - -# Swift Package Manager -# -# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. -# Packages/ -# Package.pins -# Package.resolved -.build/ - -# CocoaPods -# -# We recommend against adding the Pods directory to your .gitignore. However -# you should judge for yourself, the pros and cons are mentioned at: -# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control -# -# Pods/ -# -# Add this line if you want to avoid checking in source code from the Xcode workspace -# *.xcworkspace - -# Carthage -# -# Add this line if you want to avoid checking in source code from Carthage dependencies. -# Carthage/Checkouts - -Carthage/Build - -# Accio dependency management -Dependencies/ -.accio/ - -# fastlane -# -# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the -# screenshots whenever they are needed. -# For more information about the recommended setup visit: -# https://docs.fastlane.tools/best-practices/source-control/#source-control - -fastlane/report.xml -fastlane/Preview.html -fastlane/screenshots/**/*.png -fastlane/test_output - -# Code Injection -# -# After new code Injection tools there's a generated folder /iOSInjectionProject -# https://github.com/johnno1962/injectionforxcode - -iOSInjectionProject/ \ No newline at end of file diff --git a/Examples/iPadOS Scenes/BehindTheScenes.xcodeproj/project.pbxproj b/Examples/iPadOS Scenes/BehindTheScenes.xcodeproj/project.pbxproj new file mode 100755 index 0000000..f3fefa7 --- /dev/null +++ b/Examples/iPadOS Scenes/BehindTheScenes.xcodeproj/project.pbxproj @@ -0,0 +1,339 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + DB30CC3722A67A7800FAF43E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB30CC3622A67A7800FAF43E /* AppDelegate.swift */; }; + DB30CC3922A67A7800FAF43E /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB30CC3822A67A7800FAF43E /* SceneDelegate.swift */; }; + DB30CC3B22A67A7800FAF43E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB30CC3A22A67A7800FAF43E /* ViewController.swift */; }; + DB30CC4022A67A7A00FAF43E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DB30CC3F22A67A7A00FAF43E /* Assets.xcassets */; }; + DB30CC4322A67A7A00FAF43E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DB30CC4122A67A7A00FAF43E /* LaunchScreen.storyboard */; }; + DB30CC6B22A6937800FAF43E /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB30CC6A22A6937800FAF43E /* ContentView.swift */; }; + DB30CC6D22A6953A00FAF43E /* SwiftUISceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB30CC6C22A6953A00FAF43E /* SwiftUISceneDelegate.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + DB30CC3322A67A7800FAF43E /* BehindTheScenes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BehindTheScenes.app; sourceTree = BUILT_PRODUCTS_DIR; }; + DB30CC3622A67A7800FAF43E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + DB30CC3822A67A7800FAF43E /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + DB30CC3A22A67A7800FAF43E /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + DB30CC3F22A67A7A00FAF43E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + DB30CC4222A67A7A00FAF43E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + DB30CC4422A67A7A00FAF43E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + DB30CC6A22A6937800FAF43E /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + DB30CC6C22A6953A00FAF43E /* SwiftUISceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUISceneDelegate.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + DB30CC3022A67A7800FAF43E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + DB30CC2A22A67A7800FAF43E = { + isa = PBXGroup; + children = ( + DB30CC3522A67A7800FAF43E /* BehindTheScenes */, + DB30CC3422A67A7800FAF43E /* Products */, + ); + sourceTree = ""; + }; + DB30CC3422A67A7800FAF43E /* Products */ = { + isa = PBXGroup; + children = ( + DB30CC3322A67A7800FAF43E /* BehindTheScenes.app */, + ); + name = Products; + sourceTree = ""; + }; + DB30CC3522A67A7800FAF43E /* BehindTheScenes */ = { + isa = PBXGroup; + children = ( + DB30CC3622A67A7800FAF43E /* AppDelegate.swift */, + DB30CC3822A67A7800FAF43E /* SceneDelegate.swift */, + DB30CC6C22A6953A00FAF43E /* SwiftUISceneDelegate.swift */, + DB30CC3A22A67A7800FAF43E /* ViewController.swift */, + DB30CC6A22A6937800FAF43E /* ContentView.swift */, + DB30CC3F22A67A7A00FAF43E /* Assets.xcassets */, + DB30CC4122A67A7A00FAF43E /* LaunchScreen.storyboard */, + DB30CC4422A67A7A00FAF43E /* Info.plist */, + ); + path = BehindTheScenes; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + DB30CC3222A67A7800FAF43E /* BehindTheScenes */ = { + isa = PBXNativeTarget; + buildConfigurationList = DB30CC4722A67A7A00FAF43E /* Build configuration list for PBXNativeTarget "BehindTheScenes" */; + buildPhases = ( + DB30CC2F22A67A7800FAF43E /* Sources */, + DB30CC3022A67A7800FAF43E /* Frameworks */, + DB30CC3122A67A7800FAF43E /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = BehindTheScenes; + productName = BehindTheScenes; + productReference = DB30CC3322A67A7800FAF43E /* BehindTheScenes.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + DB30CC2B22A67A7800FAF43E /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = "Two Lives Left"; + TargetAttributes = { + DB30CC3222A67A7800FAF43E = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = DB30CC2E22A67A7800FAF43E /* Build configuration list for PBXProject "BehindTheScenes" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = DB30CC2A22A67A7800FAF43E; + productRefGroup = DB30CC3422A67A7800FAF43E /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + DB30CC3222A67A7800FAF43E /* BehindTheScenes */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + DB30CC3122A67A7800FAF43E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DB30CC4322A67A7A00FAF43E /* LaunchScreen.storyboard in Resources */, + DB30CC4022A67A7A00FAF43E /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + DB30CC2F22A67A7800FAF43E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DB30CC3B22A67A7800FAF43E /* ViewController.swift in Sources */, + DB30CC6D22A6953A00FAF43E /* SwiftUISceneDelegate.swift in Sources */, + DB30CC3722A67A7800FAF43E /* AppDelegate.swift in Sources */, + DB30CC3922A67A7800FAF43E /* SceneDelegate.swift in Sources */, + DB30CC6B22A6937800FAF43E /* ContentView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + DB30CC4122A67A7A00FAF43E /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + DB30CC4222A67A7A00FAF43E /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + DB30CC4522A67A7A00FAF43E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + DB30CC4622A67A7A00FAF43E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + DB30CC4822A67A7A00FAF43E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = G5S3RZ43N7; + INFOPLIST_FILE = BehindTheScenes/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.twolivesleft.BehindTheScenes; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + DB30CC4922A67A7A00FAF43E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = G5S3RZ43N7; + INFOPLIST_FILE = BehindTheScenes/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.twolivesleft.BehindTheScenes; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + DB30CC2E22A67A7800FAF43E /* Build configuration list for PBXProject "BehindTheScenes" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DB30CC4522A67A7A00FAF43E /* Debug */, + DB30CC4622A67A7A00FAF43E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DB30CC4722A67A7A00FAF43E /* Build configuration list for PBXNativeTarget "BehindTheScenes" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DB30CC4822A67A7A00FAF43E /* Debug */, + DB30CC4922A67A7A00FAF43E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = DB30CC2B22A67A7800FAF43E /* Project object */; +} diff --git a/Examples/iPadOS Scenes/BehindTheScenes/AppDelegate.swift b/Examples/iPadOS Scenes/BehindTheScenes/AppDelegate.swift new file mode 100755 index 0000000..7c4c79f --- /dev/null +++ b/Examples/iPadOS Scenes/BehindTheScenes/AppDelegate.swift @@ -0,0 +1,62 @@ +// +// AppDelegate.swift +// BehindTheScenes +// +// Created by Simeon Saint-Saens on 4/6/19. +// Copyright © 2019 Two Lives Left. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var sceneCount = 0 + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + sceneCount += 1 + + connectingSceneSession.userInfo = ["SceneCount" : sceneCount ] + + var sceneDelegateClass: AnyClass = SceneDelegate.self + + if let activity = options.userActivities.first, + let sceneType = SceneType(rawValue: activity.activityType) { + + switch sceneType { + case .uikitScene: + sceneDelegateClass = SceneDelegate.self + case .swiftuiScene: + sceneDelegateClass = SwiftUISceneDelegate.self + } + } + + let config = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role) + config.sceneClass = UIWindowScene.self + config.delegateClass = sceneDelegateClass + + return config + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/Examples/iPadOS Scenes/BehindTheScenes/Assets.xcassets/AppIcon.appiconset/Contents.json b/Examples/iPadOS Scenes/BehindTheScenes/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100755 index 0000000..d8db8d6 --- /dev/null +++ b/Examples/iPadOS Scenes/BehindTheScenes/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Examples/iPadOS Scenes/BehindTheScenes/Assets.xcassets/Contents.json b/Examples/iPadOS Scenes/BehindTheScenes/Assets.xcassets/Contents.json new file mode 100755 index 0000000..da4a164 --- /dev/null +++ b/Examples/iPadOS Scenes/BehindTheScenes/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Examples/iPadOS Scenes/BehindTheScenes/Base.lproj/LaunchScreen.storyboard b/Examples/iPadOS Scenes/BehindTheScenes/Base.lproj/LaunchScreen.storyboard new file mode 100755 index 0000000..865e932 --- /dev/null +++ b/Examples/iPadOS Scenes/BehindTheScenes/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Examples/iPadOS Scenes/BehindTheScenes/ContentView.swift b/Examples/iPadOS Scenes/BehindTheScenes/ContentView.swift new file mode 100755 index 0000000..6da7761 --- /dev/null +++ b/Examples/iPadOS Scenes/BehindTheScenes/ContentView.swift @@ -0,0 +1,21 @@ +// +// ContentView.swift +// BehindTheScenes +// +// Created by Simeon Saint-Saens on 4/6/19. +// Copyright © 2019 Two Lives Left. All rights reserved. +// + +import SwiftUI + +struct ContentView : View { + let count: Int + + var body: some View { + VStack { + Text("Scene \(count)") + Text("This is a SwiftUI View 🚀") + } + } +} + diff --git a/Examples/iPadOS Scenes/BehindTheScenes/Info.plist b/Examples/iPadOS Scenes/BehindTheScenes/Info.plist new file mode 100755 index 0000000..73e8d2e --- /dev/null +++ b/Examples/iPadOS Scenes/BehindTheScenes/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Examples/iPadOS Scenes/BehindTheScenes/SceneDelegate.swift b/Examples/iPadOS Scenes/BehindTheScenes/SceneDelegate.swift new file mode 100755 index 0000000..3148a60 --- /dev/null +++ b/Examples/iPadOS Scenes/BehindTheScenes/SceneDelegate.swift @@ -0,0 +1,64 @@ +// +// SceneDelegate.swift +// BehindTheScenes +// +// Created by Simeon Saint-Saens on 4/6/19. +// Copyright © 2019 Two Lives Left. All rights reserved. +// + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let windowScene = (scene as? UIWindowScene) else { return } + + let count = session.userInfo?["SceneCount"] as? Int ?? 0 + + window = UIWindow(windowScene: windowScene) + window?.rootViewController = ViewController(count: count) + window?.makeKeyAndVisible() + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { + print("Continuing \(userActivity.userInfo?["count"])") + } + + func scene(_ scene: UIScene, didUpdate userActivity: NSUserActivity) { + print("Updating user activity") + } +} + diff --git a/Examples/iPadOS Scenes/BehindTheScenes/SwiftUISceneDelegate.swift b/Examples/iPadOS Scenes/BehindTheScenes/SwiftUISceneDelegate.swift new file mode 100755 index 0000000..dce55fc --- /dev/null +++ b/Examples/iPadOS Scenes/BehindTheScenes/SwiftUISceneDelegate.swift @@ -0,0 +1,27 @@ +// +// SwiftUISceneDelegate.swift +// BehindTheScenes +// +// Created by Simeon Saint-Saens on 4/6/19. +// Copyright © 2019 Two Lives Left. All rights reserved. +// + +import UIKit +import SwiftUI + +class SwiftUISceneDelegate: UIResponder, UIWindowSceneDelegate { + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let windowScene = (scene as? UIWindowScene) else { return } + + let count = session.userInfo?["SceneCount"] as? Int ?? 0 + + window = UIWindow(windowScene: windowScene) + window?.rootViewController = UIHostingController(rootView: ContentView(count: count)) + window?.makeKeyAndVisible() + } +} diff --git a/Examples/iPadOS Scenes/BehindTheScenes/ViewController.swift b/Examples/iPadOS Scenes/BehindTheScenes/ViewController.swift new file mode 100755 index 0000000..1ac2439 --- /dev/null +++ b/Examples/iPadOS Scenes/BehindTheScenes/ViewController.swift @@ -0,0 +1,86 @@ +// +// ViewController.swift +// BehindTheScenes +// +// Created by Simeon Saint-Saens on 4/6/19. +// Copyright © 2019 Two Lives Left. All rights reserved. +// + +import UIKit + +enum SceneType: String { + case uikitScene + case swiftuiScene +} + +class ViewController: UIViewController { + + let count: Int + + init(count: Int) { + self.count = count + + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("NO THANKS XCODE") + } + + override func viewDidLoad() { + print("Loading view controller") + + super.viewDidLoad() + + view.backgroundColor = UIColor(white: 0.9, alpha: 1) + + let button = UIButton(type: .system) + button.addTarget(self, action: #selector(openScene(_:)), for: .touchUpInside) + button.setTitle("Request New Scene", for: .normal) + + view.addSubview(button) + button.translatesAutoresizingMaskIntoConstraints = false + + button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true + button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true + + let swiftUIbutton = UIButton(type: .system) + swiftUIbutton.addTarget(self, action: #selector(openSwiftUIScene(_:)), for: .touchUpInside) + swiftUIbutton.setTitle("Request Swift UI Test Scene", for: .normal) + + view.addSubview(swiftUIbutton) + swiftUIbutton.translatesAutoresizingMaskIntoConstraints = false + + swiftUIbutton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true + swiftUIbutton.topAnchor.constraint(equalTo: button.bottomAnchor, constant: 16).isActive = true + + let countLabel = UILabel() + countLabel.text = "\(count)" + countLabel.textAlignment = .center + countLabel.textColor = .black + countLabel.font = UIFont.systemFont(ofSize: 144, weight: .heavy) + + view.addSubview(countLabel) + countLabel.translatesAutoresizingMaskIntoConstraints = false + + countLabel.bottomAnchor.constraint(equalTo: button.topAnchor, constant: -30).isActive = true + countLabel.centerXAnchor.constraint(equalTo: button.centerXAnchor).isActive = true + } + + @objc private func openScene(_ sender: Any) { + let activity = NSUserActivity(activityType: SceneType.uikitScene.rawValue) + + UIApplication.shared.requestSceneSessionActivation(nil, userActivity: activity, options: nil, errorHandler: { + print($0) + }) + } + + @objc private func openSwiftUIScene(_ sender: Any) { + let activity = NSUserActivity(activityType: SceneType.swiftuiScene.rawValue) + + UIApplication.shared.requestSceneSessionActivation(nil, userActivity: activity, options: nil, errorHandler: { + print($0) + }) + } +} + diff --git a/README.md b/README.md index 175284e..33fb7ed 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ If you have project, make a pull request. - [Composing Complex Interfaces](#composing-complex-interfaces) - [Working With UIControls](#working-with-uicontrols) - [Example To-Do App](#example-to-do-app) +- [iPadOS Scenes](ipados-scenes) - [Combine using GitHub API](#combine-using-github-api) - [Interfacing With UIKit](#interfacing-with-uikit) - [GitHub Search](#github-search) @@ -46,6 +47,10 @@ If you have project, make a pull request. +#### iPadOS Scenes + + + #### Combine using GitHub API