diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo.xcodeproj/project.pbxproj b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo.xcodeproj/project.pbxproj deleted file mode 100644 index 7b04e5bebc..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo.xcodeproj/project.pbxproj +++ /dev/null @@ -1,611 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 54; - objects = { - -/* Begin PBXBuildFile section */ - 56026CAC25B8A7EF00D1DF3F /* PlayerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56026CAA25B8A7EF00D1DF3F /* PlayerTests.swift */; }; - 56026CAD25B8A7EF00D1DF3F /* AppDatabaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56026CAB25B8A7EF00D1DF3F /* AppDatabaseTests.swift */; }; - 56519DCA274FC8E900ED16D8 /* GRDBQuery in Frameworks */ = {isa = PBXBuildFile; productRef = 56519DC9274FC8E900ED16D8 /* GRDBQuery */; }; - 5671723A261B23C800423B6F /* PlayerList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56717239261B23C800423B6F /* PlayerList.swift */; }; - 56717252261B334D00423B6F /* PlayerRequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56717251261B334D00423B6F /* PlayerRequestTests.swift */; }; - 567C3E1A2520B6DE0011F6E9 /* GRDBAsyncDemoApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567C3E192520B6DE0011F6E9 /* GRDBAsyncDemoApp.swift */; }; - 567C3E1E2520B6DF0011F6E9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 567C3E1D2520B6DF0011F6E9 /* Assets.xcassets */; }; - 567C3E212520B6DF0011F6E9 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 567C3E202520B6DF0011F6E9 /* Preview Assets.xcassets */; }; - 567C3E5D2520B75C0011F6E9 /* Player.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567C3E532520B75C0011F6E9 /* Player.swift */; }; - 567C3E5E2520B75C0011F6E9 /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567C3E542520B75C0011F6E9 /* Persistence.swift */; }; - 567C3E612520B75D0011F6E9 /* PlayerFormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567C3E592520B75C0011F6E9 /* PlayerFormView.swift */; }; - 567C3E622520B75D0011F6E9 /* AppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567C3E5A2520B75C0011F6E9 /* AppView.swift */; }; - 567C3E632520B75D0011F6E9 /* PlayerCreationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567C3E5B2520B75C0011F6E9 /* PlayerCreationView.swift */; }; - 567C3E642520B75D0011F6E9 /* PlayerEditionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567C3E5C2520B75C0011F6E9 /* PlayerEditionView.swift */; }; - 567C3E662520B7880011F6E9 /* AppDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567C3E652520B7880011F6E9 /* AppDatabase.swift */; }; - 567C3E792520BB650011F6E9 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 567C3E752520BB650011F6E9 /* Localizable.stringsdict */; }; - 567C3E7A2520BB650011F6E9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 567C3E772520BB650011F6E9 /* LaunchScreen.storyboard */; }; - 56B6D1092619EC1B003CC455 /* PlayerRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B6D1082619EC1B003CC455 /* PlayerRequest.swift */; }; - 56F8A13527359A5A0011ACBE /* GRDB in Frameworks */ = {isa = PBXBuildFile; productRef = 56F8A13427359A5A0011ACBE /* GRDB */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 56026C9D25B8A7D000D1DF3F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 567C3E0E2520B6DE0011F6E9 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 567C3E152520B6DE0011F6E9; - remoteInfo = GRDBAsyncDemo; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 567C3E502520B70E0011F6E9 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 56026C9825B8A7D000D1DF3F /* GRDBAsyncDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GRDBAsyncDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 56026C9C25B8A7D000D1DF3F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 56026CAA25B8A7EF00D1DF3F /* PlayerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlayerTests.swift; sourceTree = ""; }; - 56026CAB25B8A7EF00D1DF3F /* AppDatabaseTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDatabaseTests.swift; sourceTree = ""; }; - 56717239261B23C800423B6F /* PlayerList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerList.swift; sourceTree = ""; }; - 56717251261B334D00423B6F /* PlayerRequestTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerRequestTests.swift; sourceTree = ""; }; - 567C3E162520B6DE0011F6E9 /* GRDBAsyncDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GRDBAsyncDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 567C3E192520B6DE0011F6E9 /* GRDBAsyncDemoApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GRDBAsyncDemoApp.swift; sourceTree = ""; }; - 567C3E1D2520B6DF0011F6E9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 567C3E202520B6DF0011F6E9 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; - 567C3E222520B6DF0011F6E9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 567C3E532520B75C0011F6E9 /* Player.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Player.swift; sourceTree = ""; }; - 567C3E542520B75C0011F6E9 /* Persistence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = ""; }; - 567C3E592520B75C0011F6E9 /* PlayerFormView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlayerFormView.swift; sourceTree = ""; }; - 567C3E5A2520B75C0011F6E9 /* AppView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppView.swift; sourceTree = ""; }; - 567C3E5B2520B75C0011F6E9 /* PlayerCreationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlayerCreationView.swift; sourceTree = ""; }; - 567C3E5C2520B75C0011F6E9 /* PlayerEditionView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlayerEditionView.swift; sourceTree = ""; }; - 567C3E652520B7880011F6E9 /* AppDatabase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDatabase.swift; sourceTree = ""; }; - 567C3E762520BB650011F6E9 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = ""; }; - 567C3E782520BB650011F6E9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 56B6D1082619EC1B003CC455 /* PlayerRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerRequest.swift; sourceTree = ""; }; - 56F8A12E27359A350011ACBE /* GRDB.swift */ = {isa = PBXFileReference; lastKnownFileType = folder; name = GRDB.swift; path = ../../..; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 56026C9525B8A7D000D1DF3F /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 567C3E132520B6DE0011F6E9 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 56519DCA274FC8E900ED16D8 /* GRDBQuery in Frameworks */, - 56F8A13527359A5A0011ACBE /* GRDB in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 56026C9925B8A7D000D1DF3F /* GRDBAsyncDemoTests */ = { - isa = PBXGroup; - children = ( - 56026C9C25B8A7D000D1DF3F /* Info.plist */, - 56026CAB25B8A7EF00D1DF3F /* AppDatabaseTests.swift */, - 56717251261B334D00423B6F /* PlayerRequestTests.swift */, - 56026CAA25B8A7EF00D1DF3F /* PlayerTests.swift */, - ); - path = GRDBAsyncDemoTests; - sourceTree = ""; - }; - 56185BC125B8047D00B9C30F /* Resources */ = { - isa = PBXGroup; - children = ( - 567C3E1D2520B6DF0011F6E9 /* Assets.xcassets */, - 567C3E772520BB650011F6E9 /* LaunchScreen.storyboard */, - 567C3E752520BB650011F6E9 /* Localizable.stringsdict */, - ); - path = Resources; - sourceTree = ""; - }; - 567C3E0D2520B6DE0011F6E9 = { - isa = PBXGroup; - children = ( - 567C3E182520B6DE0011F6E9 /* GRDBAsyncDemo */, - 56026C9925B8A7D000D1DF3F /* GRDBAsyncDemoTests */, - 567C3E172520B6DE0011F6E9 /* Products */, - 567C3E4D2520B70E0011F6E9 /* Frameworks */, - 56F8A12E27359A350011ACBE /* GRDB.swift */, - ); - sourceTree = ""; - }; - 567C3E172520B6DE0011F6E9 /* Products */ = { - isa = PBXGroup; - children = ( - 567C3E162520B6DE0011F6E9 /* GRDBAsyncDemo.app */, - 56026C9825B8A7D000D1DF3F /* GRDBAsyncDemoTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 567C3E182520B6DE0011F6E9 /* GRDBAsyncDemo */ = { - isa = PBXGroup; - children = ( - 567C3E222520B6DF0011F6E9 /* Info.plist */, - 567C3E652520B7880011F6E9 /* AppDatabase.swift */, - 567C3E192520B6DE0011F6E9 /* GRDBAsyncDemoApp.swift */, - 567C3E542520B75C0011F6E9 /* Persistence.swift */, - 567C3E532520B75C0011F6E9 /* Player.swift */, - 56B6D1082619EC1B003CC455 /* PlayerRequest.swift */, - 567C3E1F2520B6DF0011F6E9 /* Preview Content */, - 56185BC125B8047D00B9C30F /* Resources */, - 567C3E582520B75C0011F6E9 /* Views */, - ); - path = GRDBAsyncDemo; - sourceTree = ""; - }; - 567C3E1F2520B6DF0011F6E9 /* Preview Content */ = { - isa = PBXGroup; - children = ( - 567C3E202520B6DF0011F6E9 /* Preview Assets.xcassets */, - ); - path = "Preview Content"; - sourceTree = ""; - }; - 567C3E4D2520B70E0011F6E9 /* Frameworks */ = { - isa = PBXGroup; - children = ( - ); - name = Frameworks; - sourceTree = ""; - }; - 567C3E582520B75C0011F6E9 /* Views */ = { - isa = PBXGroup; - children = ( - 567C3E5A2520B75C0011F6E9 /* AppView.swift */, - 567C3E5B2520B75C0011F6E9 /* PlayerCreationView.swift */, - 567C3E5C2520B75C0011F6E9 /* PlayerEditionView.swift */, - 567C3E592520B75C0011F6E9 /* PlayerFormView.swift */, - 56717239261B23C800423B6F /* PlayerList.swift */, - ); - path = Views; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 56026C9725B8A7D000D1DF3F /* GRDBAsyncDemoTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 56026CA825B8A7D000D1DF3F /* Build configuration list for PBXNativeTarget "GRDBAsyncDemoTests" */; - buildPhases = ( - 56026C9425B8A7D000D1DF3F /* Sources */, - 56026C9525B8A7D000D1DF3F /* Frameworks */, - 56026C9625B8A7D000D1DF3F /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 56026C9E25B8A7D000D1DF3F /* PBXTargetDependency */, - ); - name = GRDBAsyncDemoTests; - productName = GRDBAsyncDemoTests; - productReference = 56026C9825B8A7D000D1DF3F /* GRDBAsyncDemoTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 567C3E152520B6DE0011F6E9 /* GRDBAsyncDemo */ = { - isa = PBXNativeTarget; - buildConfigurationList = 567C3E252520B6DF0011F6E9 /* Build configuration list for PBXNativeTarget "GRDBAsyncDemo" */; - buildPhases = ( - 567C3E122520B6DE0011F6E9 /* Sources */, - 567C3E132520B6DE0011F6E9 /* Frameworks */, - 567C3E142520B6DE0011F6E9 /* Resources */, - 567C3E502520B70E0011F6E9 /* Embed Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 56F8A13127359A540011ACBE /* PBXTargetDependency */, - ); - name = GRDBAsyncDemo; - packageProductDependencies = ( - 56F8A13427359A5A0011ACBE /* GRDB */, - 56519DC9274FC8E900ED16D8 /* GRDBQuery */, - ); - productName = GRBCombineDemo; - productReference = 567C3E162520B6DE0011F6E9 /* GRDBAsyncDemo.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 567C3E0E2520B6DE0011F6E9 /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = YES; - LastSwiftUpdateCheck = 1250; - LastUpgradeCheck = 1200; - TargetAttributes = { - 56026C9725B8A7D000D1DF3F = { - CreatedOnToolsVersion = 12.3; - TestTargetID = 567C3E152520B6DE0011F6E9; - }; - 567C3E152520B6DE0011F6E9 = { - CreatedOnToolsVersion = 12.0; - }; - }; - }; - buildConfigurationList = 567C3E112520B6DE0011F6E9 /* Build configuration list for PBXProject "GRDBAsyncDemo" */; - compatibilityVersion = "Xcode 12.0"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 567C3E0D2520B6DE0011F6E9; - packageReferences = ( - 56519DC8274FC8E900ED16D8 /* XCRemoteSwiftPackageReference "GRDBQuery" */, - ); - productRefGroup = 567C3E172520B6DE0011F6E9 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 567C3E152520B6DE0011F6E9 /* GRDBAsyncDemo */, - 56026C9725B8A7D000D1DF3F /* GRDBAsyncDemoTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 56026C9625B8A7D000D1DF3F /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 567C3E142520B6DE0011F6E9 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 567C3E212520B6DF0011F6E9 /* Preview Assets.xcassets in Resources */, - 567C3E7A2520BB650011F6E9 /* LaunchScreen.storyboard in Resources */, - 567C3E1E2520B6DF0011F6E9 /* Assets.xcassets in Resources */, - 567C3E792520BB650011F6E9 /* Localizable.stringsdict in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 56026C9425B8A7D000D1DF3F /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 56026CAC25B8A7EF00D1DF3F /* PlayerTests.swift in Sources */, - 56026CAD25B8A7EF00D1DF3F /* AppDatabaseTests.swift in Sources */, - 56717252261B334D00423B6F /* PlayerRequestTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 567C3E122520B6DE0011F6E9 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 567C3E5E2520B75C0011F6E9 /* Persistence.swift in Sources */, - 567C3E5D2520B75C0011F6E9 /* Player.swift in Sources */, - 56B6D1092619EC1B003CC455 /* PlayerRequest.swift in Sources */, - 5671723A261B23C800423B6F /* PlayerList.swift in Sources */, - 567C3E612520B75D0011F6E9 /* PlayerFormView.swift in Sources */, - 567C3E632520B75D0011F6E9 /* PlayerCreationView.swift in Sources */, - 567C3E662520B7880011F6E9 /* AppDatabase.swift in Sources */, - 567C3E622520B75D0011F6E9 /* AppView.swift in Sources */, - 567C3E642520B75D0011F6E9 /* PlayerEditionView.swift in Sources */, - 567C3E1A2520B6DE0011F6E9 /* GRDBAsyncDemoApp.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 56026C9E25B8A7D000D1DF3F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 567C3E152520B6DE0011F6E9 /* GRDBAsyncDemo */; - targetProxy = 56026C9D25B8A7D000D1DF3F /* PBXContainerItemProxy */; - }; - 56F8A13127359A540011ACBE /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = 56F8A13027359A540011ACBE /* GRDB */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 567C3E752520BB650011F6E9 /* Localizable.stringsdict */ = { - isa = PBXVariantGroup; - children = ( - 567C3E762520BB650011F6E9 /* en */, - ); - name = Localizable.stringsdict; - sourceTree = ""; - }; - 567C3E772520BB650011F6E9 /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 567C3E782520BB650011F6E9 /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 56026C9F25B8A7D000D1DF3F /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - INFOPLIST_FILE = GRDBAsyncDemoTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 17.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.github.groue.GRDBAsyncDemoTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GRDBAsyncDemo.app/GRDBAsyncDemo"; - }; - name = Debug; - }; - 56026CA025B8A7D000D1DF3F /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - INFOPLIST_FILE = GRDBAsyncDemoTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 17.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.github.groue.GRDBAsyncDemoTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GRDBAsyncDemo.app/GRDBAsyncDemo"; - }; - name = Release; - }; - 567C3E232520B6DF0011F6E9 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.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; - }; - 567C3E242520B6DF0011F6E9 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.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; - }; - 567C3E262520B6DF0011F6E9 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_ASSET_PATHS = "\"GRDBAsyncDemo/Preview Content\""; - DEVELOPMENT_TEAM = ""; - ENABLE_PREVIEWS = YES; - INFOPLIST_FILE = GRDBAsyncDemo/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 17.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.github.groue.GRDBAsyncDemo; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 1; - }; - name = Debug; - }; - 567C3E272520B6DF0011F6E9 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_ASSET_PATHS = "\"GRDBAsyncDemo/Preview Content\""; - DEVELOPMENT_TEAM = ""; - ENABLE_PREVIEWS = YES; - INFOPLIST_FILE = GRDBAsyncDemo/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 17.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.github.groue.GRDBAsyncDemo; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 1; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 56026CA825B8A7D000D1DF3F /* Build configuration list for PBXNativeTarget "GRDBAsyncDemoTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 56026C9F25B8A7D000D1DF3F /* Debug */, - 56026CA025B8A7D000D1DF3F /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 567C3E112520B6DE0011F6E9 /* Build configuration list for PBXProject "GRDBAsyncDemo" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 567C3E232520B6DF0011F6E9 /* Debug */, - 567C3E242520B6DF0011F6E9 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 567C3E252520B6DF0011F6E9 /* Build configuration list for PBXNativeTarget "GRDBAsyncDemo" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 567C3E262520B6DF0011F6E9 /* Debug */, - 567C3E272520B6DF0011F6E9 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - -/* Begin XCRemoteSwiftPackageReference section */ - 56519DC8274FC8E900ED16D8 /* XCRemoteSwiftPackageReference "GRDBQuery" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/groue/GRDBQuery"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 0.6.0; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 56519DC9274FC8E900ED16D8 /* GRDBQuery */ = { - isa = XCSwiftPackageProductDependency; - package = 56519DC8274FC8E900ED16D8 /* XCRemoteSwiftPackageReference "GRDBQuery" */; - productName = GRDBQuery; - }; - 56F8A13027359A540011ACBE /* GRDB */ = { - isa = XCSwiftPackageProductDependency; - productName = GRDB; - }; - 56F8A13427359A5A0011ACBE /* GRDB */ = { - isa = XCSwiftPackageProductDependency; - productName = GRDB; - }; -/* End XCSwiftPackageProductDependency section */ - }; - rootObject = 567C3E0E2520B6DE0011F6E9 /* Project object */; -} diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003d..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved deleted file mode 100644 index 216295601d..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ /dev/null @@ -1,14 +0,0 @@ -{ - "pins" : [ - { - "identity" : "grdbquery", - "kind" : "remoteSourceControl", - "location" : "https://github.com/groue/GRDBQuery", - "state" : { - "revision" : "a6c46dd38ecf11a5c37732870dc03a384d582fba", - "version" : "0.9.0" - } - } - ], - "version" : 2 -} diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo.xcodeproj/xcshareddata/xcschemes/GRDBAsyncDemo.xcscheme b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo.xcodeproj/xcshareddata/xcschemes/GRDBAsyncDemo.xcscheme deleted file mode 100644 index aeb65e487a..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo.xcodeproj/xcshareddata/xcschemes/GRDBAsyncDemo.xcscheme +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/AppDatabase.swift b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/AppDatabase.swift deleted file mode 100644 index e19cc7af7a..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/AppDatabase.swift +++ /dev/null @@ -1,235 +0,0 @@ -import Foundation -import GRDB -import os.log - -/// A database of players. -/// -/// You create an `AppDatabase` with a connection to an SQLite database -/// (see ). -/// -/// Create those connections with a configuration returned from -/// `AppDatabase/makeConfiguration(_:)`. -/// -/// For example: -/// -/// ```swift -/// // Create an in-memory AppDatabase -/// let config = AppDatabase.makeConfiguration() -/// let dbQueue = try DatabaseQueue(configuration: config) -/// let appDatabase = try AppDatabase(dbQueue) -/// ``` -struct AppDatabase { - /// Creates an `AppDatabase`, and makes sure the database schema - /// is ready. - /// - /// - important: Create the `DatabaseWriter` with a configuration - /// returned by ``makeConfiguration(_:)``. - init(_ dbWriter: any DatabaseWriter) throws { - self.dbWriter = dbWriter - try migrator.migrate(dbWriter) - } - - /// Provides access to the database. - /// - /// Application can use a `DatabasePool`, while SwiftUI previews and tests - /// can use a fast in-memory `DatabaseQueue`. - /// - /// See - private let dbWriter: any DatabaseWriter -} - -// MARK: - Database Configuration - -extension AppDatabase { - private static let sqlLogger = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "SQL") - - /// Returns a database configuration suited for `PlayerRepository`. - /// - /// SQL statements are logged if the `SQL_TRACE` environment variable - /// is set. - /// - /// - parameter base: A base configuration. - public static func makeConfiguration(_ base: Configuration = Configuration()) -> Configuration { - var config = base - - // An opportunity to add required custom SQL functions or - // collations, if needed: - // config.prepareDatabase { db in - // db.add(function: ...) - // } - - // Log SQL statements if the `SQL_TRACE` environment variable is set. - // See - if ProcessInfo.processInfo.environment["SQL_TRACE"] != nil { - config.prepareDatabase { db in - db.trace { - // It's ok to log statements publicly. Sensitive - // information (statement arguments) are not logged - // unless config.publicStatementArguments is set - // (see below). - os_log("%{public}@", log: sqlLogger, type: .debug, String(describing: $0)) - } - } - } - -#if DEBUG - // Protect sensitive information by enabling verbose debugging in - // DEBUG builds only. - // See - config.publicStatementArguments = true -#endif - - return config - } -} - -// MARK: - Database Migrations - -extension AppDatabase { - /// The DatabaseMigrator that defines the database schema. - /// - /// See - private var migrator: DatabaseMigrator { - var migrator = DatabaseMigrator() - -#if DEBUG - // Speed up development by nuking the database when migrations change - // See - migrator.eraseDatabaseOnSchemaChange = true -#endif - - migrator.registerMigration("createPlayer") { db in - // Create a table - // See - try db.create(table: "player") { t in - t.autoIncrementedPrimaryKey("id") - t.column("name", .text).notNull() - t.column("score", .integer).notNull() - } - } - - // Migrations for future application versions will be inserted here: - // migrator.registerMigration(...) { db in - // ... - // } - - return migrator - } -} - -// MARK: - Database Access: Writes -// The write methods execute invariant-preserving database transactions. - -extension AppDatabase { - /// A validation error that prevents some players from being saved into - /// the database. - enum ValidationError: LocalizedError { - case missingName - - var errorDescription: String? { - switch self { - case .missingName: - return "Please provide a name" - } - } - } - - /// Saves (inserts or updates) a player. When the method returns, the - /// player is present in the database, and its id is not nil. - func savePlayer(_ player: inout Player) async throws { - if player.name.isEmpty { - throw ValidationError.missingName - } - player = try await dbWriter.write { [player] db in - try player.saved(db) - } - } - - /// Delete the specified players - func deletePlayers(ids: [Int64]) async throws { - try await dbWriter.write { db in - _ = try Player.deleteAll(db, ids: ids) - } - } - - /// Delete all players - func deleteAllPlayers() async throws { - try await dbWriter.write { db in - _ = try Player.deleteAll(db) - } - } - - /// Refresh all players (by performing some random changes, for demo purpose). - func refreshPlayers() async throws { - try await dbWriter.write { db in - if try Player.all().isEmpty(db) { - // When database is empty, insert new random players - try createRandomPlayers(db) - } else { - // Insert a player - if Bool.random() { - _ = try Player.makeRandom().inserted(db) // insert but ignore inserted id - } - - // Delete a random player - if Bool.random() { - try Player.order(sql: "RANDOM()").limit(1).deleteAll(db) - } - - // Update some players - for var player in try Player.fetchAll(db) where Bool.random() { - try player.updateChanges(db) { - $0.score = Player.randomScore() - } - } - } - } - } - - /// Create random players if the database is empty. - func createRandomPlayersIfEmpty() throws { - try dbWriter.write { db in - if try Player.all().isEmpty(db) { - try createRandomPlayers(db) - } - } - } - - private static let uiTestPlayers = [ - Player(id: nil, name: "Arthur", score: 5), - Player(id: nil, name: "Barbara", score: 6), - Player(id: nil, name: "Craig", score: 8), - Player(id: nil, name: "David", score: 4), - Player(id: nil, name: "Elena", score: 1), - Player(id: nil, name: "Frederik", score: 2), - Player(id: nil, name: "Gilbert", score: 7), - Player(id: nil, name: "Henriette", score: 3)] - - func createPlayersForUITests() throws { - try dbWriter.write { db in - try AppDatabase.uiTestPlayers.forEach { player in - _ = try player.inserted(db) // insert but ignore inserted id - } - } - } - - /// Support for `createRandomPlayersIfEmpty()` and `refreshPlayers()`. - private func createRandomPlayers(_ db: Database) throws { - for _ in 0..<8 { - _ = try Player.makeRandom().inserted(db) // insert but ignore inserted id - } - } -} - -// MARK: - Database Access: Reads - -// This demo app does not provide any specific reading method, and instead -// gives an unrestricted read-only access to the rest of the application. -// In your app, you are free to choose another path, and define focused -// reading methods. -extension AppDatabase { - /// Provides a read-only access to the database - var reader: DatabaseReader { - dbWriter - } -} diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/GRDBAsyncDemoApp.swift b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/GRDBAsyncDemoApp.swift deleted file mode 100644 index 748b10a900..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/GRDBAsyncDemoApp.swift +++ /dev/null @@ -1,32 +0,0 @@ -import GRDBQuery -import SwiftUI - -@main -struct GRDBAsyncDemoApp: App { - var body: some Scene { - WindowGroup { - AppView().appDatabase(.shared) - } - } -} - -// MARK: - Give SwiftUI access to the database - -private struct AppDatabaseKey: EnvironmentKey { - static var defaultValue: AppDatabase { .empty() } -} - -extension EnvironmentValues { - var appDatabase: AppDatabase { - get { self[AppDatabaseKey.self] } - set { self[AppDatabaseKey.self] = newValue } - } -} - -extension View { - func appDatabase(_ appDatabase: AppDatabase) -> some View { - self - .environment(\.appDatabase, appDatabase) - .databaseContext(.readOnly { appDatabase.reader }) - } -} diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Info.plist b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Info.plist deleted file mode 100644 index 4754bb8682..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Info.plist +++ /dev/null @@ -1,50 +0,0 @@ - - - - - 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 - - - UIApplicationSupportsIndirectInputEvents - - UILaunchScreen - - UILaunchStoryboardName - LaunchScreen - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Persistence.swift b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Persistence.swift deleted file mode 100644 index 05b0115789..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Persistence.swift +++ /dev/null @@ -1,77 +0,0 @@ -import Foundation -import GRDB - -extension AppDatabase { - /// The database for the application - static let shared = makeShared() - - private static func makeShared() -> AppDatabase { - do { - // Apply recommendations from - // - // - // Create the "Application Support/Database" directory if needed - let fileManager = FileManager.default - let appSupportURL = try fileManager.url( - for: .applicationSupportDirectory, in: .userDomainMask, - appropriateFor: nil, create: true) - let directoryURL = appSupportURL.appendingPathComponent("Database", isDirectory: true) - - // Support for tests: delete the database if requested - if CommandLine.arguments.contains("-reset") { - try? fileManager.removeItem(at: directoryURL) - } - - // Create the database folder if needed - try fileManager.createDirectory(at: directoryURL, withIntermediateDirectories: true) - - // Open or create the database - let databaseURL = directoryURL.appendingPathComponent("db.sqlite") - NSLog("Database stored at \(databaseURL.path)") - let dbPool = try DatabasePool( - path: databaseURL.path, - // Use default AppDatabase configuration - configuration: AppDatabase.makeConfiguration()) - - // Create the AppDatabase - let appDatabase = try AppDatabase(dbPool) - - // Prepare the database with test fixtures if requested - if CommandLine.arguments.contains("-fixedTestData") { - try appDatabase.createPlayersForUITests() - } else { - // Otherwise, populate the database if it is empty, for better - // demo purpose. - try appDatabase.createRandomPlayersIfEmpty() - } - - return appDatabase - } catch { - // Replace this implementation with code to handle the error appropriately. - // fatalError() causes the application to generate a crash log and terminate. - // - // Typical reasons for an error here include: - // * The parent directory cannot be created, or disallows writing. - // * The database is not accessible, due to permissions or data protection when the device is locked. - // * The device is out of space. - // * The database could not be migrated to its latest schema version. - // Check the error message to determine what the actual problem was. - fatalError("Unresolved error \(error)") - } - } - - /// Creates an empty database for SwiftUI previews - static func empty() -> AppDatabase { - // Connect to an in-memory database - // See https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databaseconnections - let dbQueue = try! DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - return try! AppDatabase(dbQueue) - } - - /// Creates a database full of random players for SwiftUI previews - static func random() -> AppDatabase { - let appDatabase = empty() - try! appDatabase.createRandomPlayersIfEmpty() - return appDatabase - } -} diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Player.swift b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Player.swift deleted file mode 100644 index 7876b049df..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Player.swift +++ /dev/null @@ -1,105 +0,0 @@ -import GRDB - -/// The Player struct. -/// -/// Identifiable conformance supports SwiftUI list animations, and type-safe -/// GRDB primary key methods. -/// Equatable conformance supports tests. -struct Player: Identifiable, Equatable { - /// The player id. - /// - /// Int64 is the recommended type for auto-incremented database ids. - /// Use nil for players that are not inserted yet in the database. - var id: Int64? - var name: String - var score: Int -} - -extension Player { - private static let names = [ - "Arthur", "Anita", "Barbara", "Bernard", "Craig", "Chiara", "David", - "Dean", "Éric", "Elena", "Fatima", "Frederik", "Gilbert", "Georgette", - "Henriette", "Hassan", "Ignacio", "Irene", "Julie", "Jack", "Karl", - "Kristel", "Louis", "Liz", "Masashi", "Mary", "Noam", "Nicole", - "Ophelie", "Oleg", "Pascal", "Patricia", "Quentin", "Quinn", "Raoul", - "Rachel", "Stephan", "Susie", "Tristan", "Tatiana", "Ursule", "Urbain", - "Victor", "Violette", "Wilfried", "Wilhelmina", "Yvon", "Yann", - "Zazie", "Zoé"] - - /// Creates a new player with empty name and zero score - static func new() -> Player { - Player(id: nil, name: "", score: 0) - } - - /// Creates a new player with random name and random score - static func makeRandom() -> Player { - Player(id: nil, name: randomName(), score: randomScore()) - } - - /// Returns a random name - static func randomName() -> String { - names.randomElement()! - } - - /// Returns a random score - static func randomScore() -> Int { - 10 * Int.random(in: 0...100) - } -} - -// MARK: - Persistence - -/// Make Player a Codable Record. -/// -/// See -extension Player: Codable, FetchableRecord, MutablePersistableRecord { - // Define database columns from CodingKeys - fileprivate enum Columns { - static let name = Column(CodingKeys.name) - static let score = Column(CodingKeys.score) - } - - /// Updates a player id after it has been inserted in the database. - mutating func didInsert(_ inserted: InsertionSuccess) { - id = inserted.rowID - } -} - -// MARK: - Player Database Requests - -/// Define some player requests used by the application. -/// -/// See -extension DerivableRequest { - /// A request of players ordered by name. - /// - /// For example: - /// - /// let players: [Player] = try dbWriter.read { db in - /// try Player.all().orderedByName().fetchAll(db) - /// } - func orderedByName() -> Self { - // Sort by name in a localized case insensitive fashion - // See https://github.com/groue/GRDB.swift/blob/master/README.md#string-comparison - order(Player.Columns.name.collating(.localizedCaseInsensitiveCompare)) - } - - /// A request of players ordered by score. - /// - /// For example: - /// - /// let players: [Player] = try dbWriter.read { db in - /// try Player.all().orderedByScore().fetchAll(db) - /// } - /// let bestPlayer: Player? = try dbWriter.read { db in - /// try Player.all().orderedByScore().fetchOne(db) - /// } - func orderedByScore() -> Self { - // Sort by descending score, and then by name, in a - // localized case insensitive fashion - // See https://github.com/groue/GRDB.swift/blob/master/README.md#string-comparison - order( - Player.Columns.score.desc, - Player.Columns.name.collating(.localizedCaseInsensitiveCompare)) - } -} diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/PlayerRequest.swift b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/PlayerRequest.swift deleted file mode 100644 index 4d1d924605..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/PlayerRequest.swift +++ /dev/null @@ -1,35 +0,0 @@ -import GRDB -import GRDBQuery - -/// A player request can be used with the `@Query` property wrapper in order to -/// feed a view with a list of players. -/// -/// For example: -/// -/// struct MyView: View { -/// @Query(PlayerRequest(ordering: .byName)) private var players: [Player] -/// -/// var body: some View { -/// List(players) { player in ... ) -/// } -/// } -struct PlayerRequest: ValueObservationQueryable { - enum Ordering { - case byScore - case byName - } - - static var defaultValue: [Player] { [] } - - /// The ordering used by the player request. - var ordering: Ordering - - func fetch(_ db: Database) throws -> [Player] { - switch ordering { - case .byScore: - return try Player.all().orderedByScore().fetchAll(db) - case .byName: - return try Player.all().orderedByName().fetchAll(db) - } - } -} diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 29d91251df..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,116 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "icon_20pt@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "icon_20pt@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "icon_29pt@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "icon_29pt@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "icon_40pt@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "icon_40pt@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_60pt@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_60pt@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "icon_20pt.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "icon_20pt@2x-1.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "icon_29pt.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "icon_29pt@2x-1.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "icon_40pt.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "icon_40pt@2x-1.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_76pt.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_76pt@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "icon_83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "Icon.png", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/Icon.png b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/Icon.png deleted file mode 100644 index 66b1931a14..0000000000 Binary files a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/Icon.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt.png b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt.png deleted file mode 100644 index 90648b3f40..0000000000 Binary files a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png deleted file mode 100644 index a077a6f490..0000000000 Binary files a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png deleted file mode 100644 index a077a6f490..0000000000 Binary files a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png deleted file mode 100644 index 600bdbd9cd..0000000000 Binary files a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt.png b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt.png deleted file mode 100644 index 8e04af0dd8..0000000000 Binary files a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png deleted file mode 100644 index 686e8d99e2..0000000000 Binary files a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png deleted file mode 100644 index 686e8d99e2..0000000000 Binary files a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png deleted file mode 100644 index 1d013c3d33..0000000000 Binary files a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt.png b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt.png deleted file mode 100644 index a077a6f490..0000000000 Binary files a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png deleted file mode 100644 index da66b9ba82..0000000000 Binary files a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png deleted file mode 100644 index da66b9ba82..0000000000 Binary files a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png deleted file mode 100644 index 59346ef4b6..0000000000 Binary files a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png deleted file mode 100644 index 59346ef4b6..0000000000 Binary files a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png deleted file mode 100644 index d4640afc9a..0000000000 Binary files a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_76pt.png b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_76pt.png deleted file mode 100644 index e3a04522bf..0000000000 Binary files a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_76pt.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png deleted file mode 100644 index 593ebd783d..0000000000 Binary files a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png deleted file mode 100644 index ca02cd03bc..0000000000 Binary files a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/LaunchIcon.imageset/Contents.json b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/LaunchIcon.imageset/Contents.json deleted file mode 100644 index 2cbe59d5ec..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/LaunchIcon.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "filename" : "LaunchIcon.pdf", - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Base.lproj/LaunchScreen.storyboard b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index 79f85a1dd9..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/en.lproj/Localizable.stringsdict b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/en.lproj/Localizable.stringsdict deleted file mode 100644 index 2d9aa217c4..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/en.lproj/Localizable.stringsdict +++ /dev/null @@ -1,42 +0,0 @@ - - - - - %lld Players - - NSStringLocalizedFormatKey - %#@VARIABLE@ - VARIABLE - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - lld - zero - No Player - one - 1 Player - other - %lld Players - - - %lld points - - NSStringLocalizedFormatKey - %#@VARIABLE@ - VARIABLE - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - lld - zero - 0 point - one - 1 point - other - %lld points - - - - diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Views/AppView.swift b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Views/AppView.swift deleted file mode 100644 index 562b4aee8a..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Views/AppView.swift +++ /dev/null @@ -1,154 +0,0 @@ -import GRDBQuery -import SwiftUI - -/// The main application view -struct AppView: View { - /// Write access to the database - @Environment(\.appDatabase) private var appDatabase - - /// The `players` property is automatically updated when the database changes - @Query(PlayerRequest(ordering: .byScore)) private var players: [Player] - - /// We'll need to leave edit mode in several occasions. - @State private var editMode = EditMode.inactive - - /// Tracks the presentation of the player creation sheet. - @State private var newPlayerIsPresented = false - - // If you want to define the query on initialization, you will prefer: - // - // @Query private var players: [Player] - // - // init(initialOrdering: PlayerRequest.Ordering) { - // _players = Query(PlayerRequest(ordering: initialOrdering)) - // } - - var body: some View { - NavigationView { - PlayerList(players: players) - .navigationBarTitle(Text("\(players.count) Players")) - .navigationBarItems( - leading: HStack { - EditButton() - newPlayerButton - }, - trailing: ToggleOrderingButton( - ordering: $players.ordering, - willChange: { - // onChange(of: $players.wrappedValue.ordering) - // is not able to leave the editing mode during - // the animation of the list content. - // Workaround: stop editing before the ordering - // is changed, and the list content is updated. - stopEditing() - })) - .toolbar { toolbarContent } - .onChange(of: players) { - if players.isEmpty { - stopEditing() - } - } - .environment(\.editMode, $editMode) - } - } - - private var toolbarContent: some ToolbarContent { - ToolbarItemGroup(placement: .bottomBar) { - Button { - // Don't stopEditing() here because this is - // performed `onChange(of: players)` - Task { - try? await appDatabase.deleteAllPlayers() - } - } label: { - Image(systemName: "trash").imageScale(.large) - } - - Spacer() - - Button { - stopEditing() - Task { - try? await appDatabase.refreshPlayers() - } - } label: { - Image(systemName: "arrow.clockwise").imageScale(.large) - } - - Spacer() - - Button { - stopEditing() - // Perform 50 refreshes in parallel - Task { - try? await withThrowingTaskGroup(of: Void.self) { group in - for _ in 0..<50 { - _ = group.addTaskUnlessCancelled { - try await appDatabase.refreshPlayers() - } - } - try await group.waitForAll() - } - } - } label: { - Image(systemName: "tornado").imageScale(.large) - } - } - } - - /// The button that presents the player creation sheet. - private var newPlayerButton: some View { - Button { - stopEditing() - newPlayerIsPresented = true - } label: { - Image(systemName: "plus") - } - .accessibility(label: Text("New Player")) - .sheet(isPresented: $newPlayerIsPresented) { - PlayerCreationView() - } - } - - private func stopEditing() { - withAnimation { - editMode = .inactive - } - } -} - -private struct ToggleOrderingButton: View { - @Binding var ordering: PlayerRequest.Ordering - let willChange: () -> Void - - var body: some View { - switch ordering { - case .byName: - Button { - willChange() - ordering = .byScore - } label: { - Label("Name", systemImage: "arrowtriangle.up.fill").labelStyle(.titleAndIcon) - } - case .byScore: - Button { - willChange() - ordering = .byName - } label: { - Label("Score", systemImage: "arrowtriangle.down.fill").labelStyle(.titleAndIcon) - } - } - } -} - -// MARK: - Previews - -#Preview("Empty") { - // Preview the default, empty database - AppView() -} - -#Preview("Populated") { - // Preview a database of random players - AppView().appDatabase(.random()) -} diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Views/PlayerCreationView.swift b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Views/PlayerCreationView.swift deleted file mode 100644 index a47fdd04df..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Views/PlayerCreationView.swift +++ /dev/null @@ -1,50 +0,0 @@ -import SwiftUI - -/// The view that creates a new player. -struct PlayerCreationView: View { - /// Write access to the database - @Environment(\.appDatabase) private var appDatabase - @Environment(\.dismiss) private var dismiss - @State private var form = PlayerForm(name: "", score: "") - @State private var errorAlertIsPresented = false - @State private var errorAlertTitle = "" - - var body: some View { - NavigationView { - PlayerFormView(form: $form) - .alert( - isPresented: $errorAlertIsPresented, - content: { Alert(title: Text(errorAlertTitle)) }) - .navigationBarTitle("New Player") - .navigationBarItems( - leading: Button(role: .cancel) { - dismiss() - } label: { - Text("Cancel") - }, - trailing: Button { - Task { await save() } - } label: { - Text("Save") - }) - } - } - - private func save() async { - do { - var player = Player(id: nil, name: "", score: 0) - form.apply(to: &player) - try await appDatabase.savePlayer(&player) - dismiss() - } catch { - errorAlertTitle = (error as? LocalizedError)?.errorDescription ?? "An error occurred" - errorAlertIsPresented = true - } - } -} - -// MARK: - Previews - -#Preview { - PlayerCreationView() -} diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Views/PlayerEditionView.swift b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Views/PlayerEditionView.swift deleted file mode 100644 index 1ab97677dc..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Views/PlayerEditionView.swift +++ /dev/null @@ -1,40 +0,0 @@ -import SwiftUI - -/// The view that edits an existing player. -struct PlayerEditionView: View { - /// Write access to the database - @Environment(\.appDatabase) private var appDatabase - @Environment(\.isPresented) private var isPresented - private let player: Player - @State private var form: PlayerForm - - init(player: Player) { - self.player = player - self.form = PlayerForm(player) - } - - var body: some View { - PlayerFormView(form: $form) - .onChange(of: isPresented) { - // Save when back button is pressed - if !isPresented { - Task { - var savedPlayer = player - form.apply(to: &savedPlayer) - // Ignore error because I don't know how to cancel the - // back button and present the error - try? await appDatabase.savePlayer(&savedPlayer) - } - } - } - } -} - -// MARK: - Previews - -#Preview { - NavigationView { - PlayerEditionView(player: Player.makeRandom()) - .navigationBarTitle("Player Edition") - } -} diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Views/PlayerFormView.swift b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Views/PlayerFormView.swift deleted file mode 100644 index 590506d465..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Views/PlayerFormView.swift +++ /dev/null @@ -1,48 +0,0 @@ -import SwiftUI - -/// The Player editing form, embedded in both -/// `PlayerCreationView` and `PlayerEditionView`. -struct PlayerFormView: View { - @Binding var form: PlayerForm - - var body: some View { - List { - TextField("Name", text: $form.name) - .accessibility(label: Text("Player Name")) - TextField("Score", text: $form.score).keyboardType(.numberPad) - .accessibility(label: Text("Player Score")) - } - .listStyle(InsetGroupedListStyle()) - } -} - -struct PlayerForm { - var name: String - var score: String -} - -extension PlayerForm { - init(_ player: Player) { - self.name = player.name - self.score = "\(player.score)" - } - - func apply(to player: inout Player) { - player.name = name - player.score = Int(score) ?? 0 - } -} - -// MARK: - Previews - -#Preview("Empty") { - PlayerFormView(form: .constant(PlayerForm( - name: "", - score: ""))) -} - -#Preview("Prefilled") { - PlayerFormView(form: .constant(PlayerForm( - name: Player.randomName(), - score: "\(Player.randomScore())"))) -} diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Views/PlayerList.swift b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Views/PlayerList.swift deleted file mode 100644 index f156f786c0..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Views/PlayerList.swift +++ /dev/null @@ -1,59 +0,0 @@ -import SwiftUI - -struct PlayerList: View { - /// Write access to the database - @Environment(\.appDatabase) private var appDatabase - - /// The players in the list - var players: [Player] - - var body: some View { - List { - ForEach(players) { player in - NavigationLink(destination: editionView(for: player)) { - PlayerRow(player: player) - // Don't animate player update - .animation(nil, value: player) - } - } - .onDelete { offsets in - let playerIds = offsets.compactMap { players[$0].id } - Task { - try? await appDatabase.deletePlayers(ids: playerIds) - } - } - } - // Animate list updates - .animation(.default, value: players) - .listStyle(.plain) - } - - /// The view that edits a player in the list. - private func editionView(for player: Player) -> some View { - PlayerEditionView(player: player).navigationBarTitle(player.name) - } -} - -private struct PlayerRow: View { - var player: Player - - var body: some View { - HStack { - Text(player.name) - Spacer() - Text("\(player.score) points").foregroundColor(.gray) - } - } -} - -// MARK: - Previews - -#Preview { - NavigationView { - PlayerList(players: [ - Player(id: 1, name: "Arthur", score: 100), - Player(id: 2, name: "Barbara", score: 1000), - ]) - .navigationTitle("Preview") - } -} diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemoTests/AppDatabaseTests.swift b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemoTests/AppDatabaseTests.swift deleted file mode 100644 index b736e90774..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemoTests/AppDatabaseTests.swift +++ /dev/null @@ -1,144 +0,0 @@ -import XCTest -import GRDB -@testable import GRDBAsyncDemo - -class AppDatabaseTests: XCTestCase { - func test_database_schema() throws { - // Given an empty database - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - - // When we instantiate an AppDatabase - _ = try AppDatabase(dbQueue) - - // Then the player table exists, with id, name & score columns - try dbQueue.read { db in - try XCTAssert(db.tableExists("player")) - let columns = try db.columns(in: "player") - let columnNames = Set(columns.map { $0.name }) - XCTAssertEqual(columnNames, ["id", "name", "score"]) - } - } - - func test_savePlayer_inserts() async throws { - // Given an empty players database - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - let appDatabase = try AppDatabase(dbQueue) - - // When we save a new player - var player = Player(id: nil, name: "Arthur", score: 100) - try await appDatabase.savePlayer(&player) - - // Then the player exists in the database - let playerExists = try await dbQueue.read { [player] in try player.exists($0) } - XCTAssertTrue(playerExists) - } - - func test_savePlayer_updates() async throws { - // Given a players database that contains a player - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - let appDatabase = try AppDatabase(dbQueue) - var player = try await dbQueue.write { db in - try Player(id: nil, name: "Arthur", score: 100).inserted(db) - } - - // When we modify and save the player - player.name = "Barbara" - player.score = 1000 - try await appDatabase.savePlayer(&player) - - // Then the player has been updated in the database - let fetchedPlayer = try await dbQueue.read { [player] db in - try XCTUnwrap(Player.fetchOne(db, key: player.id)) - } - XCTAssertEqual(fetchedPlayer, player) - } - - func test_deletePlayers() async throws { - // Given a players database that contains four players - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - let appDatabase = try AppDatabase(dbQueue) - let playerIds: [Int64] = try await dbQueue.write { db in - _ = try Player(id: nil, name: "Arthur", score: 100).inserted(db) - _ = try Player(id: nil, name: "Barbara", score: 200).inserted(db) - _ = try Player(id: nil, name: "Craig", score: 150).inserted(db) - _ = try Player(id: nil, name: "David", score: 120).inserted(db) - return try Player.selectPrimaryKey().fetchAll(db) - } - - // When we delete two players - let deletedId1 = playerIds[0] - let deletedId2 = playerIds[2] - try await appDatabase.deletePlayers(ids: [deletedId1, deletedId2]) - - // Then the deleted players no longer exist - try await dbQueue.read { db in - try XCTAssertFalse(Player.exists(db, id: deletedId1)) - try XCTAssertFalse(Player.exists(db, id: deletedId2)) - } - - // Then the database still contains two players - let count = try await dbQueue.read { try Player.fetchCount($0) } - XCTAssertEqual(count, 2) - } - - func test_deleteAllPlayers() async throws { - // Given a players database that contains players - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - let appDatabase = try AppDatabase(dbQueue) - try await dbQueue.write { db in - _ = try Player(id: nil, name: "Arthur", score: 100).inserted(db) - _ = try Player(id: nil, name: "Barbara", score: 200).inserted(db) - _ = try Player(id: nil, name: "Craig", score: 150).inserted(db) - _ = try Player(id: nil, name: "David", score: 120).inserted(db) - } - - // When we delete all players - try await appDatabase.deleteAllPlayers() - - // Then the database does not contain any player - let count = try await dbQueue.read { try Player.fetchCount($0) } - XCTAssertEqual(count, 0) - } - - func test_refreshPlayers_populates_an_empty_database() async throws { - // Given an empty players database - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - let appDatabase = try AppDatabase(dbQueue) - - // When we refresh players - try await appDatabase.refreshPlayers() - - // Then the database is not empty - let count = try await dbQueue.read { try Player.fetchCount($0) } - XCTAssert(count > 0) - } - - func test_createRandomPlayersIfEmpty_populates_an_empty_database() throws { - // Given an empty players database - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - let appDatabase = try AppDatabase(dbQueue) - - // When we create random players - try appDatabase.createRandomPlayersIfEmpty() - - // Then the database is not empty - try XCTAssert(dbQueue.read(Player.fetchCount) > 0) - } - - func test_createRandomPlayersIfEmpty_does_not_modify_a_non_empty_database() throws { - // Given a players database that contains one player - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - let appDatabase = try AppDatabase(dbQueue) - var player = Player(id: nil, name: "Arthur", score: 100) - try dbQueue.write { db in - try player.insert(db) - } - - // When we create random players - try appDatabase.createRandomPlayersIfEmpty() - - // Then the database still only contains the original player - let players = try dbQueue.read(Player.fetchAll) - XCTAssertEqual(players, [player]) - } -} diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemoTests/Info.plist b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemoTests/Info.plist deleted file mode 100644 index 64d65ca495..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemoTests/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - 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 - - diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemoTests/PlayerRequestTests.swift b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemoTests/PlayerRequestTests.swift deleted file mode 100644 index 71d82ab409..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemoTests/PlayerRequestTests.swift +++ /dev/null @@ -1,43 +0,0 @@ -import XCTest -import GRDB -@testable import GRDBAsyncDemo - -class PlayerRequestTests: XCTestCase { - func test_PlayerRequest_byName_fetches_well_ordered_players() throws { - // Given a players database that contains two players - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - _ = try AppDatabase(dbQueue) - var player1 = Player(id: nil, name: "Arthur", score: 100) - var player2 = Player(id: nil, name: "Barbara", score: 1000) - try dbQueue.write { db in - try player1.insert(db) - try player2.insert(db) - } - - // When we fetch players ordered by name - let playerRequest = PlayerRequest(ordering: .byName) - let players = try dbQueue.read(playerRequest.fetch) - - // Then the players are the two players ordered by name - XCTAssertEqual(players, [player1, player2]) - } - - func test_PlayerRequest_byScore_fetches_well_ordered_players() throws { - // Given a players database that contains two players - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - _ = try AppDatabase(dbQueue) - var player1 = Player(id: nil, name: "Arthur", score: 100) - var player2 = Player(id: nil, name: "Barbara", score: 1000) - try dbQueue.write { db in - try player1.insert(db) - try player2.insert(db) - } - - // When we fetch players ordered by score - let playerRequest = PlayerRequest(ordering: .byScore) - let players = try dbQueue.read(playerRequest.fetch) - - // Then the players are the two players ordered by score descending - XCTAssertEqual(players, [player2, player1]) - } -} diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemoTests/PlayerTests.swift b/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemoTests/PlayerTests.swift deleted file mode 100644 index edd8726845..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemoTests/PlayerTests.swift +++ /dev/null @@ -1,108 +0,0 @@ -import XCTest -import GRDB -@testable import GRDBAsyncDemo - -class PlayerTests: XCTestCase { - // MARK: - CRUD - // Test that our Player type properly talks to GRDB. - - func testInsert() throws { - // Given an empty players database - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - _ = try AppDatabase(dbQueue) - - // When we insert a player - var player = Player(id: nil, name: "Arthur", score: 100) - try dbQueue.write { db in - try player.insert(db) - } - - // Then the player gets a non-nil id - XCTAssertNotNil(player.id) - } - - func testRoundtrip() throws { - // Given an empty players database - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - _ = try AppDatabase(dbQueue) - - // When we insert a player and fetch the player with the same id - var insertedPlayer = Player(id: nil, name: "Arthur", score: 100) - let fetchedPlayer: Player? = try dbQueue.write { db in - try insertedPlayer.insert(db) - return try Player.fetchOne(db, key: insertedPlayer.id) - } - - // Then the fetched player is equal to the inserted player - XCTAssertEqual(insertedPlayer, fetchedPlayer) - } - - // MARK: - Requests - // Test that requests defined on the Player type behave as expected. - - func testOrderedByScore() throws { - // Given a players database that contains players with distinct scores - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - _ = try AppDatabase(dbQueue) - var player1 = Player(id: 1, name: "Arthur", score: 100) - var player2 = Player(id: 2, name: "Barbara", score: 200) - var player3 = Player(id: 3, name: "Craig", score: 150) - var player4 = Player(id: 4, name: "David", score: 120) - try dbQueue.write { db in - try player1.insert(db) - try player2.insert(db) - try player3.insert(db) - try player4.insert(db) - } - - // When we fetch players ordered by score - let players = try dbQueue.read(Player.all().orderedByScore().fetchAll) - - // Then fetched players are ordered by score descending - XCTAssertEqual(players, [player2, player3, player4, player1]) - } - - func testOrderedByScoreSortsIdenticalScoresByName() throws { - // Given a players database that contains players with common scores - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - _ = try AppDatabase(dbQueue) - var player1 = Player(id: 1, name: "Arthur", score: 100) - var player2 = Player(id: 2, name: "Barbara", score: 200) - var player3 = Player(id: 3, name: "Craig", score: 200) - var player4 = Player(id: 4, name: "David", score: 200) - try dbQueue.write { db in - try player1.insert(db) - try player2.insert(db) - try player3.insert(db) - try player4.insert(db) - } - - // When we fetch players ordered by score - let players = try dbQueue.read(Player.all().orderedByScore().fetchAll) - - // Then fetched players are ordered by score descending and by name - XCTAssertEqual(players, [player2, player3, player4, player1]) - } - - func testOrderedByName() throws { - // Given a players database that contains players with distinct names - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - _ = try AppDatabase(dbQueue) - var player1 = Player(id: 1, name: "Arthur", score: 100) - var player2 = Player(id: 2, name: "Barbara", score: 200) - var player3 = Player(id: 3, name: "Craig", score: 150) - var player4 = Player(id: 4, name: "David", score: 120) - try dbQueue.write { db in - try player1.insert(db) - try player2.insert(db) - try player3.insert(db) - try player4.insert(db) - } - - // When we fetch players ordered by name - let players = try dbQueue.read(Player.all().orderedByName().fetchAll) - - // Then fetched players are ordered by name - XCTAssertEqual(players, [player1, player2, player3, player4]) - } -} diff --git a/Documentation/DemoApps/GRDBAsyncDemo/README.md b/Documentation/DemoApps/GRDBAsyncDemo/README.md deleted file mode 100644 index 79389fdb21..0000000000 --- a/Documentation/DemoApps/GRDBAsyncDemo/README.md +++ /dev/null @@ -1,52 +0,0 @@ -Async/Await + SwiftUI Demo Application -====================================== - - - -**This demo application is an Async/Await + SwiftUI application.** For a demo application that uses UIKit, see [GRDBDemoiOS](../GRDBDemoiOS/README.md), and for Combine + SwiftUI, see [GRDBCombineDemo](../GRDBCombineDemo/README.md). - -**Requirements**: iOS 15.0+ / Xcode 13.1+ - -> **Note**: This demo app is not a project template. Do not copy it as a starting point for your application. Instead, create a new project, choose a GRDB [installation method](../../../README.md#installation), and use the demo as an inspiration. - -The topics covered in this demo are: - -- How to setup a database in an iOS app. -- How to define a simple [Codable Record](../../../README.md#codable-records). -- How to track database changes and animate a SwiftUI List with [ValueObservation](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/valueobservation) Combine publishers. -- How to apply the recommendations of [Recommended Practices for Designing Record Types](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/recordrecommendedpractices). -- How to perform `async` database accesses. -- How to feed SwiftUI previews with a transient database. - -**Files of interest:** - -- [GRDBAsyncDemoApp.swift](GRDBAsyncDemo/GRDBAsyncDemoApp.swift) - - `GRDBAsyncDemoApp` feeds the app views with a database, through the SwiftUI environment. - -- [AppDatabase.swift](GRDBAsyncDemo/AppDatabase.swift) - - `AppDatabase` is the type that grants database access. It uses [DatabaseMigrator](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databasemigrator) in order to setup the database schema. - -- [Persistence.swift](GRDBAsyncDemo/Persistence.swift) - - This file instantiates various `AppDatabase` for the various projects needs: one database on disk for the application, and in-memory databases for SwiftUI previews. - -- [Player.swift](GRDBAsyncDemo/Player.swift) - - `Player` is a [Record](../../../README.md#records) type, able to read and write in the database. It conforms to the standard Codable protocol in order to gain all advantages of [Codable Records](../../../README.md#codable-records). - -- [PlayerRequest.swift](GRDBAsyncDemo/PlayerRequest.swift), [AppView.swift](GRDBAsyncDemo/Views/AppView.swift) - - `PlayerRequest` defines the player requests used by the app (sorted by score, or by name). - - `PlayerRequest` feeds the `@Query` property wrapper (`@Query`, defined in [GRDBQuery](https://github.com/groue/GRDBQuery), allows SwiftUI views to display up-to-date database content). - - `AppView` is the SwiftUI view that uses `@Query` in order to feed its player list. - -- [GRDBAsyncDemoTests](GRDBAsyncDemoTests) - - - Test the database schema - - Test the `Player` record and its requests - - Test the `PlayerRequest` methods that feed the list of players. - - Test the `AppDatabase` methods that let the app access the database. diff --git a/Documentation/DemoApps/GRDBAsyncDemo/Screenshot.png b/Documentation/DemoApps/GRDBAsyncDemo/Screenshot.png deleted file mode 100644 index 0536821854..0000000000 Binary files a/Documentation/DemoApps/GRDBAsyncDemo/Screenshot.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo.xcodeproj/project.pbxproj b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo.xcodeproj/project.pbxproj deleted file mode 100644 index f1892a540c..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo.xcodeproj/project.pbxproj +++ /dev/null @@ -1,611 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 54; - objects = { - -/* Begin PBXBuildFile section */ - 56026CAC25B8A7EF00D1DF3F /* PlayerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56026CAA25B8A7EF00D1DF3F /* PlayerTests.swift */; }; - 56026CAD25B8A7EF00D1DF3F /* AppDatabaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56026CAB25B8A7EF00D1DF3F /* AppDatabaseTests.swift */; }; - 56519DC7274FC85600ED16D8 /* GRDBQuery in Frameworks */ = {isa = PBXBuildFile; productRef = 56519DC6274FC85600ED16D8 /* GRDBQuery */; }; - 5671723A261B23C800423B6F /* PlayerList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56717239261B23C800423B6F /* PlayerList.swift */; }; - 56717252261B334D00423B6F /* PlayerRequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56717251261B334D00423B6F /* PlayerRequestTests.swift */; }; - 567C3E1A2520B6DE0011F6E9 /* GRDBCombineDemoApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567C3E192520B6DE0011F6E9 /* GRDBCombineDemoApp.swift */; }; - 567C3E1E2520B6DF0011F6E9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 567C3E1D2520B6DF0011F6E9 /* Assets.xcassets */; }; - 567C3E212520B6DF0011F6E9 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 567C3E202520B6DF0011F6E9 /* Preview Assets.xcassets */; }; - 567C3E5D2520B75C0011F6E9 /* Player.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567C3E532520B75C0011F6E9 /* Player.swift */; }; - 567C3E5E2520B75C0011F6E9 /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567C3E542520B75C0011F6E9 /* Persistence.swift */; }; - 567C3E612520B75D0011F6E9 /* PlayerFormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567C3E592520B75C0011F6E9 /* PlayerFormView.swift */; }; - 567C3E622520B75D0011F6E9 /* AppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567C3E5A2520B75C0011F6E9 /* AppView.swift */; }; - 567C3E632520B75D0011F6E9 /* PlayerCreationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567C3E5B2520B75C0011F6E9 /* PlayerCreationView.swift */; }; - 567C3E642520B75D0011F6E9 /* PlayerEditionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567C3E5C2520B75C0011F6E9 /* PlayerEditionView.swift */; }; - 567C3E662520B7880011F6E9 /* AppDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567C3E652520B7880011F6E9 /* AppDatabase.swift */; }; - 567C3E792520BB650011F6E9 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 567C3E752520BB650011F6E9 /* Localizable.stringsdict */; }; - 567C3E7A2520BB650011F6E9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 567C3E772520BB650011F6E9 /* LaunchScreen.storyboard */; }; - 56B6D1092619EC1B003CC455 /* PlayerRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B6D1082619EC1B003CC455 /* PlayerRequest.swift */; }; - 56F8A1202735989D0011ACBE /* GRDB in Frameworks */ = {isa = PBXBuildFile; productRef = 56F8A11F2735989D0011ACBE /* GRDB */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 56026C9D25B8A7D000D1DF3F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 567C3E0E2520B6DE0011F6E9 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 567C3E152520B6DE0011F6E9; - remoteInfo = GRDBCombineDemo; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 567C3E502520B70E0011F6E9 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 56026C9825B8A7D000D1DF3F /* GRDBCombineDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GRDBCombineDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 56026C9C25B8A7D000D1DF3F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 56026CAA25B8A7EF00D1DF3F /* PlayerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlayerTests.swift; sourceTree = ""; }; - 56026CAB25B8A7EF00D1DF3F /* AppDatabaseTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDatabaseTests.swift; sourceTree = ""; }; - 56717239261B23C800423B6F /* PlayerList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerList.swift; sourceTree = ""; }; - 56717251261B334D00423B6F /* PlayerRequestTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerRequestTests.swift; sourceTree = ""; }; - 567C3E162520B6DE0011F6E9 /* GRDBCombineDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GRDBCombineDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 567C3E192520B6DE0011F6E9 /* GRDBCombineDemoApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GRDBCombineDemoApp.swift; sourceTree = ""; }; - 567C3E1D2520B6DF0011F6E9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 567C3E202520B6DF0011F6E9 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; - 567C3E222520B6DF0011F6E9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 567C3E532520B75C0011F6E9 /* Player.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Player.swift; sourceTree = ""; }; - 567C3E542520B75C0011F6E9 /* Persistence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = ""; }; - 567C3E592520B75C0011F6E9 /* PlayerFormView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlayerFormView.swift; sourceTree = ""; }; - 567C3E5A2520B75C0011F6E9 /* AppView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppView.swift; sourceTree = ""; }; - 567C3E5B2520B75C0011F6E9 /* PlayerCreationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlayerCreationView.swift; sourceTree = ""; }; - 567C3E5C2520B75C0011F6E9 /* PlayerEditionView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlayerEditionView.swift; sourceTree = ""; }; - 567C3E652520B7880011F6E9 /* AppDatabase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDatabase.swift; sourceTree = ""; }; - 567C3E762520BB650011F6E9 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = ""; }; - 567C3E782520BB650011F6E9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 56B6D1082619EC1B003CC455 /* PlayerRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerRequest.swift; sourceTree = ""; }; - 56F8A11C2735988F0011ACBE /* GRDB.swift */ = {isa = PBXFileReference; lastKnownFileType = folder; name = GRDB.swift; path = ../../..; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 56026C9525B8A7D000D1DF3F /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 567C3E132520B6DE0011F6E9 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 56519DC7274FC85600ED16D8 /* GRDBQuery in Frameworks */, - 56F8A1202735989D0011ACBE /* GRDB in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 56026C9925B8A7D000D1DF3F /* GRDBCombineDemoTests */ = { - isa = PBXGroup; - children = ( - 56026C9C25B8A7D000D1DF3F /* Info.plist */, - 56026CAB25B8A7EF00D1DF3F /* AppDatabaseTests.swift */, - 56717251261B334D00423B6F /* PlayerRequestTests.swift */, - 56026CAA25B8A7EF00D1DF3F /* PlayerTests.swift */, - ); - path = GRDBCombineDemoTests; - sourceTree = ""; - }; - 56185BC125B8047D00B9C30F /* Resources */ = { - isa = PBXGroup; - children = ( - 567C3E1D2520B6DF0011F6E9 /* Assets.xcassets */, - 567C3E772520BB650011F6E9 /* LaunchScreen.storyboard */, - 567C3E752520BB650011F6E9 /* Localizable.stringsdict */, - ); - path = Resources; - sourceTree = ""; - }; - 567C3E0D2520B6DE0011F6E9 = { - isa = PBXGroup; - children = ( - 567C3E182520B6DE0011F6E9 /* GRDBCombineDemo */, - 56026C9925B8A7D000D1DF3F /* GRDBCombineDemoTests */, - 567C3E172520B6DE0011F6E9 /* Products */, - 567C3E4D2520B70E0011F6E9 /* Frameworks */, - 56F8A11C2735988F0011ACBE /* GRDB.swift */, - ); - sourceTree = ""; - }; - 567C3E172520B6DE0011F6E9 /* Products */ = { - isa = PBXGroup; - children = ( - 567C3E162520B6DE0011F6E9 /* GRDBCombineDemo.app */, - 56026C9825B8A7D000D1DF3F /* GRDBCombineDemoTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 567C3E182520B6DE0011F6E9 /* GRDBCombineDemo */ = { - isa = PBXGroup; - children = ( - 567C3E222520B6DF0011F6E9 /* Info.plist */, - 567C3E652520B7880011F6E9 /* AppDatabase.swift */, - 567C3E192520B6DE0011F6E9 /* GRDBCombineDemoApp.swift */, - 567C3E542520B75C0011F6E9 /* Persistence.swift */, - 567C3E532520B75C0011F6E9 /* Player.swift */, - 56B6D1082619EC1B003CC455 /* PlayerRequest.swift */, - 567C3E1F2520B6DF0011F6E9 /* Preview Content */, - 56185BC125B8047D00B9C30F /* Resources */, - 567C3E582520B75C0011F6E9 /* Views */, - ); - path = GRDBCombineDemo; - sourceTree = ""; - }; - 567C3E1F2520B6DF0011F6E9 /* Preview Content */ = { - isa = PBXGroup; - children = ( - 567C3E202520B6DF0011F6E9 /* Preview Assets.xcassets */, - ); - path = "Preview Content"; - sourceTree = ""; - }; - 567C3E4D2520B70E0011F6E9 /* Frameworks */ = { - isa = PBXGroup; - children = ( - ); - name = Frameworks; - sourceTree = ""; - }; - 567C3E582520B75C0011F6E9 /* Views */ = { - isa = PBXGroup; - children = ( - 567C3E5A2520B75C0011F6E9 /* AppView.swift */, - 567C3E5B2520B75C0011F6E9 /* PlayerCreationView.swift */, - 567C3E5C2520B75C0011F6E9 /* PlayerEditionView.swift */, - 567C3E592520B75C0011F6E9 /* PlayerFormView.swift */, - 56717239261B23C800423B6F /* PlayerList.swift */, - ); - path = Views; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 56026C9725B8A7D000D1DF3F /* GRDBCombineDemoTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 56026CA825B8A7D000D1DF3F /* Build configuration list for PBXNativeTarget "GRDBCombineDemoTests" */; - buildPhases = ( - 56026C9425B8A7D000D1DF3F /* Sources */, - 56026C9525B8A7D000D1DF3F /* Frameworks */, - 56026C9625B8A7D000D1DF3F /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 56026C9E25B8A7D000D1DF3F /* PBXTargetDependency */, - ); - name = GRDBCombineDemoTests; - productName = GRDBCombineDemoTests; - productReference = 56026C9825B8A7D000D1DF3F /* GRDBCombineDemoTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 567C3E152520B6DE0011F6E9 /* GRDBCombineDemo */ = { - isa = PBXNativeTarget; - buildConfigurationList = 567C3E252520B6DF0011F6E9 /* Build configuration list for PBXNativeTarget "GRDBCombineDemo" */; - buildPhases = ( - 567C3E122520B6DE0011F6E9 /* Sources */, - 567C3E132520B6DE0011F6E9 /* Frameworks */, - 567C3E142520B6DE0011F6E9 /* Resources */, - 567C3E502520B70E0011F6E9 /* Embed Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 56F8A11E273598960011ACBE /* PBXTargetDependency */, - ); - name = GRDBCombineDemo; - packageProductDependencies = ( - 56F8A11F2735989D0011ACBE /* GRDB */, - 56519DC6274FC85600ED16D8 /* GRDBQuery */, - ); - productName = GRBCombineDemo; - productReference = 567C3E162520B6DE0011F6E9 /* GRDBCombineDemo.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 567C3E0E2520B6DE0011F6E9 /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = YES; - LastSwiftUpdateCheck = 1250; - LastUpgradeCheck = 1200; - TargetAttributes = { - 56026C9725B8A7D000D1DF3F = { - CreatedOnToolsVersion = 12.3; - TestTargetID = 567C3E152520B6DE0011F6E9; - }; - 567C3E152520B6DE0011F6E9 = { - CreatedOnToolsVersion = 12.0; - }; - }; - }; - buildConfigurationList = 567C3E112520B6DE0011F6E9 /* Build configuration list for PBXProject "GRDBCombineDemo" */; - compatibilityVersion = "Xcode 12.0"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 567C3E0D2520B6DE0011F6E9; - packageReferences = ( - 56519DC5274FC85600ED16D8 /* XCRemoteSwiftPackageReference "GRDBQuery" */, - ); - productRefGroup = 567C3E172520B6DE0011F6E9 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 567C3E152520B6DE0011F6E9 /* GRDBCombineDemo */, - 56026C9725B8A7D000D1DF3F /* GRDBCombineDemoTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 56026C9625B8A7D000D1DF3F /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 567C3E142520B6DE0011F6E9 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 567C3E212520B6DF0011F6E9 /* Preview Assets.xcassets in Resources */, - 567C3E7A2520BB650011F6E9 /* LaunchScreen.storyboard in Resources */, - 567C3E1E2520B6DF0011F6E9 /* Assets.xcassets in Resources */, - 567C3E792520BB650011F6E9 /* Localizable.stringsdict in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 56026C9425B8A7D000D1DF3F /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 56026CAC25B8A7EF00D1DF3F /* PlayerTests.swift in Sources */, - 56026CAD25B8A7EF00D1DF3F /* AppDatabaseTests.swift in Sources */, - 56717252261B334D00423B6F /* PlayerRequestTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 567C3E122520B6DE0011F6E9 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 567C3E5E2520B75C0011F6E9 /* Persistence.swift in Sources */, - 567C3E5D2520B75C0011F6E9 /* Player.swift in Sources */, - 56B6D1092619EC1B003CC455 /* PlayerRequest.swift in Sources */, - 5671723A261B23C800423B6F /* PlayerList.swift in Sources */, - 567C3E612520B75D0011F6E9 /* PlayerFormView.swift in Sources */, - 567C3E632520B75D0011F6E9 /* PlayerCreationView.swift in Sources */, - 567C3E662520B7880011F6E9 /* AppDatabase.swift in Sources */, - 567C3E622520B75D0011F6E9 /* AppView.swift in Sources */, - 567C3E642520B75D0011F6E9 /* PlayerEditionView.swift in Sources */, - 567C3E1A2520B6DE0011F6E9 /* GRDBCombineDemoApp.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 56026C9E25B8A7D000D1DF3F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 567C3E152520B6DE0011F6E9 /* GRDBCombineDemo */; - targetProxy = 56026C9D25B8A7D000D1DF3F /* PBXContainerItemProxy */; - }; - 56F8A11E273598960011ACBE /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = 56F8A11D273598960011ACBE /* GRDB */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 567C3E752520BB650011F6E9 /* Localizable.stringsdict */ = { - isa = PBXVariantGroup; - children = ( - 567C3E762520BB650011F6E9 /* en */, - ); - name = Localizable.stringsdict; - sourceTree = ""; - }; - 567C3E772520BB650011F6E9 /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 567C3E782520BB650011F6E9 /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 56026C9F25B8A7D000D1DF3F /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - INFOPLIST_FILE = GRDBCombineDemoTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 17.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.github.groue.GRDBCombineDemoTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GRDBCombineDemo.app/GRDBCombineDemo"; - }; - name = Debug; - }; - 56026CA025B8A7D000D1DF3F /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - INFOPLIST_FILE = GRDBCombineDemoTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 17.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.github.groue.GRDBCombineDemoTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GRDBCombineDemo.app/GRDBCombineDemo"; - }; - name = Release; - }; - 567C3E232520B6DF0011F6E9 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.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; - }; - 567C3E242520B6DF0011F6E9 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.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; - }; - 567C3E262520B6DF0011F6E9 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_ASSET_PATHS = "\"GRDBCombineDemo/Preview Content\""; - DEVELOPMENT_TEAM = ""; - ENABLE_PREVIEWS = YES; - INFOPLIST_FILE = GRDBCombineDemo/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 17.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.github.groue.GRDBCombineDemo; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 1; - }; - name = Debug; - }; - 567C3E272520B6DF0011F6E9 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_ASSET_PATHS = "\"GRDBCombineDemo/Preview Content\""; - DEVELOPMENT_TEAM = ""; - ENABLE_PREVIEWS = YES; - INFOPLIST_FILE = GRDBCombineDemo/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 17.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.github.groue.GRDBCombineDemo; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 1; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 56026CA825B8A7D000D1DF3F /* Build configuration list for PBXNativeTarget "GRDBCombineDemoTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 56026C9F25B8A7D000D1DF3F /* Debug */, - 56026CA025B8A7D000D1DF3F /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 567C3E112520B6DE0011F6E9 /* Build configuration list for PBXProject "GRDBCombineDemo" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 567C3E232520B6DF0011F6E9 /* Debug */, - 567C3E242520B6DF0011F6E9 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 567C3E252520B6DF0011F6E9 /* Build configuration list for PBXNativeTarget "GRDBCombineDemo" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 567C3E262520B6DF0011F6E9 /* Debug */, - 567C3E272520B6DF0011F6E9 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - -/* Begin XCRemoteSwiftPackageReference section */ - 56519DC5274FC85600ED16D8 /* XCRemoteSwiftPackageReference "GRDBQuery" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/groue/GRDBQuery"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 0.6.0; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 56519DC6274FC85600ED16D8 /* GRDBQuery */ = { - isa = XCSwiftPackageProductDependency; - package = 56519DC5274FC85600ED16D8 /* XCRemoteSwiftPackageReference "GRDBQuery" */; - productName = GRDBQuery; - }; - 56F8A11D273598960011ACBE /* GRDB */ = { - isa = XCSwiftPackageProductDependency; - productName = GRDB; - }; - 56F8A11F2735989D0011ACBE /* GRDB */ = { - isa = XCSwiftPackageProductDependency; - productName = GRDB; - }; -/* End XCSwiftPackageProductDependency section */ - }; - rootObject = 567C3E0E2520B6DE0011F6E9 /* Project object */; -} diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a625..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003d..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved deleted file mode 100644 index 216295601d..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ /dev/null @@ -1,14 +0,0 @@ -{ - "pins" : [ - { - "identity" : "grdbquery", - "kind" : "remoteSourceControl", - "location" : "https://github.com/groue/GRDBQuery", - "state" : { - "revision" : "a6c46dd38ecf11a5c37732870dc03a384d582fba", - "version" : "0.9.0" - } - } - ], - "version" : 2 -} diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo.xcodeproj/xcshareddata/xcschemes/GRDBCombineDemo.xcscheme b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo.xcodeproj/xcshareddata/xcschemes/GRDBCombineDemo.xcscheme deleted file mode 100644 index 0cbf7bf5c1..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo.xcodeproj/xcshareddata/xcschemes/GRDBCombineDemo.xcscheme +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/AppDatabase.swift b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/AppDatabase.swift deleted file mode 100644 index c4b5a5e920..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/AppDatabase.swift +++ /dev/null @@ -1,235 +0,0 @@ -import Foundation -import GRDB -import os.log - -/// A database of players. -/// -/// You create an `AppDatabase` with a connection to an SQLite database -/// (see ). -/// -/// Create those connections with a configuration returned from -/// `AppDatabase/makeConfiguration(_:)`. -/// -/// For example: -/// -/// ```swift -/// // Create an in-memory AppDatabase -/// let config = AppDatabase.makeConfiguration() -/// let dbQueue = try DatabaseQueue(configuration: config) -/// let appDatabase = try AppDatabase(dbQueue) -/// ``` -struct AppDatabase { - /// Creates an `AppDatabase`, and makes sure the database schema - /// is ready. - /// - /// - important: Create the `DatabaseWriter` with a configuration - /// returned by ``makeConfiguration(_:)``. - init(_ dbWriter: any DatabaseWriter) throws { - self.dbWriter = dbWriter - try migrator.migrate(dbWriter) - } - - /// Provides access to the database. - /// - /// Application can use a `DatabasePool`, while SwiftUI previews and tests - /// can use a fast in-memory `DatabaseQueue`. - /// - /// See - private let dbWriter: any DatabaseWriter -} - -// MARK: - Database Configuration - -extension AppDatabase { - private static let sqlLogger = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "SQL") - - /// Returns a database configuration suited for `PlayerRepository`. - /// - /// SQL statements are logged if the `SQL_TRACE` environment variable - /// is set. - /// - /// - parameter base: A base configuration. - public static func makeConfiguration(_ base: Configuration = Configuration()) -> Configuration { - var config = base - - // An opportunity to add required custom SQL functions or - // collations, if needed: - // config.prepareDatabase { db in - // db.add(function: ...) - // } - - // Log SQL statements if the `SQL_TRACE` environment variable is set. - // See - if ProcessInfo.processInfo.environment["SQL_TRACE"] != nil { - config.prepareDatabase { db in - db.trace { - // It's ok to log statements publicly. Sensitive - // information (statement arguments) are not logged - // unless config.publicStatementArguments is set - // (see below). - os_log("%{public}@", log: sqlLogger, type: .debug, String(describing: $0)) - } - } - } - -#if DEBUG - // Protect sensitive information by enabling verbose debugging in - // DEBUG builds only. - // See - config.publicStatementArguments = true -#endif - - return config - } -} - -// MARK: - Database Migrations - -extension AppDatabase { - /// The DatabaseMigrator that defines the database schema. - /// - /// See - private var migrator: DatabaseMigrator { - var migrator = DatabaseMigrator() - -#if DEBUG - // Speed up development by nuking the database when migrations change - // See - migrator.eraseDatabaseOnSchemaChange = true -#endif - - migrator.registerMigration("createPlayer") { db in - // Create a table - // See - try db.create(table: "player") { t in - t.autoIncrementedPrimaryKey("id") - t.column("name", .text).notNull() - t.column("score", .integer).notNull() - } - } - - // Migrations for future application versions will be inserted here: - // migrator.registerMigration(...) { db in - // ... - // } - - return migrator - } -} - -// MARK: - Database Access: Writes -// The write methods execute invariant-preserving database transactions. - -extension AppDatabase { - /// A validation error that prevents some players from being saved into - /// the database. - enum ValidationError: LocalizedError { - case missingName - - var errorDescription: String? { - switch self { - case .missingName: - return "Please provide a name" - } - } - } - - /// Saves (inserts or updates) a player. When the method returns, the - /// player is present in the database, and its id is not nil. - func savePlayer(_ player: inout Player) throws { - if player.name.isEmpty { - throw ValidationError.missingName - } - try dbWriter.write { db in - try player.save(db) - } - } - - /// Delete the specified players - func deletePlayers(ids: [Int64]) throws { - try dbWriter.write { db in - _ = try Player.deleteAll(db, ids: ids) - } - } - - /// Delete all players - func deleteAllPlayers() throws { - try dbWriter.write { db in - _ = try Player.deleteAll(db) - } - } - - /// Refresh all players (by performing some random changes, for demo purpose). - func refreshPlayers() throws { - try dbWriter.write { db in - if try Player.all().isEmpty(db) { - // When database is empty, insert new random players - try createRandomPlayers(db) - } else { - // Insert a player - if Bool.random() { - _ = try Player.makeRandom().inserted(db) // insert but ignore inserted id - } - - // Delete a random player - if Bool.random() { - try Player.order(sql: "RANDOM()").limit(1).deleteAll(db) - } - - // Update some players - for var player in try Player.fetchAll(db) where Bool.random() { - try player.updateChanges(db) { - $0.score = Player.randomScore() - } - } - } - } - } - - /// Create random players if the database is empty. - func createRandomPlayersIfEmpty() throws { - try dbWriter.write { db in - if try Player.all().isEmpty(db) { - try createRandomPlayers(db) - } - } - } - - private static let uiTestPlayers = [ - Player(id: nil, name: "Arthur", score: 5), - Player(id: nil, name: "Barbara", score: 6), - Player(id: nil, name: "Craig", score: 8), - Player(id: nil, name: "David", score: 4), - Player(id: nil, name: "Elena", score: 1), - Player(id: nil, name: "Frederik", score: 2), - Player(id: nil, name: "Gilbert", score: 7), - Player(id: nil, name: "Henriette", score: 3)] - - func createPlayersForUITests() throws { - try dbWriter.write { db in - try AppDatabase.uiTestPlayers.forEach { player in - _ = try player.inserted(db) // insert but ignore inserted id - } - } - } - - /// Support for `createRandomPlayersIfEmpty()` and `refreshPlayers()`. - private func createRandomPlayers(_ db: Database) throws { - for _ in 0..<8 { - _ = try Player.makeRandom().inserted(db) // insert but ignore inserted id - } - } -} - -// MARK: - Database Access: Reads - -// This demo app does not provide any specific reading method, and instead -// gives an unrestricted read-only access to the rest of the application. -// In your app, you are free to choose another path, and define focused -// reading methods. -extension AppDatabase { - /// Provides a read-only access to the database - var reader: DatabaseReader { - dbWriter - } -} diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/GRDBCombineDemoApp.swift b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/GRDBCombineDemoApp.swift deleted file mode 100644 index 27db2c5ea4..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/GRDBCombineDemoApp.swift +++ /dev/null @@ -1,32 +0,0 @@ -import GRDBQuery -import SwiftUI - -@main -struct GRDBCombineDemoApp: App { - var body: some Scene { - WindowGroup { - AppView().appDatabase(.shared) - } - } -} - -// MARK: - Give SwiftUI access to the database - -private struct AppDatabaseKey: EnvironmentKey { - static var defaultValue: AppDatabase { .empty() } -} - -extension EnvironmentValues { - var appDatabase: AppDatabase { - get { self[AppDatabaseKey.self] } - set { self[AppDatabaseKey.self] = newValue } - } -} - -extension View { - func appDatabase(_ appDatabase: AppDatabase) -> some View { - self - .environment(\.appDatabase, appDatabase) - .databaseContext(.readOnly { appDatabase.reader }) - } -} diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Info.plist b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Info.plist deleted file mode 100644 index 4754bb8682..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Info.plist +++ /dev/null @@ -1,50 +0,0 @@ - - - - - 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 - - - UIApplicationSupportsIndirectInputEvents - - UILaunchScreen - - UILaunchStoryboardName - LaunchScreen - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Persistence.swift b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Persistence.swift deleted file mode 100644 index 05b0115789..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Persistence.swift +++ /dev/null @@ -1,77 +0,0 @@ -import Foundation -import GRDB - -extension AppDatabase { - /// The database for the application - static let shared = makeShared() - - private static func makeShared() -> AppDatabase { - do { - // Apply recommendations from - // - // - // Create the "Application Support/Database" directory if needed - let fileManager = FileManager.default - let appSupportURL = try fileManager.url( - for: .applicationSupportDirectory, in: .userDomainMask, - appropriateFor: nil, create: true) - let directoryURL = appSupportURL.appendingPathComponent("Database", isDirectory: true) - - // Support for tests: delete the database if requested - if CommandLine.arguments.contains("-reset") { - try? fileManager.removeItem(at: directoryURL) - } - - // Create the database folder if needed - try fileManager.createDirectory(at: directoryURL, withIntermediateDirectories: true) - - // Open or create the database - let databaseURL = directoryURL.appendingPathComponent("db.sqlite") - NSLog("Database stored at \(databaseURL.path)") - let dbPool = try DatabasePool( - path: databaseURL.path, - // Use default AppDatabase configuration - configuration: AppDatabase.makeConfiguration()) - - // Create the AppDatabase - let appDatabase = try AppDatabase(dbPool) - - // Prepare the database with test fixtures if requested - if CommandLine.arguments.contains("-fixedTestData") { - try appDatabase.createPlayersForUITests() - } else { - // Otherwise, populate the database if it is empty, for better - // demo purpose. - try appDatabase.createRandomPlayersIfEmpty() - } - - return appDatabase - } catch { - // Replace this implementation with code to handle the error appropriately. - // fatalError() causes the application to generate a crash log and terminate. - // - // Typical reasons for an error here include: - // * The parent directory cannot be created, or disallows writing. - // * The database is not accessible, due to permissions or data protection when the device is locked. - // * The device is out of space. - // * The database could not be migrated to its latest schema version. - // Check the error message to determine what the actual problem was. - fatalError("Unresolved error \(error)") - } - } - - /// Creates an empty database for SwiftUI previews - static func empty() -> AppDatabase { - // Connect to an in-memory database - // See https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databaseconnections - let dbQueue = try! DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - return try! AppDatabase(dbQueue) - } - - /// Creates a database full of random players for SwiftUI previews - static func random() -> AppDatabase { - let appDatabase = empty() - try! appDatabase.createRandomPlayersIfEmpty() - return appDatabase - } -} diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Player.swift b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Player.swift deleted file mode 100644 index 7876b049df..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Player.swift +++ /dev/null @@ -1,105 +0,0 @@ -import GRDB - -/// The Player struct. -/// -/// Identifiable conformance supports SwiftUI list animations, and type-safe -/// GRDB primary key methods. -/// Equatable conformance supports tests. -struct Player: Identifiable, Equatable { - /// The player id. - /// - /// Int64 is the recommended type for auto-incremented database ids. - /// Use nil for players that are not inserted yet in the database. - var id: Int64? - var name: String - var score: Int -} - -extension Player { - private static let names = [ - "Arthur", "Anita", "Barbara", "Bernard", "Craig", "Chiara", "David", - "Dean", "Éric", "Elena", "Fatima", "Frederik", "Gilbert", "Georgette", - "Henriette", "Hassan", "Ignacio", "Irene", "Julie", "Jack", "Karl", - "Kristel", "Louis", "Liz", "Masashi", "Mary", "Noam", "Nicole", - "Ophelie", "Oleg", "Pascal", "Patricia", "Quentin", "Quinn", "Raoul", - "Rachel", "Stephan", "Susie", "Tristan", "Tatiana", "Ursule", "Urbain", - "Victor", "Violette", "Wilfried", "Wilhelmina", "Yvon", "Yann", - "Zazie", "Zoé"] - - /// Creates a new player with empty name and zero score - static func new() -> Player { - Player(id: nil, name: "", score: 0) - } - - /// Creates a new player with random name and random score - static func makeRandom() -> Player { - Player(id: nil, name: randomName(), score: randomScore()) - } - - /// Returns a random name - static func randomName() -> String { - names.randomElement()! - } - - /// Returns a random score - static func randomScore() -> Int { - 10 * Int.random(in: 0...100) - } -} - -// MARK: - Persistence - -/// Make Player a Codable Record. -/// -/// See -extension Player: Codable, FetchableRecord, MutablePersistableRecord { - // Define database columns from CodingKeys - fileprivate enum Columns { - static let name = Column(CodingKeys.name) - static let score = Column(CodingKeys.score) - } - - /// Updates a player id after it has been inserted in the database. - mutating func didInsert(_ inserted: InsertionSuccess) { - id = inserted.rowID - } -} - -// MARK: - Player Database Requests - -/// Define some player requests used by the application. -/// -/// See -extension DerivableRequest { - /// A request of players ordered by name. - /// - /// For example: - /// - /// let players: [Player] = try dbWriter.read { db in - /// try Player.all().orderedByName().fetchAll(db) - /// } - func orderedByName() -> Self { - // Sort by name in a localized case insensitive fashion - // See https://github.com/groue/GRDB.swift/blob/master/README.md#string-comparison - order(Player.Columns.name.collating(.localizedCaseInsensitiveCompare)) - } - - /// A request of players ordered by score. - /// - /// For example: - /// - /// let players: [Player] = try dbWriter.read { db in - /// try Player.all().orderedByScore().fetchAll(db) - /// } - /// let bestPlayer: Player? = try dbWriter.read { db in - /// try Player.all().orderedByScore().fetchOne(db) - /// } - func orderedByScore() -> Self { - // Sort by descending score, and then by name, in a - // localized case insensitive fashion - // See https://github.com/groue/GRDB.swift/blob/master/README.md#string-comparison - order( - Player.Columns.score.desc, - Player.Columns.name.collating(.localizedCaseInsensitiveCompare)) - } -} diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/PlayerRequest.swift b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/PlayerRequest.swift deleted file mode 100644 index 4d1d924605..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/PlayerRequest.swift +++ /dev/null @@ -1,35 +0,0 @@ -import GRDB -import GRDBQuery - -/// A player request can be used with the `@Query` property wrapper in order to -/// feed a view with a list of players. -/// -/// For example: -/// -/// struct MyView: View { -/// @Query(PlayerRequest(ordering: .byName)) private var players: [Player] -/// -/// var body: some View { -/// List(players) { player in ... ) -/// } -/// } -struct PlayerRequest: ValueObservationQueryable { - enum Ordering { - case byScore - case byName - } - - static var defaultValue: [Player] { [] } - - /// The ordering used by the player request. - var ordering: Ordering - - func fetch(_ db: Database) throws -> [Player] { - switch ordering { - case .byScore: - return try Player.all().orderedByScore().fetchAll(db) - case .byName: - return try Player.all().orderedByName().fetchAll(db) - } - } -} diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Preview Content/Preview Assets.xcassets/Contents.json b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Preview Content/Preview Assets.xcassets/Contents.json deleted file mode 100644 index 73c00596a7..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Preview Content/Preview Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AccentColor.colorset/Contents.json b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AccentColor.colorset/Contents.json deleted file mode 100644 index eb87897008..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AccentColor.colorset/Contents.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "colors" : [ - { - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 29d91251df..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,116 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "icon_20pt@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "icon_20pt@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "icon_29pt@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "icon_29pt@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "icon_40pt@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "icon_40pt@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_60pt@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_60pt@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "icon_20pt.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "icon_20pt@2x-1.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "icon_29pt.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "icon_29pt@2x-1.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "icon_40pt.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "icon_40pt@2x-1.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_76pt.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_76pt@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "icon_83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "Icon.png", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/Icon.png b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/Icon.png deleted file mode 100644 index 66b1931a14..0000000000 Binary files a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/Icon.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt.png b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt.png deleted file mode 100644 index 90648b3f40..0000000000 Binary files a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png deleted file mode 100644 index a077a6f490..0000000000 Binary files a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png deleted file mode 100644 index a077a6f490..0000000000 Binary files a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png deleted file mode 100644 index 600bdbd9cd..0000000000 Binary files a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt.png b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt.png deleted file mode 100644 index 8e04af0dd8..0000000000 Binary files a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png deleted file mode 100644 index 686e8d99e2..0000000000 Binary files a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png deleted file mode 100644 index 686e8d99e2..0000000000 Binary files a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png deleted file mode 100644 index 1d013c3d33..0000000000 Binary files a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt.png b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt.png deleted file mode 100644 index a077a6f490..0000000000 Binary files a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png deleted file mode 100644 index da66b9ba82..0000000000 Binary files a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png deleted file mode 100644 index da66b9ba82..0000000000 Binary files a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png deleted file mode 100644 index 59346ef4b6..0000000000 Binary files a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png deleted file mode 100644 index 59346ef4b6..0000000000 Binary files a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png deleted file mode 100644 index d4640afc9a..0000000000 Binary files a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_76pt.png b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_76pt.png deleted file mode 100644 index e3a04522bf..0000000000 Binary files a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_76pt.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png deleted file mode 100644 index 593ebd783d..0000000000 Binary files a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png deleted file mode 100644 index ca02cd03bc..0000000000 Binary files a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/Contents.json b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/Contents.json deleted file mode 100644 index 73c00596a7..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/LaunchIcon.imageset/Contents.json b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/LaunchIcon.imageset/Contents.json deleted file mode 100644 index 2cbe59d5ec..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/LaunchIcon.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "filename" : "LaunchIcon.pdf", - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/LaunchIcon.imageset/LaunchIcon.pdf b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/LaunchIcon.imageset/LaunchIcon.pdf deleted file mode 100644 index 2660891492..0000000000 Binary files a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Assets.xcassets/LaunchIcon.imageset/LaunchIcon.pdf and /dev/null differ diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Base.lproj/LaunchScreen.storyboard b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index 79f85a1dd9..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/en.lproj/Localizable.stringsdict b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/en.lproj/Localizable.stringsdict deleted file mode 100644 index 2d9aa217c4..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Resources/en.lproj/Localizable.stringsdict +++ /dev/null @@ -1,42 +0,0 @@ - - - - - %lld Players - - NSStringLocalizedFormatKey - %#@VARIABLE@ - VARIABLE - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - lld - zero - No Player - one - 1 Player - other - %lld Players - - - %lld points - - NSStringLocalizedFormatKey - %#@VARIABLE@ - VARIABLE - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - lld - zero - 0 point - one - 1 point - other - %lld points - - - - diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Views/AppView.swift b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Views/AppView.swift deleted file mode 100644 index 7c93e15cb8..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Views/AppView.swift +++ /dev/null @@ -1,145 +0,0 @@ -import GRDBQuery -import SwiftUI - -/// The main application view -struct AppView: View { - /// Write access to the database - @Environment(\.appDatabase) private var appDatabase - - /// The `players` property is automatically updated when the database changes - @Query(PlayerRequest(ordering: .byScore)) private var players: [Player] - - /// We'll need to leave edit mode in several occasions. - @State private var editMode = EditMode.inactive - - /// Tracks the presentation of the player creation sheet. - @State private var newPlayerIsPresented = false - - // If you want to define the query on initialization, you will prefer: - // - // @Query private var players: [Player] - // - // init(initialOrdering: PlayerRequest.Ordering) { - // _players = Query(PlayerRequest(ordering: initialOrdering)) - // } - - var body: some View { - NavigationView { - PlayerList(players: players) - .navigationBarTitle(Text("\(players.count) Players")) - .navigationBarItems( - leading: HStack { - EditButton() - newPlayerButton - }, - trailing: ToggleOrderingButton( - ordering: $players.ordering, - willChange: { - // onChange(of: $players.wrappedValue.ordering) - // is not able to leave the editing mode during - // the animation of the list content. - // Workaround: stop editing before the ordering - // is changed, and the list content is updated. - stopEditing() - })) - .toolbar { toolbarContent } - .onChange(of: players) { - if players.isEmpty { - stopEditing() - } - } - .environment(\.editMode, $editMode) - } - } - - private var toolbarContent: some ToolbarContent { - ToolbarItemGroup(placement: .bottomBar) { - Button { - // Don't stopEditing() here because this is - // performed `onChange(of: players)` - try! appDatabase.deleteAllPlayers() - } label: { - Image(systemName: "trash").imageScale(.large) - } - - Spacer() - - Button { - stopEditing() - try! appDatabase.refreshPlayers() - } label: { - Image(systemName: "arrow.clockwise").imageScale(.large) - } - - Spacer() - - Button { - stopEditing() - // Perform 50 refreshes in parallel - for _ in 0..<50 { - DispatchQueue.global().async { - try! AppDatabase.shared.refreshPlayers() - } - } - } label: { - Image(systemName: "tornado").imageScale(.large) - } - } - } - - /// The button that presents the player creation sheet. - private var newPlayerButton: some View { - Button { - stopEditing() - newPlayerIsPresented = true - } label: { - Image(systemName: "plus") - } - .accessibility(label: Text("New Player")) - .sheet(isPresented: $newPlayerIsPresented) { - PlayerCreationView() - } - } - - private func stopEditing() { - withAnimation { - editMode = .inactive - } - } -} - -private struct ToggleOrderingButton: View { - @Binding var ordering: PlayerRequest.Ordering - let willChange: () -> Void - - var body: some View { - switch ordering { - case .byName: - Button { - willChange() - ordering = .byScore - } label: { - Label("Name", systemImage: "arrowtriangle.up.fill").labelStyle(.titleAndIcon) - } - case .byScore: - Button { - willChange() - ordering = .byName - } label: { - Label("Score", systemImage: "arrowtriangle.down.fill").labelStyle(.titleAndIcon) - } - } - } -} - -// MARK: - Previews - -#Preview("Empty") { - // Preview the default, empty database - AppView() -} - -#Preview("Populated") { - // Preview a database of random players - AppView().appDatabase(.random()) -} diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Views/PlayerCreationView.swift b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Views/PlayerCreationView.swift deleted file mode 100644 index f86876fd9f..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Views/PlayerCreationView.swift +++ /dev/null @@ -1,50 +0,0 @@ -import SwiftUI - -/// The view that creates a new player. -struct PlayerCreationView: View { - /// Write access to the database - @Environment(\.appDatabase) private var appDatabase - @Environment(\.dismiss) private var dismiss - @State private var form = PlayerForm(name: "", score: "") - @State private var errorAlertIsPresented = false - @State private var errorAlertTitle = "" - - var body: some View { - NavigationView { - PlayerFormView(form: $form) - .alert( - isPresented: $errorAlertIsPresented, - content: { Alert(title: Text(errorAlertTitle)) }) - .navigationBarTitle("New Player") - .navigationBarItems( - leading: Button(role: .cancel) { - dismiss() - } label: { - Text("Cancel") - }, - trailing: Button { - save() - } label: { - Text("Save") - }) - } - } - - private func save() { - do { - var player = Player(id: nil, name: "", score: 0) - form.apply(to: &player) - try appDatabase.savePlayer(&player) - dismiss() - } catch { - errorAlertTitle = (error as? LocalizedError)?.errorDescription ?? "An error occurred" - errorAlertIsPresented = true - } - } -} - -// MARK: - Previews - -#Preview { - PlayerCreationView() -} diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Views/PlayerEditionView.swift b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Views/PlayerEditionView.swift deleted file mode 100644 index a3c559a1af..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Views/PlayerEditionView.swift +++ /dev/null @@ -1,38 +0,0 @@ -import SwiftUI - -/// The view that edits an existing player. -struct PlayerEditionView: View { - /// Write access to the database - @Environment(\.appDatabase) private var appDatabase - @Environment(\.isPresented) private var isPresented - private let player: Player - @State private var form: PlayerForm - - init(player: Player) { - self.player = player - self.form = PlayerForm(player) - } - - var body: some View { - PlayerFormView(form: $form) - .onChange(of: isPresented) { - // Save when back button is pressed - if !isPresented { - var savedPlayer = player - form.apply(to: &savedPlayer) - // Ignore error because I don't know how to cancel the - // back button and present the error - try? appDatabase.savePlayer(&savedPlayer) - } - } - } -} - -// MARK: - Previews - -#Preview { - NavigationView { - PlayerEditionView(player: Player.makeRandom()) - .navigationBarTitle("Player Edition") - } -} diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Views/PlayerFormView.swift b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Views/PlayerFormView.swift deleted file mode 100644 index 590506d465..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Views/PlayerFormView.swift +++ /dev/null @@ -1,48 +0,0 @@ -import SwiftUI - -/// The Player editing form, embedded in both -/// `PlayerCreationView` and `PlayerEditionView`. -struct PlayerFormView: View { - @Binding var form: PlayerForm - - var body: some View { - List { - TextField("Name", text: $form.name) - .accessibility(label: Text("Player Name")) - TextField("Score", text: $form.score).keyboardType(.numberPad) - .accessibility(label: Text("Player Score")) - } - .listStyle(InsetGroupedListStyle()) - } -} - -struct PlayerForm { - var name: String - var score: String -} - -extension PlayerForm { - init(_ player: Player) { - self.name = player.name - self.score = "\(player.score)" - } - - func apply(to player: inout Player) { - player.name = name - player.score = Int(score) ?? 0 - } -} - -// MARK: - Previews - -#Preview("Empty") { - PlayerFormView(form: .constant(PlayerForm( - name: "", - score: ""))) -} - -#Preview("Prefilled") { - PlayerFormView(form: .constant(PlayerForm( - name: Player.randomName(), - score: "\(Player.randomScore())"))) -} diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Views/PlayerList.swift b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Views/PlayerList.swift deleted file mode 100644 index 7913c73c60..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/Views/PlayerList.swift +++ /dev/null @@ -1,57 +0,0 @@ -import SwiftUI - -struct PlayerList: View { - /// Write access to the database - @Environment(\.appDatabase) private var appDatabase - - /// The players in the list - var players: [Player] - - var body: some View { - List { - ForEach(players) { player in - NavigationLink(destination: editionView(for: player)) { - PlayerRow(player: player) - // Don't animate player update - .animation(nil, value: player) - } - } - .onDelete { offsets in - let playerIds = offsets.compactMap { players[$0].id } - try? appDatabase.deletePlayers(ids: playerIds) - } - } - // Animate list updates - .animation(.default, value: players) - .listStyle(.plain) - } - - /// The view that edits a player in the list. - private func editionView(for player: Player) -> some View { - PlayerEditionView(player: player).navigationBarTitle(player.name) - } -} - -private struct PlayerRow: View { - var player: Player - - var body: some View { - HStack { - Text(player.name) - Spacer() - Text("\(player.score) points").foregroundColor(.gray) - } - } -} - -// MARK: - Previews - -#Preview { - NavigationView { - PlayerList(players: [ - Player(id: 1, name: "Arthur", score: 100), - Player(id: 2, name: "Barbara", score: 1000), - ]) - .navigationTitle("Preview") - } -} diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemoTests/AppDatabaseTests.swift b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemoTests/AppDatabaseTests.swift deleted file mode 100644 index f9343671e1..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemoTests/AppDatabaseTests.swift +++ /dev/null @@ -1,146 +0,0 @@ -import XCTest -import GRDB -@testable import GRDBCombineDemo - -class AppDatabaseTests: XCTestCase { - func test_database_schema() throws { - // Given an empty database - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - - // When we instantiate an AppDatabase - _ = try AppDatabase(dbQueue) - - // Then the player table exists, with id, name & score columns - try dbQueue.read { db in - try XCTAssert(db.tableExists("player")) - let columns = try db.columns(in: "player") - let columnNames = Set(columns.map { $0.name }) - XCTAssertEqual(columnNames, ["id", "name", "score"]) - } - } - - func test_savePlayer_inserts() throws { - // Given an empty players database - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - let appDatabase = try AppDatabase(dbQueue) - - // When we save a new player - var player = Player(id: nil, name: "Arthur", score: 100) - try appDatabase.savePlayer(&player) - - // Then the player exists in the database - try XCTAssertTrue(dbQueue.read(player.exists)) - } - - func test_savePlayer_updates() throws { - // Given a players database that contains a player - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - let appDatabase = try AppDatabase(dbQueue) - var player = Player(id: nil, name: "Arthur", score: 100) - try dbQueue.write { db in - try player.insert(db) - } - - // When we modify and save the player - player.name = "Barbara" - player.score = 1000 - try appDatabase.savePlayer(&player) - - // Then the player has been updated in the database - let fetchedPlayer = try dbQueue.read { db in - try XCTUnwrap(Player.fetchOne(db, key: player.id)) - } - XCTAssertEqual(fetchedPlayer, player) - } - - func test_deletePlayers() throws { - // Given a players database that contains four players - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - let appDatabase = try AppDatabase(dbQueue) - var player1 = Player(id: nil, name: "Arthur", score: 100) - var player2 = Player(id: nil, name: "Barbara", score: 200) - var player3 = Player(id: nil, name: "Craig", score: 150) - var player4 = Player(id: nil, name: "David", score: 120) - try dbQueue.write { db in - try player1.insert(db) - try player2.insert(db) - try player3.insert(db) - try player4.insert(db) - } - - // When we delete two players - try appDatabase.deletePlayers(ids: [player1.id!, player3.id!]) - - // Then the deleted players no longer exist - try dbQueue.read { db in - try XCTAssertFalse(player1.exists(db)) - try XCTAssertFalse(player3.exists(db)) - } - - // Then the database still contains two players - try XCTAssertEqual(dbQueue.read(Player.fetchCount), 2) - } - - func test_deleteAllPlayers() throws { - // Given a players database that contains players - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - let appDatabase = try AppDatabase(dbQueue) - var player1 = Player(id: nil, name: "Arthur", score: 100) - var player2 = Player(id: nil, name: "Barbara", score: 200) - var player3 = Player(id: nil, name: "Craig", score: 150) - var player4 = Player(id: nil, name: "David", score: 120) - try dbQueue.write { db in - try player1.insert(db) - try player2.insert(db) - try player3.insert(db) - try player4.insert(db) - } - - // When we delete all players - try appDatabase.deleteAllPlayers() - - // Then the database does not contain any player - try XCTAssertEqual(dbQueue.read(Player.fetchCount), 0) - } - - func test_refreshPlayers_populates_an_empty_database() throws { - // Given an empty players database - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - let appDatabase = try AppDatabase(dbQueue) - - // When we refresh players - try appDatabase.refreshPlayers() - - // Then the database is not empty - try XCTAssert(dbQueue.read(Player.fetchCount) > 0) - } - - func test_createRandomPlayersIfEmpty_populates_an_empty_database() throws { - // Given an empty players database - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - let appDatabase = try AppDatabase(dbQueue) - - // When we create random players - try appDatabase.createRandomPlayersIfEmpty() - - // Then the database is not empty - try XCTAssert(dbQueue.read(Player.fetchCount) > 0) - } - - func test_createRandomPlayersIfEmpty_does_not_modify_a_non_empty_database() throws { - // Given a players database that contains one player - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - let appDatabase = try AppDatabase(dbQueue) - var player = Player(id: nil, name: "Arthur", score: 100) - try dbQueue.write { db in - try player.insert(db) - } - - // When we create random players - try appDatabase.createRandomPlayersIfEmpty() - - // Then the database still only contains the original player - let players = try dbQueue.read(Player.fetchAll) - XCTAssertEqual(players, [player]) - } -} diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemoTests/Info.plist b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemoTests/Info.plist deleted file mode 100644 index 64d65ca495..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemoTests/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - 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 - - diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemoTests/PlayerRequestTests.swift b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemoTests/PlayerRequestTests.swift deleted file mode 100644 index c9e58da1ed..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemoTests/PlayerRequestTests.swift +++ /dev/null @@ -1,43 +0,0 @@ -import XCTest -import GRDB -@testable import GRDBCombineDemo - -class PlayerRequestTests: XCTestCase { - func test_PlayerRequest_byName_fetches_well_ordered_players() throws { - // Given a players database that contains two players - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - _ = try AppDatabase(dbQueue) - var player1 = Player(id: nil, name: "Arthur", score: 100) - var player2 = Player(id: nil, name: "Barbara", score: 1000) - try dbQueue.write { db in - try player1.insert(db) - try player2.insert(db) - } - - // When we fetch players ordered by name - let playerRequest = PlayerRequest(ordering: .byName) - let players = try dbQueue.read(playerRequest.fetch) - - // Then the players are the two players ordered by name - XCTAssertEqual(players, [player1, player2]) - } - - func test_PlayerRequest_byScore_fetches_well_ordered_players() throws { - // Given a players database that contains two players - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - _ = try AppDatabase(dbQueue) - var player1 = Player(id: nil, name: "Arthur", score: 100) - var player2 = Player(id: nil, name: "Barbara", score: 1000) - try dbQueue.write { db in - try player1.insert(db) - try player2.insert(db) - } - - // When we fetch players ordered by score - let playerRequest = PlayerRequest(ordering: .byScore) - let players = try dbQueue.read(playerRequest.fetch) - - // Then the players are the two players ordered by score descending - XCTAssertEqual(players, [player2, player1]) - } -} diff --git a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemoTests/PlayerTests.swift b/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemoTests/PlayerTests.swift deleted file mode 100644 index 4262d80235..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemoTests/PlayerTests.swift +++ /dev/null @@ -1,108 +0,0 @@ -import XCTest -import GRDB -@testable import GRDBCombineDemo - -class PlayerTests: XCTestCase { - // MARK: - CRUD - // Test that our Player type properly talks to GRDB. - - func testInsert() throws { - // Given an empty players database - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - _ = try AppDatabase(dbQueue) - - // When we insert a player - var player = Player(id: nil, name: "Arthur", score: 100) - try dbQueue.write { db in - try player.insert(db) - } - - // Then the player gets a non-nil id - XCTAssertNotNil(player.id) - } - - func testRoundtrip() throws { - // Given an empty players database - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - _ = try AppDatabase(dbQueue) - - // When we insert a player and fetch the player with the same id - var insertedPlayer = Player(id: nil, name: "Arthur", score: 100) - let fetchedPlayer: Player? = try dbQueue.write { db in - try insertedPlayer.insert(db) - return try Player.fetchOne(db, key: insertedPlayer.id) - } - - // Then the fetched player is equal to the inserted player - XCTAssertEqual(insertedPlayer, fetchedPlayer) - } - - // MARK: - Requests - // Test that requests defined on the Player type behave as expected. - - func testOrderedByScore() throws { - // Given a players database that contains players with distinct scores - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - _ = try AppDatabase(dbQueue) - var player1 = Player(id: 1, name: "Arthur", score: 100) - var player2 = Player(id: 2, name: "Barbara", score: 200) - var player3 = Player(id: 3, name: "Craig", score: 150) - var player4 = Player(id: 4, name: "David", score: 120) - try dbQueue.write { db in - try player1.insert(db) - try player2.insert(db) - try player3.insert(db) - try player4.insert(db) - } - - // When we fetch players ordered by score - let players = try dbQueue.read(Player.all().orderedByScore().fetchAll) - - // Then fetched players are ordered by score descending - XCTAssertEqual(players, [player2, player3, player4, player1]) - } - - func testOrderedByScoreSortsIdenticalScoresByName() throws { - // Given a players database that contains players with common scores - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - _ = try AppDatabase(dbQueue) - var player1 = Player(id: 1, name: "Arthur", score: 100) - var player2 = Player(id: 2, name: "Barbara", score: 200) - var player3 = Player(id: 3, name: "Craig", score: 200) - var player4 = Player(id: 4, name: "David", score: 200) - try dbQueue.write { db in - try player1.insert(db) - try player2.insert(db) - try player3.insert(db) - try player4.insert(db) - } - - // When we fetch players ordered by score - let players = try dbQueue.read(Player.all().orderedByScore().fetchAll) - - // Then fetched players are ordered by score descending and by name - XCTAssertEqual(players, [player2, player3, player4, player1]) - } - - func testOrderedByName() throws { - // Given a players database that contains players with distinct names - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - _ = try AppDatabase(dbQueue) - var player1 = Player(id: 1, name: "Arthur", score: 100) - var player2 = Player(id: 2, name: "Barbara", score: 200) - var player3 = Player(id: 3, name: "Craig", score: 150) - var player4 = Player(id: 4, name: "David", score: 120) - try dbQueue.write { db in - try player1.insert(db) - try player2.insert(db) - try player3.insert(db) - try player4.insert(db) - } - - // When we fetch players ordered by name - let players = try dbQueue.read(Player.all().orderedByName().fetchAll) - - // Then fetched players are ordered by name - XCTAssertEqual(players, [player1, player2, player3, player4]) - } -} diff --git a/Documentation/DemoApps/GRDBCombineDemo/README.md b/Documentation/DemoApps/GRDBCombineDemo/README.md deleted file mode 100644 index 6b2ccec0f7..0000000000 --- a/Documentation/DemoApps/GRDBCombineDemo/README.md +++ /dev/null @@ -1,51 +0,0 @@ -Combine + SwiftUI Demo Application -================================== - - - -**This demo application is a Combine + SwiftUI application.** For a demo application that uses UIKit, see [GRDBDemoiOS](../GRDBDemoiOS/README.md), and for Async/Await + SwiftUI, see [GRDBAsyncDemo](../GRDBAsyncDemo/README.md). - -**Requirements**: iOS 15.0+ / Xcode 12+ - -> **Note**: This demo app is not a project template. Do not copy it as a starting point for your application. Instead, create a new project, choose a GRDB [installation method](../../../README.md#installation), and use the demo as an inspiration. - -The topics covered in this demo are: - -- How to setup a database in an iOS app. -- How to define a simple [Codable Record](../../../README.md#codable-records). -- How to track database changes and animate a SwiftUI List with [ValueObservation](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/valueobservation) Combine publishers. -- How to apply the recommendations of [Recommended Practices for Designing Record Types](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/recordrecommendedpractices). -- How to feed SwiftUI previews with a transient database. - -**Files of interest:** - -- [GRDBCombineDemoApp.swift](GRDBCombineDemo/GRDBCombineDemoApp.swift) - - `GRDBCombineDemoApp` feeds the app views with a database, through the SwiftUI environment. - -- [AppDatabase.swift](GRDBCombineDemo/AppDatabase.swift) - - `AppDatabase` is the type that grants database access. It uses [DatabaseMigrator](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databasemigrator) in order to setup the database schema. - -- [Persistence.swift](GRDBCombineDemo/Persistence.swift) - - This file instantiates various `AppDatabase` for the various projects needs: one database on disk for the application, and in-memory databases for SwiftUI previews. - -- [Player.swift](GRDBCombineDemo/Player.swift) - - `Player` is a [Record](../../../README.md#records) type, able to read and write in the database. It conforms to the standard Codable protocol in order to gain all advantages of [Codable Records](../../../README.md#codable-records). - -- [PlayerRequest.swift](GRDBCombineDemo/PlayerRequest.swift), [AppView.swift](GRDBCombineDemo/Views/AppView.swift) - - `PlayerRequest` defines the player requests used by the app (sorted by score, or by name). - - `PlayerRequest` feeds the `@Query` property wrapper (`@Query`, defined in [GRDBQuery](https://github.com/groue/GRDBQuery), allows SwiftUI views to display up-to-date database content). - - `AppView` is the SwiftUI view that uses `@Query` in order to feed its player list. - -- [GRDBCombineDemoTests](GRDBCombineDemoTests) - - - Test the database schema - - Test the `Player` record and its requests - - Test the `PlayerRequest` methods that feed the list of players. - - Test the `AppDatabase` methods that let the app access the database. diff --git a/Documentation/DemoApps/GRDBCombineDemo/Screenshot.png b/Documentation/DemoApps/GRDBCombineDemo/Screenshot.png deleted file mode 100644 index 0536821854..0000000000 Binary files a/Documentation/DemoApps/GRDBCombineDemo/Screenshot.png and /dev/null differ diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemo.xcodeproj/project.pbxproj b/Documentation/DemoApps/GRDBDemo/GRDBDemo.xcodeproj/project.pbxproj similarity index 96% rename from Documentation/DemoApps2/GRDBDemo/GRDBDemo.xcodeproj/project.pbxproj rename to Documentation/DemoApps/GRDBDemo/GRDBDemo.xcodeproj/project.pbxproj index de05422b4d..47782e0625 100644 --- a/Documentation/DemoApps2/GRDBDemo/GRDBDemo.xcodeproj/project.pbxproj +++ b/Documentation/DemoApps/GRDBDemo/GRDBDemo.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 56CFC6772C9F1E1B000B5023 /* GRDB in Frameworks */ = {isa = PBXBuildFile; productRef = 56CFC6762C9F1E1B000B5023 /* GRDB */; }; + 56CFC6E42C9F5AEA000B5023 /* GRDB in Frameworks */ = {isa = PBXBuildFile; productRef = 56CFC6E32C9F5AEA000B5023 /* GRDB */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -65,6 +66,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 56CFC6E42C9F5AEA000B5023 /* GRDB in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -77,6 +79,7 @@ 56CFC6B82C9F544D000B5023 /* README.md */, 56CFC6462C9F1DC9000B5023 /* GRDBDemo */, 56CFC6572C9F1DCA000B5023 /* GRDBDemoTests */, + 56CFC6E22C9F5AEA000B5023 /* Frameworks */, 56CFC6452C9F1DC9000B5023 /* Products */, ); sourceTree = ""; @@ -90,6 +93,13 @@ name = Products; sourceTree = ""; }; + 56CFC6E22C9F5AEA000B5023 /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -134,6 +144,7 @@ ); name = GRDBDemoTests; packageProductDependencies = ( + 56CFC6E32C9F5AEA000B5023 /* GRDB */, ); productName = GRDBDemoTests; productReference = 56CFC6542C9F1DCA000B5023 /* GRDBDemoTests.xctest */; @@ -481,6 +492,11 @@ isa = XCSwiftPackageProductDependency; productName = GRDB; }; + 56CFC6E32C9F5AEA000B5023 /* GRDB */ = { + isa = XCSwiftPackageProductDependency; + package = 56CFC6752C9F1E1B000B5023 /* XCLocalSwiftPackageReference "../../../../GRDB.swift" */; + productName = GRDB; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 56CFC63C2C9F1DC9000B5023 /* Project object */; diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Documentation/DemoApps/GRDBDemo/GRDBDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to Documentation/DemoApps/GRDBDemo/GRDBDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS.xcodeproj/xcshareddata/xcschemes/GRDBDemoiOS.xcscheme b/Documentation/DemoApps/GRDBDemo/GRDBDemo.xcodeproj/xcshareddata/xcschemes/GRDBDemo.xcscheme similarity index 65% rename from Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS.xcodeproj/xcshareddata/xcschemes/GRDBDemoiOS.xcscheme rename to Documentation/DemoApps/GRDBDemo/GRDBDemo.xcodeproj/xcshareddata/xcschemes/GRDBDemo.xcscheme index 20c4615d25..7151d8104b 100644 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS.xcodeproj/xcshareddata/xcschemes/GRDBDemoiOS.xcscheme +++ b/Documentation/DemoApps/GRDBDemo/GRDBDemo.xcodeproj/xcshareddata/xcschemes/GRDBDemo.xcscheme @@ -1,10 +1,11 @@ + LastUpgradeVersion = "1600" + version = "1.7"> + buildImplicitDependencies = "YES" + buildArchitectures = "Automatic"> + BlueprintIdentifier = "56CFC6432C9F1DC9000B5023" + BuildableName = "GRDBDemo.app" + BlueprintName = "GRDBDemo" + ReferencedContainer = "container:GRDBDemo.xcodeproj"> @@ -26,17 +27,18 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES"> + shouldUseLaunchSchemeArgsEnv = "YES" + shouldAutocreateTestPlan = "YES"> + BlueprintIdentifier = "56CFC6532C9F1DCA000B5023" + BuildableName = "GRDBDemoTests.xctest" + BlueprintName = "GRDBDemoTests" + ReferencedContainer = "container:GRDBDemo.xcodeproj"> @@ -55,19 +57,12 @@ runnableDebuggingMode = "0"> + BlueprintIdentifier = "56CFC6432C9F1DC9000B5023" + BuildableName = "GRDBDemo.app" + BlueprintName = "GRDBDemo" + ReferencedContainer = "container:GRDBDemo.xcodeproj"> - - - - + BlueprintIdentifier = "56CFC6432C9F1DC9000B5023" + BuildableName = "GRDBDemo.app" + BlueprintName = "GRDBDemo" + ReferencedContainer = "container:GRDBDemo.xcodeproj"> diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Database/AppDatabase.swift b/Documentation/DemoApps/GRDBDemo/GRDBDemo/Database/AppDatabase.swift similarity index 100% rename from Documentation/DemoApps2/GRDBDemo/GRDBDemo/Database/AppDatabase.swift rename to Documentation/DemoApps/GRDBDemo/GRDBDemo/Database/AppDatabase.swift diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Database/Models/Player.swift b/Documentation/DemoApps/GRDBDemo/GRDBDemo/Database/Models/Player.swift similarity index 100% rename from Documentation/DemoApps2/GRDBDemo/GRDBDemo/Database/Models/Player.swift rename to Documentation/DemoApps/GRDBDemo/GRDBDemo/Database/Models/Player.swift diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Database/Persistence.swift b/Documentation/DemoApps/GRDBDemo/GRDBDemo/Database/Persistence.swift similarity index 100% rename from Documentation/DemoApps2/GRDBDemo/GRDBDemo/Database/Persistence.swift rename to Documentation/DemoApps/GRDBDemo/GRDBDemo/Database/Persistence.swift diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/GRDBDemoApp.swift b/Documentation/DemoApps/GRDBDemo/GRDBDemo/GRDBDemoApp.swift similarity index 100% rename from Documentation/DemoApps2/GRDBDemo/GRDBDemo/GRDBDemoApp.swift rename to Documentation/DemoApps/GRDBDemo/GRDBDemo/GRDBDemoApp.swift diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Info.plist b/Documentation/DemoApps/GRDBDemo/GRDBDemo/Info.plist similarity index 100% rename from Documentation/DemoApps2/GRDBDemo/GRDBDemo/Info.plist rename to Documentation/DemoApps/GRDBDemo/GRDBDemo/Info.plist diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Preview Content/Preview Assets.xcassets/Contents.json b/Documentation/DemoApps/GRDBDemo/GRDBDemo/Preview Content/Preview Assets.xcassets/Contents.json similarity index 100% rename from Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Preview Content/Preview Assets.xcassets/Contents.json rename to Documentation/DemoApps/GRDBDemo/GRDBDemo/Preview Content/Preview Assets.xcassets/Contents.json diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AccentColor.colorset/Contents.json b/Documentation/DemoApps/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/AccentColor.colorset/Contents.json rename to Documentation/DemoApps/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json b/Documentation/DemoApps/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from Documentation/DemoApps2/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json rename to Documentation/DemoApps/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git "a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/AppIcon.appiconset/Icon-Dark-1024\303\2271024.png" "b/Documentation/DemoApps/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/AppIcon.appiconset/Icon-Dark-1024\303\2271024.png" similarity index 100% rename from "Documentation/DemoApps2/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/AppIcon.appiconset/Icon-Dark-1024\303\2271024.png" rename to "Documentation/DemoApps/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/AppIcon.appiconset/Icon-Dark-1024\303\2271024.png" diff --git "a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/AppIcon.appiconset/Icon-Light-1024\303\2271024.png" "b/Documentation/DemoApps/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/AppIcon.appiconset/Icon-Light-1024\303\2271024.png" similarity index 100% rename from "Documentation/DemoApps2/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/AppIcon.appiconset/Icon-Light-1024\303\2271024.png" rename to "Documentation/DemoApps/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/AppIcon.appiconset/Icon-Light-1024\303\2271024.png" diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/Contents.json b/Documentation/DemoApps/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/Contents.json similarity index 100% rename from Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/Contents.json rename to Documentation/DemoApps/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/Contents.json diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/LaunchScreen.imageset/Contents.json b/Documentation/DemoApps/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/LaunchScreen.imageset/Contents.json similarity index 100% rename from Documentation/DemoApps2/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/LaunchScreen.imageset/Contents.json rename to Documentation/DemoApps/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/LaunchScreen.imageset/Contents.json diff --git a/Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/LaunchIcon.imageset/LaunchIcon.pdf b/Documentation/DemoApps/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/LaunchScreen.imageset/LaunchIcon.pdf similarity index 100% rename from Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo/Resources/Assets.xcassets/LaunchIcon.imageset/LaunchIcon.pdf rename to Documentation/DemoApps/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/LaunchScreen.imageset/LaunchIcon.pdf diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/LaunchScreen.imageset/LaunchIcon~Dark.pdf b/Documentation/DemoApps/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/LaunchScreen.imageset/LaunchIcon~Dark.pdf similarity index 100% rename from Documentation/DemoApps2/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/LaunchScreen.imageset/LaunchIcon~Dark.pdf rename to Documentation/DemoApps/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/LaunchScreen.imageset/LaunchIcon~Dark.pdf diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Resources/Localizable.xcstrings b/Documentation/DemoApps/GRDBDemo/GRDBDemo/Resources/Localizable.xcstrings similarity index 100% rename from Documentation/DemoApps2/GRDBDemo/GRDBDemo/Resources/Localizable.xcstrings rename to Documentation/DemoApps/GRDBDemo/GRDBDemo/Resources/Localizable.xcstrings diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Views/PlayerCreationSheet.swift b/Documentation/DemoApps/GRDBDemo/GRDBDemo/Views/PlayerCreationSheet.swift similarity index 100% rename from Documentation/DemoApps2/GRDBDemo/GRDBDemo/Views/PlayerCreationSheet.swift rename to Documentation/DemoApps/GRDBDemo/GRDBDemo/Views/PlayerCreationSheet.swift diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Views/PlayerEditionView.swift b/Documentation/DemoApps/GRDBDemo/GRDBDemo/Views/PlayerEditionView.swift similarity index 100% rename from Documentation/DemoApps2/GRDBDemo/GRDBDemo/Views/PlayerEditionView.swift rename to Documentation/DemoApps/GRDBDemo/GRDBDemo/Views/PlayerEditionView.swift diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Views/PlayerFormView.swift b/Documentation/DemoApps/GRDBDemo/GRDBDemo/Views/PlayerFormView.swift similarity index 100% rename from Documentation/DemoApps2/GRDBDemo/GRDBDemo/Views/PlayerFormView.swift rename to Documentation/DemoApps/GRDBDemo/GRDBDemo/Views/PlayerFormView.swift diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Views/PlayerListModel.swift b/Documentation/DemoApps/GRDBDemo/GRDBDemo/Views/PlayerListModel.swift similarity index 100% rename from Documentation/DemoApps2/GRDBDemo/GRDBDemo/Views/PlayerListModel.swift rename to Documentation/DemoApps/GRDBDemo/GRDBDemo/Views/PlayerListModel.swift diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Views/PlayerListView.swift b/Documentation/DemoApps/GRDBDemo/GRDBDemo/Views/PlayerListView.swift similarity index 100% rename from Documentation/DemoApps2/GRDBDemo/GRDBDemo/Views/PlayerListView.swift rename to Documentation/DemoApps/GRDBDemo/GRDBDemo/Views/PlayerListView.swift diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Views/PlayerNavigationView.swift b/Documentation/DemoApps/GRDBDemo/GRDBDemo/Views/PlayerNavigationView.swift similarity index 100% rename from Documentation/DemoApps2/GRDBDemo/GRDBDemo/Views/PlayerNavigationView.swift rename to Documentation/DemoApps/GRDBDemo/GRDBDemo/Views/PlayerNavigationView.swift diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemoTests/AppDatabaseTests.swift b/Documentation/DemoApps/GRDBDemo/GRDBDemoTests/AppDatabaseTests.swift similarity index 100% rename from Documentation/DemoApps2/GRDBDemo/GRDBDemoTests/AppDatabaseTests.swift rename to Documentation/DemoApps/GRDBDemo/GRDBDemoTests/AppDatabaseTests.swift diff --git a/Documentation/DemoApps2/GRDBDemo/README.md b/Documentation/DemoApps/GRDBDemo/README.md similarity index 100% rename from Documentation/DemoApps2/GRDBDemo/README.md rename to Documentation/DemoApps/GRDBDemo/README.md diff --git a/Documentation/DemoApps2/GRDBDemo/Screenshot.png b/Documentation/DemoApps/GRDBDemo/Screenshot.png similarity index 100% rename from Documentation/DemoApps2/GRDBDemo/Screenshot.png rename to Documentation/DemoApps/GRDBDemo/Screenshot.png diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/Assets.xcassets/Complication.complicationset/Circular.imageset/Contents.json b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/Assets.xcassets/Complication.complicationset/Circular.imageset/Contents.json deleted file mode 100644 index 9be9adbf7d..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/Assets.xcassets/Complication.complicationset/Circular.imageset/Contents.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "images" : [ - { - "idiom" : "watch", - "screenWidth" : "{130,145}", - "scale" : "2x" - }, - { - "idiom" : "watch", - "screenWidth" : "{146,165}", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/Assets.xcassets/Complication.complicationset/Contents.json b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/Assets.xcassets/Complication.complicationset/Contents.json deleted file mode 100644 index 2eca9a1f46..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/Assets.xcassets/Complication.complicationset/Contents.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "assets" : [ - { - "idiom" : "watch", - "filename" : "Circular.imageset", - "role" : "circular" - }, - { - "idiom" : "watch", - "filename" : "Extra Large.imageset", - "role" : "extra-large" - }, - { - "idiom" : "watch", - "filename" : "Modular.imageset", - "role" : "modular" - }, - { - "idiom" : "watch", - "filename" : "Utilitarian.imageset", - "role" : "utilitarian" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/Assets.xcassets/Complication.complicationset/Extra Large.imageset/Contents.json b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/Assets.xcassets/Complication.complicationset/Extra Large.imageset/Contents.json deleted file mode 100644 index 9be9adbf7d..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/Assets.xcassets/Complication.complicationset/Extra Large.imageset/Contents.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "images" : [ - { - "idiom" : "watch", - "screenWidth" : "{130,145}", - "scale" : "2x" - }, - { - "idiom" : "watch", - "screenWidth" : "{146,165}", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Contents.json b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Contents.json deleted file mode 100644 index 9be9adbf7d..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Contents.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "images" : [ - { - "idiom" : "watch", - "screenWidth" : "{130,145}", - "scale" : "2x" - }, - { - "idiom" : "watch", - "screenWidth" : "{146,165}", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Contents.json b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Contents.json deleted file mode 100644 index 9be9adbf7d..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Contents.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "images" : [ - { - "idiom" : "watch", - "screenWidth" : "{130,145}", - "scale" : "2x" - }, - { - "idiom" : "watch", - "screenWidth" : "{146,165}", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/ExtensionDelegate.swift b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/ExtensionDelegate.swift deleted file mode 100644 index 320f84a6b2..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/ExtensionDelegate.swift +++ /dev/null @@ -1,48 +0,0 @@ -import WatchKit - -class ExtensionDelegate: NSObject, WKExtensionDelegate { - - func applicationDidFinishLaunching() { - // Perform any final initialization of your application. - } - - func applicationDidBecomeActive() { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. - } - - func applicationWillResignActive() { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, etc. - } - - func handle(_ backgroundTasks: Set) { - // Sent when the system needs to launch the application in the background to process tasks. Tasks arrive in a set, so loop through and process each one. - for task in backgroundTasks { - // Use a switch statement to check the task type - switch task { - case let backgroundTask as WKApplicationRefreshBackgroundTask: - // Be sure to complete the background task once you’re done. - backgroundTask.setTaskCompletedWithSnapshot(false) - case let snapshotTask as WKSnapshotRefreshBackgroundTask: - // Snapshot tasks have a unique completion call, make sure to set your expiration date - snapshotTask.setTaskCompleted(restoredDefaultState: true, estimatedSnapshotExpiration: Date.distantFuture, userInfo: nil) - case let connectivityTask as WKWatchConnectivityRefreshBackgroundTask: - // Be sure to complete the connectivity task once you’re done. - connectivityTask.setTaskCompletedWithSnapshot(false) - case let urlSessionTask as WKURLSessionRefreshBackgroundTask: - // Be sure to complete the URL session task once you’re done. - urlSessionTask.setTaskCompletedWithSnapshot(false) - case let relevantShortcutTask as WKRelevantShortcutRefreshBackgroundTask: - // Be sure to complete the relevant-shortcut task once you're done. - relevantShortcutTask.setTaskCompletedWithSnapshot(false) - case let intentDidRunTask as WKIntentDidRunRefreshBackgroundTask: - // Be sure to complete the intent-did-run task once you're done. - intentDidRunTask.setTaskCompletedWithSnapshot(false) - default: - // make sure to complete unhandled task types - task.setTaskCompletedWithSnapshot(false) - } - } - } - -} diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/Info.plist b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/Info.plist deleted file mode 100644 index 0881b8b30e..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/Info.plist +++ /dev/null @@ -1,36 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - GRDBDemoWatchOS Extension - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - XPC! - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - NSExtension - - NSExtensionAttributes - - WKAppBundleIdentifier - com.github.groue.GRDBDemoiOS2.watchkitapp - - NSExtensionPointIdentifier - com.apple.watchkit - - WKExtensionDelegateClassName - $(PRODUCT_MODULE_NAME).ExtensionDelegate - - diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/InterfaceController.swift b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/InterfaceController.swift deleted file mode 100644 index a116db10fa..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS Extension/InterfaceController.swift +++ /dev/null @@ -1,16 +0,0 @@ -import WatchKit -import Foundation -import GRDB -import SQLite3 - -class InterfaceController: WKInterfaceController { - - @IBOutlet var versionLabel: WKInterfaceLabel! - - override func awake(withContext context: Any?) { - super.awake(withContext: context) - - let sqliteVersion = String(cString: sqlite3_libversion(), encoding: .utf8) - versionLabel.setText(sqliteVersion) - } -} diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS/Assets.xcassets/AppIcon.appiconset/Contents.json b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index dd221ba54d..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "images" : [ - { - "size" : "24x24", - "idiom" : "watch", - "scale" : "2x", - "role" : "notificationCenter", - "subtype" : "38mm" - }, - { - "size" : "27.5x27.5", - "idiom" : "watch", - "scale" : "2x", - "role" : "notificationCenter", - "subtype" : "42mm" - }, - { - "size" : "29x29", - "idiom" : "watch", - "role" : "companionSettings", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "watch", - "role" : "companionSettings", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "watch", - "scale" : "2x", - "role" : "appLauncher", - "subtype" : "38mm" - }, - { - "size" : "86x86", - "idiom" : "watch", - "scale" : "2x", - "role" : "quickLook", - "subtype" : "38mm" - }, - { - "size" : "98x98", - "idiom" : "watch", - "scale" : "2x", - "role" : "quickLook", - "subtype" : "42mm" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS/Base.lproj/Interface.storyboard b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS/Base.lproj/Interface.storyboard deleted file mode 100644 index 4988b4b688..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS/Base.lproj/Interface.storyboard +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS/Info.plist b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS/Info.plist deleted file mode 100644 index 0478fa15f8..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoWatchOS/Info.plist +++ /dev/null @@ -1,33 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - GRDBDemoiOS - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - - WKCompanionAppBundleIdentifier - com.github.groue.GRDBDemoiOS2 - WKWatchKitApp - - - diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS.xcodeproj/project.pbxproj b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS.xcodeproj/project.pbxproj deleted file mode 100644 index 827e5c560c..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS.xcodeproj/project.pbxproj +++ /dev/null @@ -1,912 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 54; - objects = { - -/* Begin PBXBuildFile section */ - 56185BBF25B8036100B9C30F /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56185BBE25B8036100B9C30F /* Persistence.swift */; }; - 56185BF325B80B8900B9C30F /* AppDatabaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56185BF225B80B8900B9C30F /* AppDatabaseTests.swift */; }; - 56185C0725B80CEC00B9C30F /* PlayerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56185C0625B80CEC00B9C30F /* PlayerTests.swift */; }; - 567940C528BA33D2004A0298 /* GRDB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 56606D0A2355931F00185962 /* GRDB.framework */; }; - 567940C628BA33D2004A0298 /* GRDB.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 56606D0A2355931F00185962 /* GRDB.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 567940C728BA33DE004A0298 /* GRDB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 56606D0A2355931F00185962 /* GRDB.framework */; }; - 567940C828BA33DE004A0298 /* GRDB.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 56606D0A2355931F00185962 /* GRDB.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 568E5FC31E926430002582E0 /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 568E5FC11E926430002582E0 /* Interface.storyboard */; }; - 568E5FC51E926430002582E0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 568E5FC41E926430002582E0 /* Assets.xcassets */; }; - 568E5FCC1E926430002582E0 /* GRDBDemoWatchOS Extension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 568E5FCB1E926430002582E0 /* GRDBDemoWatchOS Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 568E5FD11E926430002582E0 /* InterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 568E5FD01E926430002582E0 /* InterfaceController.swift */; }; - 568E5FD31E926430002582E0 /* ExtensionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 568E5FD21E926430002582E0 /* ExtensionDelegate.swift */; }; - 568E5FD51E926430002582E0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 568E5FD41E926430002582E0 /* Assets.xcassets */; }; - 568E5FD91E926430002582E0 /* GRDBDemoWatchOS.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 568E5FBF1E926430002582E0 /* GRDBDemoWatchOS.app */; }; - 56B036071E8D9EBE003B6DA4 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B036061E8D9EBE003B6DA4 /* AppDelegate.swift */; }; - 56B0360C1E8D9EBE003B6DA4 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 56B0360A1E8D9EBE003B6DA4 /* Main.storyboard */; }; - 56B0360E1E8D9EBE003B6DA4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 56B0360D1E8D9EBE003B6DA4 /* Assets.xcassets */; }; - 56B036111E8D9EBE003B6DA4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 56B0360F1E8D9EBE003B6DA4 /* LaunchScreen.storyboard */; }; - 56B0361B1E8D9F38003B6DA4 /* AppDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B036191E8D9F38003B6DA4 /* AppDatabase.swift */; }; - 56B0361C1E8D9F38003B6DA4 /* Player.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B0361A1E8D9F38003B6DA4 /* Player.swift */; }; - 56B036231E8D9F4C003B6DA4 /* PlayerEditionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B0361F1E8D9F4C003B6DA4 /* PlayerEditionViewController.swift */; }; - 56B036241E8D9F4C003B6DA4 /* PlayerListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B036201E8D9F4C003B6DA4 /* PlayerListViewController.swift */; }; - 56FE6F2624A90CE400711EDF /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56FE6F2524A90CE400711EDF /* SceneDelegate.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 56185BF525B80B8900B9C30F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 56B035FB1E8D9EBE003B6DA4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 56B036021E8D9EBE003B6DA4; - remoteInfo = GRDBDemoiOS; - }; - 5642252F29A2390800D714BF /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 56B036261E8D9F79003B6DA4 /* GRDB.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = DC3773F219C8CBB3004FCF85; - remoteInfo = GRDB; - }; - 5642253329A2391900D714BF /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 56B036261E8D9F79003B6DA4 /* GRDB.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = DC3773F219C8CBB3004FCF85; - remoteInfo = GRDB; - }; - 56606D092355931F00185962 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 56B036261E8D9F79003B6DA4 /* GRDB.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = DC3773F319C8CBB3004FCF85; - remoteInfo = GRDBOSX; - }; - 56606D0B2355931F00185962 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 56B036261E8D9F79003B6DA4 /* GRDB.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 56E5D7F91B4D422D00430942; - remoteInfo = GRDBOSXTests; - }; - 568E5FCD1E926430002582E0 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 56B035FB1E8D9EBE003B6DA4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 568E5FCA1E926430002582E0; - remoteInfo = "GRDBDemoWatchOS Extension"; - }; - 568E5FD71E926430002582E0 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 56B035FB1E8D9EBE003B6DA4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 568E5FBE1E926430002582E0; - remoteInfo = GRDBDemoWatchOS; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 568E5FDD1E926430002582E0 /* Embed Foundation Extensions */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 13; - files = ( - 568E5FCC1E926430002582E0 /* GRDBDemoWatchOS Extension.appex in Embed Foundation Extensions */, - ); - name = "Embed Foundation Extensions"; - runOnlyForDeploymentPostprocessing = 0; - }; - 568E5FE11E926430002582E0 /* Embed Watch Content */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "$(CONTENTS_FOLDER_PATH)/Watch"; - dstSubfolderSpec = 16; - files = ( - 568E5FD91E926430002582E0 /* GRDBDemoWatchOS.app in Embed Watch Content */, - ); - name = "Embed Watch Content"; - runOnlyForDeploymentPostprocessing = 0; - }; - 568E5FE81E926547002582E0 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 567940C828BA33DE004A0298 /* GRDB.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; - 56B036621E8D9FB1003B6DA4 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 567940C628BA33D2004A0298 /* GRDB.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 56185BBE25B8036100B9C30F /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = ""; }; - 56185BF025B80B8900B9C30F /* GRDBDemoiOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GRDBDemoiOSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 56185BF225B80B8900B9C30F /* AppDatabaseTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDatabaseTests.swift; sourceTree = ""; }; - 56185BF425B80B8900B9C30F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 56185C0625B80CEC00B9C30F /* PlayerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerTests.swift; sourceTree = ""; }; - 568E5FBF1E926430002582E0 /* GRDBDemoWatchOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GRDBDemoWatchOS.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 568E5FC21E926430002582E0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Interface.storyboard; sourceTree = ""; }; - 568E5FC41E926430002582E0 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 568E5FC61E926430002582E0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 568E5FCB1E926430002582E0 /* GRDBDemoWatchOS Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "GRDBDemoWatchOS Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; - 568E5FD01E926430002582E0 /* InterfaceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InterfaceController.swift; sourceTree = ""; }; - 568E5FD21E926430002582E0 /* ExtensionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionDelegate.swift; sourceTree = ""; }; - 568E5FD41E926430002582E0 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 568E5FD61E926430002582E0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 56B036031E8D9EBE003B6DA4 /* GRDBDemoiOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GRDBDemoiOS.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 56B036061E8D9EBE003B6DA4 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 56B0360B1E8D9EBE003B6DA4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 56B0360D1E8D9EBE003B6DA4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 56B036101E8D9EBE003B6DA4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 56B036121E8D9EBE003B6DA4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 56B036191E8D9F38003B6DA4 /* AppDatabase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDatabase.swift; sourceTree = ""; }; - 56B0361A1E8D9F38003B6DA4 /* Player.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Player.swift; sourceTree = ""; }; - 56B0361F1E8D9F4C003B6DA4 /* PlayerEditionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlayerEditionViewController.swift; sourceTree = ""; }; - 56B036201E8D9F4C003B6DA4 /* PlayerListViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlayerListViewController.swift; sourceTree = ""; }; - 56B036261E8D9F79003B6DA4 /* GRDB.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = GRDB.xcodeproj; path = ../../../GRDB.xcodeproj; sourceTree = ""; }; - 56FE6F2524A90CE400711EDF /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 56185BED25B80B8900B9C30F /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 568E5FC81E926430002582E0 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 567940C728BA33DE004A0298 /* GRDB.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 56B036001E8D9EBE003B6DA4 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 567940C528BA33D2004A0298 /* GRDB.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 56185BF125B80B8900B9C30F /* GRDBDemoiOSTests */ = { - isa = PBXGroup; - children = ( - 56185BF425B80B8900B9C30F /* Info.plist */, - 56185BF225B80B8900B9C30F /* AppDatabaseTests.swift */, - 56185C0625B80CEC00B9C30F /* PlayerTests.swift */, - ); - path = GRDBDemoiOSTests; - sourceTree = ""; - }; - 56606CFD2355931F00185962 /* Products */ = { - isa = PBXGroup; - children = ( - 56606D0A2355931F00185962 /* GRDB.framework */, - 56606D0C2355931F00185962 /* GRDBTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 56606D1F2355938A00185962 /* Frameworks */ = { - isa = PBXGroup; - children = ( - ); - name = Frameworks; - sourceTree = ""; - }; - 568E5FC01E926430002582E0 /* GRDBDemoWatchOS */ = { - isa = PBXGroup; - children = ( - 568E5FC11E926430002582E0 /* Interface.storyboard */, - 568E5FC41E926430002582E0 /* Assets.xcassets */, - 568E5FC61E926430002582E0 /* Info.plist */, - ); - path = GRDBDemoWatchOS; - sourceTree = ""; - }; - 568E5FCF1E926430002582E0 /* GRDBDemoWatchOS Extension */ = { - isa = PBXGroup; - children = ( - 568E5FD01E926430002582E0 /* InterfaceController.swift */, - 568E5FD21E926430002582E0 /* ExtensionDelegate.swift */, - 568E5FD41E926430002582E0 /* Assets.xcassets */, - 568E5FD61E926430002582E0 /* Info.plist */, - ); - path = "GRDBDemoWatchOS Extension"; - sourceTree = ""; - }; - 56B035FA1E8D9EBE003B6DA4 = { - isa = PBXGroup; - children = ( - 56B036261E8D9F79003B6DA4 /* GRDB.xcodeproj */, - 56B036051E8D9EBE003B6DA4 /* GRDBDemoiOS */, - 568E5FC01E926430002582E0 /* GRDBDemoWatchOS */, - 568E5FCF1E926430002582E0 /* GRDBDemoWatchOS Extension */, - 56185BF125B80B8900B9C30F /* GRDBDemoiOSTests */, - 56B036041E8D9EBE003B6DA4 /* Products */, - 56606D1F2355938A00185962 /* Frameworks */, - ); - sourceTree = ""; - }; - 56B036041E8D9EBE003B6DA4 /* Products */ = { - isa = PBXGroup; - children = ( - 56B036031E8D9EBE003B6DA4 /* GRDBDemoiOS.app */, - 568E5FBF1E926430002582E0 /* GRDBDemoWatchOS.app */, - 568E5FCB1E926430002582E0 /* GRDBDemoWatchOS Extension.appex */, - 56185BF025B80B8900B9C30F /* GRDBDemoiOSTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 56B036051E8D9EBE003B6DA4 /* GRDBDemoiOS */ = { - isa = PBXGroup; - children = ( - 56B036121E8D9EBE003B6DA4 /* Info.plist */, - 56B036191E8D9F38003B6DA4 /* AppDatabase.swift */, - 56B036061E8D9EBE003B6DA4 /* AppDelegate.swift */, - 56185BBE25B8036100B9C30F /* Persistence.swift */, - 56B0361A1E8D9F38003B6DA4 /* Player.swift */, - 56FE6F2524A90CE400711EDF /* SceneDelegate.swift */, - 56FE6F4E24A9112900711EDF /* Resources */, - 56FE6F4F24A9114200711EDF /* ViewControllers */, - ); - path = GRDBDemoiOS; - sourceTree = ""; - }; - 56FE6F4E24A9112900711EDF /* Resources */ = { - isa = PBXGroup; - children = ( - 56B0360D1E8D9EBE003B6DA4 /* Assets.xcassets */, - 56B0360F1E8D9EBE003B6DA4 /* LaunchScreen.storyboard */, - 56B0360A1E8D9EBE003B6DA4 /* Main.storyboard */, - ); - path = Resources; - sourceTree = ""; - }; - 56FE6F4F24A9114200711EDF /* ViewControllers */ = { - isa = PBXGroup; - children = ( - 56B0361F1E8D9F4C003B6DA4 /* PlayerEditionViewController.swift */, - 56B036201E8D9F4C003B6DA4 /* PlayerListViewController.swift */, - ); - path = ViewControllers; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 56185BEF25B80B8900B9C30F /* GRDBDemoiOSTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 56185BFF25B80B8900B9C30F /* Build configuration list for PBXNativeTarget "GRDBDemoiOSTests" */; - buildPhases = ( - 56185BEC25B80B8900B9C30F /* Sources */, - 56185BED25B80B8900B9C30F /* Frameworks */, - 56185BEE25B80B8900B9C30F /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 56185BF625B80B8900B9C30F /* PBXTargetDependency */, - ); - name = GRDBDemoiOSTests; - productName = GRDBDemoiOSTests; - productReference = 56185BF025B80B8900B9C30F /* GRDBDemoiOSTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 568E5FBE1E926430002582E0 /* GRDBDemoWatchOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 568E5FDE1E926430002582E0 /* Build configuration list for PBXNativeTarget "GRDBDemoWatchOS" */; - buildPhases = ( - 568E5FBD1E926430002582E0 /* Resources */, - 568E5FDD1E926430002582E0 /* Embed Foundation Extensions */, - ); - buildRules = ( - ); - dependencies = ( - 568E5FCE1E926430002582E0 /* PBXTargetDependency */, - ); - name = GRDBDemoWatchOS; - productName = GRDBDemoWatchOS; - productReference = 568E5FBF1E926430002582E0 /* GRDBDemoWatchOS.app */; - productType = "com.apple.product-type.application.watchapp2"; - }; - 568E5FCA1E926430002582E0 /* GRDBDemoWatchOS Extension */ = { - isa = PBXNativeTarget; - buildConfigurationList = 568E5FDA1E926430002582E0 /* Build configuration list for PBXNativeTarget "GRDBDemoWatchOS Extension" */; - buildPhases = ( - 568E5FC71E926430002582E0 /* Sources */, - 568E5FC81E926430002582E0 /* Frameworks */, - 568E5FC91E926430002582E0 /* Resources */, - 568E5FE81E926547002582E0 /* Embed Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 5642253429A2391900D714BF /* PBXTargetDependency */, - ); - name = "GRDBDemoWatchOS Extension"; - productName = "GRDBDemoWatchOS Extension"; - productReference = 568E5FCB1E926430002582E0 /* GRDBDemoWatchOS Extension.appex */; - productType = "com.apple.product-type.watchkit2-extension"; - }; - 56B036021E8D9EBE003B6DA4 /* GRDBDemoiOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 56B036151E8D9EBE003B6DA4 /* Build configuration list for PBXNativeTarget "GRDBDemoiOS" */; - buildPhases = ( - 56B035FF1E8D9EBE003B6DA4 /* Sources */, - 56B036001E8D9EBE003B6DA4 /* Frameworks */, - 56B036011E8D9EBE003B6DA4 /* Resources */, - 56B036621E8D9FB1003B6DA4 /* Embed Frameworks */, - 568E5FE11E926430002582E0 /* Embed Watch Content */, - ); - buildRules = ( - ); - dependencies = ( - 5642253029A2390800D714BF /* PBXTargetDependency */, - 568E5FD81E926430002582E0 /* PBXTargetDependency */, - ); - name = GRDBDemoiOS; - productName = GRDBDemoiOS; - productReference = 56B036031E8D9EBE003B6DA4 /* GRDBDemoiOS.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 56B035FB1E8D9EBE003B6DA4 /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 1230; - LastUpgradeCheck = 1400; - ORGANIZATIONNAME = "Gwendal Roué"; - TargetAttributes = { - 56185BEF25B80B8900B9C30F = { - CreatedOnToolsVersion = 12.3; - DevelopmentTeam = AMD8W895CT; - ProvisioningStyle = Automatic; - TestTargetID = 56B036021E8D9EBE003B6DA4; - }; - 568E5FBE1E926430002582E0 = { - CreatedOnToolsVersion = 8.3; - DevelopmentTeam = AMD8W895CT; - ProvisioningStyle = Automatic; - }; - 568E5FCA1E926430002582E0 = { - CreatedOnToolsVersion = 8.3; - DevelopmentTeam = AMD8W895CT; - LastSwiftMigration = 1020; - ProvisioningStyle = Automatic; - }; - 56B036021E8D9EBE003B6DA4 = { - CreatedOnToolsVersion = 8.3; - DevelopmentTeam = AMD8W895CT; - LastSwiftMigration = 1020; - ProvisioningStyle = Automatic; - }; - }; - }; - buildConfigurationList = 56B035FE1E8D9EBE003B6DA4 /* Build configuration list for PBXProject "GRDBDemoiOS" */; - compatibilityVersion = "Xcode 12.0"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 56B035FA1E8D9EBE003B6DA4; - productRefGroup = 56B036041E8D9EBE003B6DA4 /* Products */; - projectDirPath = ""; - projectReferences = ( - { - ProductGroup = 56606CFD2355931F00185962 /* Products */; - ProjectRef = 56B036261E8D9F79003B6DA4 /* GRDB.xcodeproj */; - }, - ); - projectRoot = ""; - targets = ( - 56B036021E8D9EBE003B6DA4 /* GRDBDemoiOS */, - 568E5FBE1E926430002582E0 /* GRDBDemoWatchOS */, - 568E5FCA1E926430002582E0 /* GRDBDemoWatchOS Extension */, - 56185BEF25B80B8900B9C30F /* GRDBDemoiOSTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXReferenceProxy section */ - 56606D0A2355931F00185962 /* GRDB.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = GRDB.framework; - remoteRef = 56606D092355931F00185962 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 56606D0C2355931F00185962 /* GRDBTests.xctest */ = { - isa = PBXReferenceProxy; - fileType = wrapper.cfbundle; - path = GRDBTests.xctest; - remoteRef = 56606D0B2355931F00185962 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; -/* End PBXReferenceProxy section */ - -/* Begin PBXResourcesBuildPhase section */ - 56185BEE25B80B8900B9C30F /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 568E5FBD1E926430002582E0 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 568E5FC51E926430002582E0 /* Assets.xcassets in Resources */, - 568E5FC31E926430002582E0 /* Interface.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 568E5FC91E926430002582E0 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 568E5FD51E926430002582E0 /* Assets.xcassets in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 56B036011E8D9EBE003B6DA4 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 56B036111E8D9EBE003B6DA4 /* LaunchScreen.storyboard in Resources */, - 56B0360E1E8D9EBE003B6DA4 /* Assets.xcassets in Resources */, - 56B0360C1E8D9EBE003B6DA4 /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 56185BEC25B80B8900B9C30F /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 56185C0725B80CEC00B9C30F /* PlayerTests.swift in Sources */, - 56185BF325B80B8900B9C30F /* AppDatabaseTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 568E5FC71E926430002582E0 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 568E5FD31E926430002582E0 /* ExtensionDelegate.swift in Sources */, - 568E5FD11E926430002582E0 /* InterfaceController.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 56B035FF1E8D9EBE003B6DA4 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 56FE6F2624A90CE400711EDF /* SceneDelegate.swift in Sources */, - 56B0361C1E8D9F38003B6DA4 /* Player.swift in Sources */, - 56B0361B1E8D9F38003B6DA4 /* AppDatabase.swift in Sources */, - 56185BBF25B8036100B9C30F /* Persistence.swift in Sources */, - 56B036071E8D9EBE003B6DA4 /* AppDelegate.swift in Sources */, - 56B036241E8D9F4C003B6DA4 /* PlayerListViewController.swift in Sources */, - 56B036231E8D9F4C003B6DA4 /* PlayerEditionViewController.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 56185BF625B80B8900B9C30F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 56B036021E8D9EBE003B6DA4 /* GRDBDemoiOS */; - targetProxy = 56185BF525B80B8900B9C30F /* PBXContainerItemProxy */; - }; - 5642253029A2390800D714BF /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = GRDB; - targetProxy = 5642252F29A2390800D714BF /* PBXContainerItemProxy */; - }; - 5642253429A2391900D714BF /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = GRDB; - targetProxy = 5642253329A2391900D714BF /* PBXContainerItemProxy */; - }; - 568E5FCE1E926430002582E0 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 568E5FCA1E926430002582E0 /* GRDBDemoWatchOS Extension */; - targetProxy = 568E5FCD1E926430002582E0 /* PBXContainerItemProxy */; - }; - 568E5FD81E926430002582E0 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 568E5FBE1E926430002582E0 /* GRDBDemoWatchOS */; - targetProxy = 568E5FD71E926430002582E0 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 568E5FC11E926430002582E0 /* Interface.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 568E5FC21E926430002582E0 /* Base */, - ); - name = Interface.storyboard; - sourceTree = ""; - }; - 56B0360A1E8D9EBE003B6DA4 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 56B0360B1E8D9EBE003B6DA4 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 56B0360F1E8D9EBE003B6DA4 /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 56B036101E8D9EBE003B6DA4 /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 56185BF725B80B8900B9C30F /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = AMD8W895CT; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = GRDBDemoiOSTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 17.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = com.github.groue.GRDBDemoiOSTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GRDBDemoiOS.app/GRDBDemoiOS"; - }; - name = Debug; - }; - 56185BF825B80B8900B9C30F /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = AMD8W895CT; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = GRDBDemoiOSTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 17.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = com.github.groue.GRDBDemoiOSTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GRDBDemoiOS.app/GRDBDemoiOS"; - }; - name = Release; - }; - 568E5FDB1E926430002582E0 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; - CLANG_ENABLE_OBJC_WEAK = YES; - DEVELOPMENT_TEAM = AMD8W895CT; - INFOPLIST_FILE = "GRDBDemoWatchOS Extension/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.github.groue.GRDBDemoiOS2.watchkitapp.watchkitextension; - PRODUCT_NAME = "${TARGET_NAME}"; - SDKROOT = watchos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = 4; - }; - name = Debug; - }; - 568E5FDC1E926430002582E0 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; - CLANG_ENABLE_OBJC_WEAK = YES; - DEVELOPMENT_TEAM = AMD8W895CT; - INFOPLIST_FILE = "GRDBDemoWatchOS Extension/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.github.groue.GRDBDemoiOS2.watchkitapp.watchkitextension; - PRODUCT_NAME = "${TARGET_NAME}"; - SDKROOT = watchos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = 4; - }; - name = Release; - }; - 568E5FDF1E926430002582E0 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_OBJC_WEAK = YES; - DEVELOPMENT_TEAM = AMD8W895CT; - IBSC_MODULE = GRDBDemoWatchOS_Extension; - INFOPLIST_FILE = GRDBDemoWatchOS/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.github.groue.GRDBDemoiOS2.watchkitapp; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = watchos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = 4; - }; - name = Debug; - }; - 568E5FE01E926430002582E0 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_OBJC_WEAK = YES; - DEVELOPMENT_TEAM = AMD8W895CT; - IBSC_MODULE = GRDBDemoWatchOS_Extension; - INFOPLIST_FILE = GRDBDemoWatchOS/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.github.groue.GRDBDemoiOS2.watchkitapp; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = watchos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = 4; - }; - name = Release; - }; - 56B036131E8D9EBE003B6DA4 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - 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 = 15.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - WATCHOS_DEPLOYMENT_TARGET = 8.0; - }; - name = Debug; - }; - 56B036141E8D9EBE003B6DA4 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - 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 = 15.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - SWIFT_VERSION = 5.0; - VALIDATE_PRODUCT = YES; - WATCHOS_DEPLOYMENT_TARGET = 8.0; - }; - name = Release; - }; - 56B036161E8D9EBE003B6DA4 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_OBJC_WEAK = YES; - DEVELOPMENT_TEAM = AMD8W895CT; - INFOPLIST_FILE = GRDBDemoiOS/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 17.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.github.groue.GRDBDemoiOS2; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 56B036171E8D9EBE003B6DA4 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_OBJC_WEAK = YES; - DEVELOPMENT_TEAM = AMD8W895CT; - INFOPLIST_FILE = GRDBDemoiOS/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 17.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.github.groue.GRDBDemoiOS2; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 56185BFF25B80B8900B9C30F /* Build configuration list for PBXNativeTarget "GRDBDemoiOSTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 56185BF725B80B8900B9C30F /* Debug */, - 56185BF825B80B8900B9C30F /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 568E5FDA1E926430002582E0 /* Build configuration list for PBXNativeTarget "GRDBDemoWatchOS Extension" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 568E5FDB1E926430002582E0 /* Debug */, - 568E5FDC1E926430002582E0 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 568E5FDE1E926430002582E0 /* Build configuration list for PBXNativeTarget "GRDBDemoWatchOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 568E5FDF1E926430002582E0 /* Debug */, - 568E5FE01E926430002582E0 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 56B035FE1E8D9EBE003B6DA4 /* Build configuration list for PBXProject "GRDBDemoiOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 56B036131E8D9EBE003B6DA4 /* Debug */, - 56B036141E8D9EBE003B6DA4 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 56B036151E8D9EBE003B6DA4 /* Build configuration list for PBXNativeTarget "GRDBDemoiOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 56B036161E8D9EBE003B6DA4 /* Debug */, - 56B036171E8D9EBE003B6DA4 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 56B035FB1E8D9EBE003B6DA4 /* Project object */; -} diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a625..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003d..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS.xcodeproj/xcshareddata/xcschemes/GRDBDemoWatchOS.xcscheme b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS.xcodeproj/xcshareddata/xcschemes/GRDBDemoWatchOS.xcscheme deleted file mode 100644 index bd03393c0d..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS.xcodeproj/xcshareddata/xcschemes/GRDBDemoWatchOS.xcscheme +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/AppDatabase.swift b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/AppDatabase.swift deleted file mode 100644 index 8c38cd2a77..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/AppDatabase.swift +++ /dev/null @@ -1,200 +0,0 @@ -import GRDB -import os.log - -/// `AppDatabase` lets the application access the database. -/// -/// You create an `AppDatabase` with a connection to an SQLite database -/// (see ). -/// -/// Create those connections with a configuration returned from -/// `AppDatabase/makeConfiguration(_:)`. -/// -/// For example: -/// -/// ```swift -/// // Create an in-memory AppDatabase -/// let config = AppDatabase.makeConfiguration() -/// let dbQueue = try DatabaseQueue(configuration: config) -/// let appDatabase = try AppDatabase(dbQueue) -/// ``` -struct AppDatabase { - /// Creates an `AppDatabase`, and makes sure the database schema - /// is ready. - /// - /// - important: Create the `DatabaseWriter` with a configuration - /// returned by ``makeConfiguration(_:)``. - init(_ dbWriter: any DatabaseWriter) throws { - self.dbWriter = dbWriter - try migrator.migrate(dbWriter) - } - - /// Provides access to the database. - /// - /// Application can use a `DatabasePool`, and tests can use a fast - /// in-memory `DatabaseQueue`. - /// - /// See - private let dbWriter: any DatabaseWriter -} - -// MARK: - Database Configuration - -extension AppDatabase { - private static let sqlLogger = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "SQL") - - /// Returns a database configuration suited for `PlayerRepository`. - /// - /// SQL statements are logged if the `SQL_TRACE` environment variable - /// is set. - /// - /// - parameter base: A base configuration. - public static func makeConfiguration(_ base: Configuration = Configuration()) -> Configuration { - var config = base - - // An opportunity to add required custom SQL functions or - // collations, if needed: - // config.prepareDatabase { db in - // db.add(function: ...) - // } - - // Log SQL statements if the `SQL_TRACE` environment variable is set. - // See - if ProcessInfo.processInfo.environment["SQL_TRACE"] != nil { - config.prepareDatabase { db in - db.trace { - // It's ok to log statements publicly. Sensitive - // information (statement arguments) are not logged - // unless config.publicStatementArguments is set - // (see below). - os_log("%{public}@", log: sqlLogger, type: .debug, String(describing: $0)) - } - } - } - -#if DEBUG - // Protect sensitive information by enabling verbose debugging in - // DEBUG builds only. - // See - config.publicStatementArguments = true -#endif - - return config - } -} - -// MARK: - Database Migrations - -extension AppDatabase { - /// The DatabaseMigrator that defines the database schema. - /// - /// See - private var migrator: DatabaseMigrator { - var migrator = DatabaseMigrator() - -#if DEBUG - // Speed up development by nuking the database when migrations change - // See - migrator.eraseDatabaseOnSchemaChange = true -#endif - - migrator.registerMigration("createPlayer") { db in - // Create a table - // See - try db.create(table: "player") { t in - t.autoIncrementedPrimaryKey("id") - t.column("name", .text).notNull() - t.column("score", .integer).notNull() - } - } - - // Migrations for future application versions will be inserted here: - // migrator.registerMigration(...) { db in - // ... - // } - - return migrator - } -} - -// MARK: - Database Access: Writes -// The write methods execute invariant-preserving database transactions. - -extension AppDatabase { - /// Saves (inserts or updates) a player. When the method returns, the - /// player is present in the database, and its id is not nil. - func savePlayer(_ player: inout Player) throws { - try dbWriter.write { db in - try player.save(db) - } - } - - /// Delete the specified players - func deletePlayers(ids: [Int64]) throws { - try dbWriter.write { db in - _ = try Player.deleteAll(db, ids: ids) - } - } - - /// Delete all players - func deleteAllPlayers() throws { - try dbWriter.write { db in - _ = try Player.deleteAll(db) - } - } - - /// Refresh all players (by performing some random changes, for demo purpose). - func refreshPlayers() throws { - try dbWriter.write { db in - if try Player.all().isEmpty(db) { - // When database is empty, insert new random players - try createRandomPlayers(db) - } else { - // Insert a player - if Bool.random() { - _ = try Player.makeRandom().inserted(db) // insert but ignore inserted id - } - - // Delete a random player - if Bool.random() { - try Player.order(sql: "RANDOM()").limit(1).deleteAll(db) - } - - // Update some players - for var player in try Player.fetchAll(db) where Bool.random() { - try player.updateChanges(db) { - $0.score = Player.randomScore() - } - } - } - } - } - - /// Create random players if the database is empty. - func createRandomPlayersIfEmpty() throws { - try dbWriter.write { db in - if try Player.all().isEmpty(db) { - try createRandomPlayers(db) - } - } - } - - /// Support for `createRandomPlayersIfEmpty()` and `refreshPlayers()`. - private func createRandomPlayers(_ db: Database) throws { - for _ in 0..<8 { - _ = try Player.makeRandom().inserted(db) // insert but ignore inserted id - } - } -} - -// MARK: - Database Access: Reads - -// This demo app does not provide any specific reading method, and instead -// gives an unrestricted read-only access to the rest of the application. -// In your app, you are free to choose another path, and define focused -// reading methods. -extension AppDatabase { - /// Provides a read-only access to the database - var reader: DatabaseReader { - dbWriter - } -} diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/AppDelegate.swift b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/AppDelegate.swift deleted file mode 100644 index 07edceeed8..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/AppDelegate.swift +++ /dev/null @@ -1,22 +0,0 @@ -import UIKit - -@UIApplicationMain -class AppDelegate: UIResponder, UIApplicationDelegate { - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - return true - } - - // 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. - return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) - } - - 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/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Info.plist b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Info.plist deleted file mode 100644 index b5f9c0796b..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Info.plist +++ /dev/null @@ -1,62 +0,0 @@ - - - - - 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 - - - UISceneConfigurationName - Default Configuration - UISceneDelegateClassName - $(PRODUCT_MODULE_NAME).SceneDelegate - UISceneStoryboardFile - Main - - - - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Persistence.swift b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Persistence.swift deleted file mode 100644 index 96267e6846..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Persistence.swift +++ /dev/null @@ -1,49 +0,0 @@ -import Foundation -import GRDB - -extension AppDatabase { - /// The database for the application - static let shared = makeShared() - - private static func makeShared() -> AppDatabase { - do { - // Apply recommendations from - // - // - // Create the "Application Support/Database" directory if needed - let fileManager = FileManager.default - let appSupportURL = try fileManager.url( - for: .applicationSupportDirectory, in: .userDomainMask, - appropriateFor: nil, create: true) - let directoryURL = appSupportURL.appendingPathComponent("Database", isDirectory: true) - try fileManager.createDirectory(at: directoryURL, withIntermediateDirectories: true) - - // Open or create the database - let databaseURL = directoryURL.appendingPathComponent("db.sqlite") - NSLog("Database stored at \(databaseURL.path)") - let dbPool = try DatabasePool( - path: databaseURL.path, - // Use default AppDatabase configuration - configuration: AppDatabase.makeConfiguration()) - - // Create the AppDatabase - let appDatabase = try AppDatabase(dbPool) - - // Populate the database if it is empty, for better demo purpose. - try appDatabase.createRandomPlayersIfEmpty() - - return appDatabase - } catch { - // Replace this implementation with code to handle the error appropriately. - // fatalError() causes the application to generate a crash log and terminate. - // - // Typical reasons for an error here include: - // * The parent directory cannot be created, or disallows writing. - // * The database is not accessible, due to permissions or data protection when the device is locked. - // * The device is out of space. - // * The database could not be migrated to its latest schema version. - // Check the error message to determine what the actual problem was. - fatalError("Unresolved error \(error)") - } - } -} diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Player.swift b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Player.swift deleted file mode 100644 index 82204b62c4..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Player.swift +++ /dev/null @@ -1,104 +0,0 @@ -import GRDB - -/// The Player struct. -/// -/// Identifiable conformance supports type-safe GRDB primary key methods. -/// Hashable conformance supports table view updates -struct Player: Identifiable, Hashable { - /// The player id. - /// - /// Int64 is the recommended type for auto-incremented database ids. - /// Use nil for players that are not inserted yet in the database. - var id: Int64? - var name: String - var score: Int -} - -extension Player { - private static let names = [ - "Arthur", "Anita", "Barbara", "Bernard", "Craig", "Chiara", "David", - "Dean", "Éric", "Elena", "Fatima", "Frederik", "Gilbert", "Georgette", - "Henriette", "Hassan", "Ignacio", "Irene", "Julie", "Jack", "Karl", - "Kristel", "Louis", "Liz", "Masashi", "Mary", "Noam", "Nicole", - "Ophelie", "Oleg", "Pascal", "Patricia", "Quentin", "Quinn", "Raoul", - "Rachel", "Stephan", "Susie", "Tristan", "Tatiana", "Ursule", "Urbain", - "Victor", "Violette", "Wilfried", "Wilhelmina", "Yvon", "Yann", - "Zazie", "Zoé"] - - /// Creates a new player with empty name and zero score - static func new() -> Player { - Player(id: nil, name: "", score: 0) - } - - /// Creates a new player with random name and random score - static func makeRandom() -> Player { - Player(id: nil, name: randomName(), score: randomScore()) - } - - /// Returns a random name - static func randomName() -> String { - names.randomElement()! - } - - /// Returns a random score - static func randomScore() -> Int { - 10 * Int.random(in: 0...100) - } -} - -// MARK: - Persistence - -/// Make Player a Codable Record. -/// -/// See -extension Player: Codable, FetchableRecord, MutablePersistableRecord { - // Define database columns from CodingKeys - fileprivate enum Columns { - static let name = Column(CodingKeys.name) - static let score = Column(CodingKeys.score) - } - - /// Updates a player id after it has been inserted in the database. - mutating func didInsert(_ inserted: InsertionSuccess) { - id = inserted.rowID - } -} - -// MARK: - Player Database Requests - -/// Define some player requests used by the application. -/// -/// See -extension DerivableRequest { - /// A request of players ordered by name. - /// - /// For example: - /// - /// let players: [Player] = try dbWriter.read { db in - /// try Player.all().orderedByName().fetchAll(db) - /// } - func orderedByName() -> Self { - // Sort by name in a localized case insensitive fashion - // See https://github.com/groue/GRDB.swift/blob/master/README.md#string-comparison - order(Player.Columns.name.collating(.localizedCaseInsensitiveCompare)) - } - - /// A request of players ordered by score. - /// - /// For example: - /// - /// let players: [Player] = try dbWriter.read { db in - /// try Player.all().orderedByScore().fetchAll(db) - /// } - /// let bestPlayer: Player? = try dbWriter.read { db in - /// try Player.all().orderedByScore().fetchOne(db) - /// } - func orderedByScore() -> Self { - // Sort by descending score, and then by name, in a - // localized case insensitive fashion - // See https://github.com/groue/GRDB.swift/blob/master/README.md#string-comparison - order( - Player.Columns.score.desc, - Player.Columns.name.collating(.localizedCaseInsensitiveCompare)) - } -} diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 29d91251df..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,116 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "icon_20pt@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "icon_20pt@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "icon_29pt@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "icon_29pt@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "icon_40pt@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "icon_40pt@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_60pt@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_60pt@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "icon_20pt.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "icon_20pt@2x-1.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "icon_29pt.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "icon_29pt@2x-1.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "icon_40pt.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "icon_40pt@2x-1.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_76pt.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_76pt@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "icon_83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "Icon.png", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon.png b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon.png deleted file mode 100644 index 66b1931a14..0000000000 Binary files a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/Icon.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt.png b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt.png deleted file mode 100644 index 90648b3f40..0000000000 Binary files a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png deleted file mode 100644 index a077a6f490..0000000000 Binary files a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png deleted file mode 100644 index a077a6f490..0000000000 Binary files a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png deleted file mode 100644 index 600bdbd9cd..0000000000 Binary files a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt.png b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt.png deleted file mode 100644 index 8e04af0dd8..0000000000 Binary files a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png deleted file mode 100644 index 686e8d99e2..0000000000 Binary files a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png deleted file mode 100644 index 686e8d99e2..0000000000 Binary files a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png deleted file mode 100644 index 1d013c3d33..0000000000 Binary files a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt.png b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt.png deleted file mode 100644 index a077a6f490..0000000000 Binary files a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png deleted file mode 100644 index da66b9ba82..0000000000 Binary files a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png deleted file mode 100644 index da66b9ba82..0000000000 Binary files a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png deleted file mode 100644 index 59346ef4b6..0000000000 Binary files a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png deleted file mode 100644 index 59346ef4b6..0000000000 Binary files a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png deleted file mode 100644 index d4640afc9a..0000000000 Binary files a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_76pt.png b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_76pt.png deleted file mode 100644 index e3a04522bf..0000000000 Binary files a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_76pt.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png deleted file mode 100644 index 593ebd783d..0000000000 Binary files a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png deleted file mode 100644 index ca02cd03bc..0000000000 Binary files a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png and /dev/null differ diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/Contents.json b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/Contents.json deleted file mode 100644 index 73c00596a7..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/LaunchIcon.imageset/Contents.json b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/LaunchIcon.imageset/Contents.json deleted file mode 100644 index 2cbe59d5ec..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/LaunchIcon.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "filename" : "LaunchIcon.pdf", - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/LaunchIcon.imageset/LaunchIcon.pdf b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/LaunchIcon.imageset/LaunchIcon.pdf deleted file mode 100644 index 2660891492..0000000000 Binary files a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Assets.xcassets/LaunchIcon.imageset/LaunchIcon.pdf and /dev/null differ diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Base.lproj/LaunchScreen.storyboard b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index 307d45b11d..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Base.lproj/Main.storyboard b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Base.lproj/Main.storyboard deleted file mode 100644 index 0f36128da4..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/Resources/Base.lproj/Main.storyboard +++ /dev/null @@ -1,213 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/SceneDelegate.swift b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/SceneDelegate.swift deleted file mode 100644 index b484ed11dc..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/SceneDelegate.swift +++ /dev/null @@ -1,40 +0,0 @@ -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 _ = (scene as? UIWindowScene) else { return } - } - - 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. - } -} diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/ViewControllers/PlayerEditionViewController.swift b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/ViewControllers/PlayerEditionViewController.swift deleted file mode 100644 index e9988462ae..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/ViewControllers/PlayerEditionViewController.swift +++ /dev/null @@ -1,128 +0,0 @@ -import UIKit - -class PlayerEditionViewController: UITableViewController { - enum Mode { - /// Edition ends with the "Commit" unwind segue. - case creation - - /// Edition ends when user hits the back button. - case edition - } - - /// The edited player - private(set) var player: Player - - /// The presentation mode - let mode: Mode - - @IBOutlet private weak var cancelButtonItem: UIBarButtonItem! - @IBOutlet private weak var saveButtonItem: UIBarButtonItem! - @IBOutlet private weak var nameCell: UITableViewCell! - @IBOutlet private weak var nameTextField: UITextField! - @IBOutlet private weak var scoreCell: UITableViewCell! - @IBOutlet private weak var scoreTextField: UITextField! - - init?(_ coder: NSCoder, mode: Mode, player: Player) { - self.mode = mode - self.player = player - super.init(coder: coder) - } - - @available(*, unavailable) - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func viewDidLoad() { - super.viewDidLoad() - configureNavigationItem() - configureForm() - } -} - -// MARK: - Navigation - -extension PlayerEditionViewController { - override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool { - // Force keyboard to dismiss early - view.endEditing(true) - return true - } - - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - if segue.identifier == "Commit" { - saveChanges() - } - } - - override func willMove(toParent parent: UIViewController?) { - super.willMove(toParent: parent) - - if mode == .edition, parent == nil { - // Self is popping from its navigation controller - saveChanges() - } - } - - private func configureNavigationItem() { - switch mode { - case .creation: - navigationItem.title = "New Player" - navigationItem.leftBarButtonItem = cancelButtonItem - navigationItem.rightBarButtonItem = saveButtonItem - case .edition: - navigationItem.title = player.name - navigationItem.leftBarButtonItem = nil - navigationItem.rightBarButtonItem = nil - } - } -} - -// MARK: - Form - -extension PlayerEditionViewController: UITextFieldDelegate { - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - nameTextField.becomeFirstResponder() - } - - override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - tableView.deselectRow(at: indexPath, animated: false) - let cell = tableView.cellForRow(at: indexPath) - if cell === nameCell { - nameTextField.becomeFirstResponder() - } else if cell === scoreCell { - scoreTextField.becomeFirstResponder() - } - } - - func textFieldShouldReturn(_ textField: UITextField) -> Bool { - if textField == nameTextField { - scoreTextField.becomeFirstResponder() - } - return false - } - - @IBAction func textFieldDidChange(_ textField: UITextField) { - // User has edited the player: prevent interactive dismissal - isModalInPresentation = true - } - - private func configureForm() { - nameTextField.text = player.name - - if player.score == 0 && player.id == nil { - scoreTextField.text = "" - } else { - scoreTextField.text = "\(player.score)" - } - } - - private func saveChanges() { - var player = self.player - player.name = nameTextField.text ?? "" - player.score = scoreTextField.text.flatMap { Int($0) } ?? 0 - try! AppDatabase.shared.savePlayer(&player) - self.player = player - } -} diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/ViewControllers/PlayerListViewController.swift b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/ViewControllers/PlayerListViewController.swift deleted file mode 100644 index 0ef0c52d4b..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/ViewControllers/PlayerListViewController.swift +++ /dev/null @@ -1,194 +0,0 @@ -import UIKit -import GRDB - -/// PlayerListViewController displays the list of players. -class PlayerListViewController: UITableViewController { - private enum PlayerOrdering { - case byName - case byScore - } - - @IBOutlet private weak var newPlayerButtonItem: UIBarButtonItem! - private var dataSource: PlayerDataSource! - private var playersCancellable: DatabaseCancellable? - private var playerOrdering: PlayerOrdering = .byScore { - didSet { - configureOrderingBarButtonItem() - observePlayers() - } - } - - override func viewDidLoad() { - super.viewDidLoad() - configureToolbar() - configureNavigationItem() - configureDataSource() - observePlayers() - } - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - navigationController?.isToolbarHidden = false - } - - private func configureToolbar() { - toolbarItems = [ - UIBarButtonItem(systemItem: .trash, primaryAction: UIAction { [unowned self] _ in - setEditing(false, animated: true) - try! AppDatabase.shared.deleteAllPlayers() - }), - UIBarButtonItem(systemItem: .flexibleSpace), - UIBarButtonItem(systemItem: .refresh, primaryAction: UIAction { [unowned self] _ in - setEditing(false, animated: true) - try! AppDatabase.shared.refreshPlayers() - }), - UIBarButtonItem(systemItem: .flexibleSpace), - UIBarButtonItem(image: UIImage(systemName: "tornado"), primaryAction: UIAction { [unowned self] _ in - setEditing(false, animated: true) - for _ in 0..<50 { - DispatchQueue.global().async { - try! AppDatabase.shared.refreshPlayers() - } - } - }), - ] - } - - private func configureNavigationItem() { - navigationItem.backBarButtonItem = UIBarButtonItem(title: "Players") - navigationItem.leftBarButtonItems = [editButtonItem, newPlayerButtonItem] - configureOrderingBarButtonItem() - } - - private func configureOrderingBarButtonItem() { - switch playerOrdering { - case .byScore: - navigationItem.rightBarButtonItem = UIBarButtonItem( - title: "Score ▼", - primaryAction: UIAction { [unowned self] _ in - setEditing(false, animated: true) - playerOrdering = .byName - }) - case .byName: - navigationItem.rightBarButtonItem = UIBarButtonItem( - title: "Name ▲", - primaryAction: UIAction { [unowned self] _ in - setEditing(false, animated: true) - playerOrdering = .byScore - }) - } - } - - private func configureDataSource() { - dataSource = PlayerDataSource(tableView: tableView) { (tableView, indexPath, player) in - let cell = tableView.dequeueReusableCell(withIdentifier: "Player", for: indexPath) - if player.name.isEmpty { - cell.textLabel?.text = "(anonymous)" - } else { - cell.textLabel?.text = player.name - } - cell.detailTextLabel?.text = abs(player.score) > 1 ? "\(player.score) points" : "0 point" - return cell - } - dataSource.defaultRowAnimation = .fade - tableView.dataSource = dataSource - } - - private func configureTitle(from players: [Player]) { - switch players.count { - case 0: - navigationItem.title = "No Player" - case 1: - navigationItem.title = "1 Player" - case let count: - navigationItem.title = "\(count) Players" - } - } - - private func configureDataSource(from players: [Player]) { - var snapshot = NSDiffableDataSourceSnapshot() - snapshot.appendSections([0]) - snapshot.appendItems(players, toSection: 0) - - // Remember selection - let selectedPlayerId = tableView.indexPathForSelectedRow.flatMap { - dataSource.itemIdentifier(for: $0)?.id - } - - // Avoid a UIKit warning; don't animate when popping from edition - let animated = view.window != nil - - dataSource.apply(snapshot, animatingDifferences: animated, completion: { - // Restore selection - if let index = players.firstIndex(where: { $0.id == selectedPlayerId }) { - self.tableView.selectRow(at: IndexPath(row: index, section: 0), animated: false, scrollPosition: .none) - } - }) - } - - private func observePlayers() { - let request: QueryInterfaceRequest - switch playerOrdering { - case .byName: - request = Player.all().orderedByName() - case .byScore: - request = Player.all().orderedByScore() - } - - playersCancellable = ValueObservation - .tracking(request.fetchAll(_:)) - .start( - in: AppDatabase.shared.reader, - // Immediate scheduling feeds the data source right on subscription, - // and avoids an undesired animation when the application starts. - scheduling: .immediate, - onError: { error in fatalError("Unexpected error: \(error)") }, - onChange: { [weak self] players in - guard let self else { return } - self.configureTitle(from: players) - self.configureDataSource(from: players) - }) - } -} - - -// MARK: - Navigation - -extension PlayerListViewController { - @IBSegueAction func makePlayerEditionViewController(_ coder: NSCoder) -> PlayerEditionViewController? { - guard let indexPath = tableView.indexPathForSelectedRow, - let player = dataSource.itemIdentifier(for: indexPath) - else { return nil } - return PlayerEditionViewController(coder, mode: .edition, player: player) - } - - @IBSegueAction func makePlayerCreationViewController(_ coder: NSCoder) -> PlayerEditionViewController? { - let player = Player(id: nil, name: "", score: 0) - return PlayerEditionViewController(coder, mode: .creation, player: player) - } - - @IBAction func cancelPlayerEdition(_ segue: UIStoryboardSegue) { - // Player creation cancelled - } - - @IBAction func commitPlayerEdition(_ segue: UIStoryboardSegue) { - // Player creation committed - } -} - - -// MARK: - UITableViewDataSource - -/// Subclass of UITableViewDiffableDataSource that supports row deletion -private class PlayerDataSource: UITableViewDiffableDataSource { - override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { - true - } - - override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { - // Delete the player - if let player = itemIdentifier(for: indexPath), let id = player.id { - try! AppDatabase.shared.deletePlayers(ids: [id]) - } - } -} diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOSTests/AppDatabaseTests.swift b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOSTests/AppDatabaseTests.swift deleted file mode 100644 index 2c359a8988..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOSTests/AppDatabaseTests.swift +++ /dev/null @@ -1,146 +0,0 @@ -import XCTest -import GRDB -@testable import GRDBDemoiOS - -class AppDatabaseTests: XCTestCase { - func test_database_schema() throws { - // Given an empty database - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - - // When we instantiate an AppDatabase - _ = try AppDatabase(dbQueue) - - // Then the player table exists, with id, name & score columns - try dbQueue.read { db in - try XCTAssert(db.tableExists("player")) - let columns = try db.columns(in: "player") - let columnNames = Set(columns.map { $0.name }) - XCTAssertEqual(columnNames, ["id", "name", "score"]) - } - } - - func test_savePlayer_inserts() throws { - // Given an empty players database - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - let appDatabase = try AppDatabase(dbQueue) - - // When we save a new player - var player = Player(id: nil, name: "Arthur", score: 100) - try appDatabase.savePlayer(&player) - - // Then the player exists in the database - try XCTAssertTrue(dbQueue.read(player.exists)) - } - - func test_savePlayer_updates() throws { - // Given a players database that contains a player - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - let appDatabase = try AppDatabase(dbQueue) - var player = Player(id: nil, name: "Arthur", score: 100) - try dbQueue.write { db in - try player.insert(db) - } - - // When we modify and save the player - player.name = "Barbara" - player.score = 1000 - try appDatabase.savePlayer(&player) - - // Then the player has been updated in the database - let fetchedPlayer = try dbQueue.read { db in - try XCTUnwrap(Player.fetchOne(db, key: player.id)) - } - XCTAssertEqual(fetchedPlayer, player) - } - - func test_deletePlayers() throws { - // Given a players database that contains four players - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - let appDatabase = try AppDatabase(dbQueue) - var player1 = Player(id: nil, name: "Arthur", score: 100) - var player2 = Player(id: nil, name: "Barbara", score: 200) - var player3 = Player(id: nil, name: "Craig", score: 150) - var player4 = Player(id: nil, name: "David", score: 120) - try dbQueue.write { db in - try player1.insert(db) - try player2.insert(db) - try player3.insert(db) - try player4.insert(db) - } - - // When we delete two players - try appDatabase.deletePlayers(ids: [player1.id!, player3.id!]) - - // Then the deleted players no longer exist - try dbQueue.read { db in - try XCTAssertFalse(player1.exists(db)) - try XCTAssertFalse(player3.exists(db)) - } - - // Then the database still contains two players - try XCTAssertEqual(dbQueue.read(Player.fetchCount), 2) - } - - func test_deleteAllPlayers() throws { - // Given a players database that contains players - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - let appDatabase = try AppDatabase(dbQueue) - var player1 = Player(id: nil, name: "Arthur", score: 100) - var player2 = Player(id: nil, name: "Barbara", score: 200) - var player3 = Player(id: nil, name: "Craig", score: 150) - var player4 = Player(id: nil, name: "David", score: 120) - try dbQueue.write { db in - try player1.insert(db) - try player2.insert(db) - try player3.insert(db) - try player4.insert(db) - } - - // When we delete all players - try appDatabase.deleteAllPlayers() - - // Then the database does not contain any player - try XCTAssertEqual(dbQueue.read(Player.fetchCount), 0) - } - - func test_refreshPlayers_populates_an_empty_database() throws { - // Given an empty players database - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - let appDatabase = try AppDatabase(dbQueue) - - // When we refresh players - try appDatabase.refreshPlayers() - - // Then the database is not empty - try XCTAssert(dbQueue.read(Player.fetchCount) > 0) - } - - func test_createRandomPlayersIfEmpty_populates_an_empty_database() throws { - // Given an empty players database - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - let appDatabase = try AppDatabase(dbQueue) - - // When we create random players - try appDatabase.createRandomPlayersIfEmpty() - - // Then the database is not empty - try XCTAssert(dbQueue.read(Player.fetchCount) > 0) - } - - func test_createRandomPlayersIfEmpty_does_not_modify_a_non_empty_database() throws { - // Given a players database that contains one player - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - let appDatabase = try AppDatabase(dbQueue) - var player = Player(id: nil, name: "Arthur", score: 100) - try dbQueue.write { db in - try player.insert(db) - } - - // When we create random players - try appDatabase.createRandomPlayersIfEmpty() - - // Then the database still only contains the original player - let players = try dbQueue.read(Player.fetchAll) - XCTAssertEqual(players, [player]) - } -} diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOSTests/Info.plist b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOSTests/Info.plist deleted file mode 100644 index 64d65ca495..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOSTests/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - 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 - - diff --git a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOSTests/PlayerTests.swift b/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOSTests/PlayerTests.swift deleted file mode 100644 index 64d1c1d2b3..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOSTests/PlayerTests.swift +++ /dev/null @@ -1,108 +0,0 @@ -import XCTest -import GRDB -@testable import GRDBDemoiOS - -class PlayerTests: XCTestCase { - // MARK: - CRUD - // Test that our Player type properly talks to GRDB. - - func testInsert() throws { - // Given an empty players database - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - _ = try AppDatabase(dbQueue) - - // When we insert a player - var player = Player(id: nil, name: "Arthur", score: 100) - try dbQueue.write { db in - try player.insert(db) - } - - // Then the player gets a non-nil id - XCTAssertNotNil(player.id) - } - - func testRoundtrip() throws { - // Given an empty players database - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - _ = try AppDatabase(dbQueue) - - // When we insert a player and fetch the player with the same id - var insertedPlayer = Player(id: nil, name: "Arthur", score: 100) - let fetchedPlayer: Player? = try dbQueue.write { db in - try insertedPlayer.insert(db) - return try Player.fetchOne(db, key: insertedPlayer.id) - } - - // Then the fetched player is equal to the inserted player - XCTAssertEqual(insertedPlayer, fetchedPlayer) - } - - // MARK: - Requests - // Test that requests defined on the Player type behave as expected. - - func testOrderedByScore() throws { - // Given a players database that contains players with distinct scores - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - _ = try AppDatabase(dbQueue) - var player1 = Player(id: 1, name: "Arthur", score: 100) - var player2 = Player(id: 2, name: "Barbara", score: 200) - var player3 = Player(id: 3, name: "Craig", score: 150) - var player4 = Player(id: 4, name: "David", score: 120) - try dbQueue.write { db in - try player1.insert(db) - try player2.insert(db) - try player3.insert(db) - try player4.insert(db) - } - - // When we fetch players ordered by score - let players = try dbQueue.read(Player.all().orderedByScore().fetchAll) - - // Then fetched players are ordered by score descending - XCTAssertEqual(players, [player2, player3, player4, player1]) - } - - func testOrderedByScoreSortsIdenticalScoresByName() throws { - // Given a players database that contains players with common scores - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - _ = try AppDatabase(dbQueue) - var player1 = Player(id: 1, name: "Arthur", score: 100) - var player2 = Player(id: 2, name: "Barbara", score: 200) - var player3 = Player(id: 3, name: "Craig", score: 200) - var player4 = Player(id: 4, name: "David", score: 200) - try dbQueue.write { db in - try player1.insert(db) - try player2.insert(db) - try player3.insert(db) - try player4.insert(db) - } - - // When we fetch players ordered by score - let players = try dbQueue.read(Player.all().orderedByScore().fetchAll) - - // Then fetched players are ordered by score descending and by name - XCTAssertEqual(players, [player2, player3, player4, player1]) - } - - func testOrderedByName() throws { - // Given a players database that contains players with distinct names - let dbQueue = try DatabaseQueue(configuration: AppDatabase.makeConfiguration()) - _ = try AppDatabase(dbQueue) - var player1 = Player(id: 1, name: "Arthur", score: 100) - var player2 = Player(id: 2, name: "Barbara", score: 200) - var player3 = Player(id: 3, name: "Craig", score: 150) - var player4 = Player(id: 4, name: "David", score: 120) - try dbQueue.write { db in - try player1.insert(db) - try player2.insert(db) - try player3.insert(db) - try player4.insert(db) - } - - // When we fetch players ordered by name - let players = try dbQueue.read(Player.all().orderedByName().fetchAll) - - // Then fetched players are ordered by name - XCTAssertEqual(players, [player1, player2, player3, player4]) - } -} diff --git a/Documentation/DemoApps/GRDBDemoiOS/README.md b/Documentation/DemoApps/GRDBDemoiOS/README.md deleted file mode 100644 index ab854697c7..0000000000 --- a/Documentation/DemoApps/GRDBDemoiOS/README.md +++ /dev/null @@ -1,45 +0,0 @@ -UIKit Demo Application -====================== - - - -**This demo application is a storyboard-based UIKit application.** For a demo application that uses Combine + SwiftUI, see [GRDBCombineDemo](../GRDBCombineDemo/README.md), and for Async/Await + SwiftUI, see [GRDBAsyncDemo](../GRDBAsyncDemo/README.md). - -**Requirements**: iOS 15.0+ / Xcode 12+ - -> **Note**: This demo app is not a project template. Do not copy it as a starting point for your application. Instead, create a new project, choose a GRDB [installation method](../../../README.md#installation), and use the demo as an inspiration. - -The topics covered in this demo are: - -- How to setup a database in an iOS app. -- How to define a simple [Codable Record](../../../README.md#codable-records). -- How to track database changes and animate a table view with [ValueObservation](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/valueobservation). -- How to apply the recommendations of [Recommended Practices for Designing Record Types](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/recordrecommendedpractices). - -**Files of interest:** - -- [AppDatabase.swift](GRDBDemoiOS/AppDatabase.swift) - - `AppDatabase` is the type that grants database access. It uses [DatabaseMigrator](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databasemigrator) in order to setup the database schema, and [ValueObservation](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/valueobservation) in order to let the application observe database changes. - -- [Persistence.swift](GRDBDemoiOS/Persistence.swift) - - This file defines the `AppDatabase` instance used by the application. - -- [Player.swift](GRDBDemoiOS/Player.swift) - - `Player` is a [Record](../../../README.md#records) type, able to read and write in the database. It conforms to the standard Codable protocol in order to gain all advantages of [Codable Records](../../../README.md#codable-records). It defines the database requests used by the application. - -- [PlayerListViewController.swift](GRDBDemoiOS/ViewControllers/PlayerListViewController.swift) - - `PlayerListViewController` displays the list of players. - -- [PlayerEditionViewController.swift](GRDBDemoiOS/ViewControllers/PlayerEditionViewController.swift) - - `PlayerEditionViewController` can create or edit a player, and save it in the database. - -- [GRDBDemoiOSTests](GRDBDemoiOSTests) - - - Test the database schema - - Test the `Player` record and its requests - - Test the `AppDatabase` methods that let the app access the database. diff --git a/Documentation/DemoApps/GRDBDemoiOS/Screenshot.png b/Documentation/DemoApps/GRDBDemoiOS/Screenshot.png deleted file mode 100644 index 7a0fccd710..0000000000 Binary files a/Documentation/DemoApps/GRDBDemoiOS/Screenshot.png and /dev/null differ diff --git a/Documentation/DemoApps/README.md b/Documentation/DemoApps/README.md index 136665c684..8c6ce177f6 100644 --- a/Documentation/DemoApps/README.md +++ b/Documentation/DemoApps/README.md @@ -1,13 +1,9 @@ Demo Applications ================= -- [GRDBDemoiOS]: a storyboard-based UIKit application. -- [GRDBCombineDemo]: a Combine + SwiftUI application. -- [GRDBAsyncDemo]: a Async/Await + SwiftUI application. +[GRDBDemo] demonstrates how GRDB can fuel a SwiftUI application. -[GRDBCombineDemo] and [GRDBAsyncDemo] use the same `@Query` property wrapper, that lets SwiftUI views automatically update their content when the database changes. It is defined in the [GRDBQuery] package. +See also the demo apps of the [GRDBQuery] package: they use the `@Query` property wrapper that helps SwiftUI views automatically update their content when the database changes. -[GRDBDemoiOS]: GRDBDemoiOS -[GRDBCombineDemo]: GRDBCombineDemo -[GRDBAsyncDemo]: GRDBAsyncDemo +[GRDBDemo]: GRDBDemo [GRDBQuery]: https://github.com/groue/GRDBQuery diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Documentation/DemoApps2/GRDBDemo/GRDBDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a625..0000000000 --- a/Documentation/DemoApps2/GRDBDemo/GRDBDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Preview Content/Preview Assets.xcassets/Contents.json b/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Preview Content/Preview Assets.xcassets/Contents.json deleted file mode 100644 index 73c00596a7..0000000000 --- a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Preview Content/Preview Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/AccentColor.colorset/Contents.json b/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/AccentColor.colorset/Contents.json deleted file mode 100644 index eb87897008..0000000000 --- a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/AccentColor.colorset/Contents.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "colors" : [ - { - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/Contents.json b/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/Contents.json deleted file mode 100644 index 73c00596a7..0000000000 --- a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/LaunchScreen.imageset/LaunchIcon.pdf b/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/LaunchScreen.imageset/LaunchIcon.pdf deleted file mode 100644 index 2660891492..0000000000 Binary files a/Documentation/DemoApps2/GRDBDemo/GRDBDemo/Resources/Assets.xcassets/LaunchScreen.imageset/LaunchIcon.pdf and /dev/null differ diff --git a/Documentation/DemoApps2/README.md b/Documentation/DemoApps2/README.md deleted file mode 100644 index 8c6ce177f6..0000000000 --- a/Documentation/DemoApps2/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Demo Applications -================= - -[GRDBDemo] demonstrates how GRDB can fuel a SwiftUI application. - -See also the demo apps of the [GRDBQuery] package: they use the `@Query` property wrapper that helps SwiftUI views automatically update their content when the database changes. - -[GRDBDemo]: GRDBDemo -[GRDBQuery]: https://github.com/groue/GRDBQuery diff --git a/Documentation/ReleaseProcess.md b/Documentation/ReleaseProcess.md index 08210d7404..07749a5b3a 100644 --- a/Documentation/ReleaseProcess.md +++ b/Documentation/ReleaseProcess.md @@ -7,8 +7,7 @@ To release a new GRDB version: - Tests - `make distclean test` - - Build and run GRDBDemoiOS in Release configuration on a device - - Archive GRDBDemoiOS + - Build and run GRDBDemo - Check for performance regression with GRDBOSXPerformanceTests - On https://github.com/groue/sqlcipher.git upgrade, update SQLCipher version in README.md - On https://github.com/swiftlyfalling/SQLiteLib upgrade, update SQLite version in Documentation/CustomSQLiteBuilds.md diff --git a/GRDB.xcworkspace/contents.xcworkspacedata b/GRDB.xcworkspace/contents.xcworkspacedata index 3258ed7a7b..26f0eae470 100644 --- a/GRDB.xcworkspace/contents.xcworkspacedata +++ b/GRDB.xcworkspace/contents.xcworkspacedata @@ -45,12 +45,6 @@ location = "group:Tests/Performance/GRDBProfiling/GRDBProfiling.xcodeproj"> - - - - + location = "group:Documentation/DemoApps/GRDBDemo/GRDBDemo.xcodeproj"> diff --git a/Makefile b/Makefile index 7d367e7e68..db8b433138 100644 --- a/Makefile +++ b/Makefile @@ -81,7 +81,7 @@ test_framework_SQLCipher: test_framework_SQLCipher3 test_framework_SQLCipher3Enc test_archive: test_universal_xcframework test_install: test_install_manual test_install_SPM test_install_customSQLite test_install_GRDB_CocoaPods test_CocoaPodsLint: test_CocoaPodsLint_GRDB -test_demo_apps: test_GRDBDemoiOS test_GRDBCombineDemo test_GRDBAsyncDemo +test_demo_apps: test_GRDBDemo test_framework_GRDBOSX: $(XCODEBUILD) \ @@ -371,26 +371,10 @@ else @exit 1 endif -test_GRDBDemoiOS: +test_GRDBDemo: $(XCODEBUILD) \ - -project Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS.xcodeproj \ - -scheme GRDBDemoiOS \ - -destination $(MAX_IOS_DESTINATION) \ - $(TEST_ACTIONS) \ - $(XCPRETTY) - -test_GRDBCombineDemo: - $(XCODEBUILD) \ - -project Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo.xcodeproj \ - -scheme GRDBCombineDemo \ - -destination $(MAX_IOS_DESTINATION) \ - $(TEST_ACTIONS) \ - $(XCPRETTY) - -test_GRDBAsyncDemo: - $(XCODEBUILD) \ - -project Documentation/DemoApps/GRDBAsyncDemo/GRDBAsyncDemo.xcodeproj \ - -scheme GRDBAsyncDemo \ + -project Documentation/DemoApps/GRDBDemo/GRDBDemo.xcodeproj \ + -scheme GRDBDemo \ -destination $(MAX_IOS_DESTINATION) \ $(TEST_ACTIONS) \ $(XCPRETTY) diff --git a/README.md b/README.md index 5928ab542a..fadc39b591 100644 --- a/README.md +++ b/README.md @@ -276,7 +276,7 @@ Documentation #### Demo Applications & Frequently Asked Questions -- [Demo Applications]: Three flavors: vanilla UIKit, Combine + SwiftUI, and Async/Await + SwiftUI. +- [Demo Applications] - [FAQ] #### Reference @@ -395,8 +395,6 @@ Due to an [issue](https://github.com/CocoaPods/CocoaPods/issues/11839) in CocoaP 4. Add the `GRDB.framework` to the **Embedded Binaries** section of the **General** tab of your application target (extension target for WatchOS). -> :bulb: **Tip**: see the [Demo Applications] for examples of such integration. - Database Connections ====================