Compare commits

..

128 Commits

Author SHA1 Message Date
John Estropia
104def4611 bump min development version to iOS 16 and macOS 13 2024-10-31 14:05:02 +09:00
John Estropia
5dcf29011a Support typed errors. Misc formatting 2024-09-10 11:14:39 +09:00
John Estropia
c9e091a6a4 Merge pull request #510 from DavidTiimo/develop
issue #509 | Xcode 16.0 beta 6 error - "'CATransaction' is unavailable in watchOS"
2024-09-10 11:11:32 +09:00
David Hansson
010a79ef6a Reverse check, as only watch os is having troubles 2024-09-04 12:55:24 +02:00
David Hansson
9f9ecb4820 Only available for iOS 2024-09-04 12:35:08 +02:00
David Hansson
3fb2b5927b Comment out broken code for Xcode beta 2024-08-13 09:47:48 +02:00
John Estropia
7c2129e38f Deprecation of legacy ValueContainer and RelationshipContainer properties in favor of @Field propertyWrapper counterpart 2024-01-28 22:11:21 +09:00
John Estropia
4b6d9a54e7 fix pod lint 2023-10-03 18:52:14 +09:00
John Estropia
cbf101506c revert unit test momd for now 2023-10-03 18:08:19 +09:00
John Estropia
9045fbbf1b bump CoreStore and Swift compiler versions 2023-10-03 11:25:56 +09:00
John Estropia
0ee4dc89aa Make unit test momd file accessible from SwiftPM builds 2023-10-03 11:25:19 +09:00
John Estropia
30d5e0a64a silence warnings on ObjectSnapshot sendability 2023-07-18 16:02:32 +09:00
John Estropia
320c6145f8 Merge branch 'develop' into prototype/concurrency 2023-07-18 09:44:53 +09:00
John Estropia
7e37219315 update header for MIT license, move all operator declarations to one file 2023-06-15 16:05:14 +09:00
John Estropia
d8235cf2e5 Merge pull request #482 from JCSooHwanCho/develop
merge operator declaration in one file
2023-06-15 16:00:40 +09:00
John Estropia
5cc34ff2e4 Merge pull request #483 from JCSooHwanCho/inlinable
mark designated initializer with usableFromInline
2023-06-15 15:56:51 +09:00
JCSoohwancho
d4d76c87c9 mark designated initializer with usableFromInline 2023-06-15 15:19:55 +09:00
JCSoohwancho
073a1bdee3 merge operator declaration in one file 2023-06-15 14:22:00 +09:00
John Estropia
118bb685fc remove watchos from unit tests 2023-06-08 11:39:17 +09:00
John Estropia
5d0c4bf8ac update jazzy docs 2023-06-08 11:02:23 +09:00
John Estropia
a8bd937c68 version bump 2023-06-08 11:02:14 +09:00
John Estropia
7988d98b92 fix warnings 2023-06-07 14:17:10 +09:00
John Estropia
4b4ae61635 add conditional compilation 2023-06-07 13:43:11 +09:00
John Estropia
535b33ca75 test reverting back to unsafeDowncast 2023-06-07 13:40:25 +09:00
John Estropia
b88ade92d6 add tentative replacement methods for SR-13069 workarounds 2023-03-24 18:28:43 +09:00
John Estropia
a682f90aff mask ObjectSnapshot as Sendable 2023-01-31 16:44:33 +09:00
John Estropia
f7c3e42009 mark sendable closures 2023-01-31 09:50:06 +09:00
John Estropia
2559375491 Raise watchOS min version to 7.4 as supported by Xcode 14 unit tests 2022-09-13 09:26:21 +09:00
John Estropia
c923dfc12c fix unit testing for multi-platform module 2022-09-12 16:51:20 +09:00
John Estropia
a5936c1120 added watchOS unit test lane to make cocoapods linter happy 2022-09-12 13:56:47 +09:00
John Estropia
159448b36d update README 2022-09-12 11:57:32 +09:00
John Estropia
7ee91834ab update README 2022-09-12 11:53:06 +09:00
John Estropia
8faf44c166 version bump 2022-09-12 10:04:33 +09:00
John Estropia
7f4cfaf5a0 Allow unit-testing in SPM builds 2022-08-16 11:55:44 +08:00
John Estropia
da4ac192db async API prototypes 2022-07-10 10:39:45 +09:00
John Estropia
e9219682b5 Fix builds for Swift 5.6 and below 2022-07-08 16:49:43 +09:00
John Estropia
6264022ccf make CoreStoreError dynamicc initializer public 2022-07-08 14:07:32 +09:00
John Estropia
1ed819b38d Goodbye Objective-C... 2022-06-29 20:27:42 +09:00
John Estropia
afddd2edbd Updated Package.swift 2022-06-22 19:20:40 +09:00
John Estropia
d1f83badef Xcode 14, iOS 16 SDK (min iOS 13) 2022-06-19 17:56:42 +09:00
John Estropia
3317867a2f Fix warnings for Xcode 13.3 beta 2022-03-05 11:31:36 +09:00
John Estropia
f738848e8c update SPM 2021-09-22 22:07:21 +09:00
John Estropia
496145761a version bump 2021-09-22 20:30:40 +09:00
John Estropia
c54795db5a project cleanup 2021-09-22 20:09:32 +09:00
John Estropia
9a026afe40 goodbye ObjectiveC 2021-09-22 20:04:58 +09:00
John Estropia
bf10f4668c revert Objc method changes 2021-09-22 15:03:46 +09:00
John Estropia
a1a04aaf8a tag refetch methods with source identifiers 2021-09-15 19:38:59 +09:00
John Estropia
4ddfa95140 added mechanism to track transaction sources 2021-09-15 14:45:13 +09:00
John Estropia
45215c7a18 WIP 2021-08-25 20:13:14 +09:00
John Estropia
d2f1656fdd test copy-on-write for ListSnapshot 2021-08-25 09:37:20 +09:00
John Estropia
5fbb1ab09d Merge pull request #421 from xquezme/develop
Fix compound indexes for dynamic models
2021-07-20 09:26:17 +09:00
John Estropia
d0cc01877e Merge pull request #433 from tackgyu/unset-library-type
Unset library type in Swift package manifests
2021-07-19 13:35:39 +09:00
tackgyu
a434628249 Unset library type in Swift package manifests 2021-07-19 12:52:51 +09:00
John Estropia
9cc616f720 fix compiler error on Xcode 13 2021-06-19 15:49:45 +09:00
John Estropia
4534bc06f5 Add utility for DiffableDataSources to create an empty snapshot for custom list construction 2021-06-16 23:28:46 +09:00
John Estropia
798d30bbd9 allow ListPublisher and ObjectPublisher combine Publishers to cancel subscription from any thread 2021-06-13 14:36:22 +09:00
John Estropia
7938aa2447 Added fast index-based ListSnapshot mutators 2021-06-12 11:06:43 +09:00
John Estropia
dda69389eb Fix SPM issues 2021-04-20 18:30:14 +09:00
John Estropia
b20be10a19 update Readme banner image 2021-04-11 11:39:43 +09:00
John Estropia
0ee8fbabd5 version bump, update resources 2021-04-11 11:26:02 +09:00
John Estropia
1f562b25a7 Updated README 2021-04-11 11:03:17 +09:00
Pimenov Sergey
6a2394052c fix compound indexes for dynamic models 2021-04-04 20:12:40 -07:00
John Estropia
593c0510d3 Allow placeholder Views in ObjectReader when an object becomes nil 2021-03-13 11:25:27 +09:00
John Estropia
338e4ddc9f Fix sig abort error 2021-03-07 17:02:09 +09:00
John Estropia
bfb1df3c40 added Publishers for addStorage functions 2021-03-07 16:08:19 +09:00
John Estropia
003bf897e2 Cleanup unnecessary #available branches 2021-03-07 12:01:08 +09:00
John Estropia
0b127956d3 Removed ObservableObject implementations of ListPublisher/ObjectPublisher in favor of LiveList/LiveObject and ".reactive" publishers 2021-03-07 10:38:53 +09:00
John Estropia
098e560fcc Merge branch 'develop' of github.com:JohnEstropia/CoreStore into develop 2021-03-07 10:17:34 +09:00
John Estropia
7dbd3777ec added sugar syntax for ForEach that removes requirement for the "id:" argument 2021-03-07 10:17:20 +09:00
John Estropia
447d8e5880 fix compile error 2021-03-03 16:59:20 +09:00
John Estropia
1f97225efa SwiftUI and Combine utilities appledocs. Bump up to 8.0 and iOS 11.0/macOS 10.13 2021-03-01 09:14:41 +09:00
John Estropia
d13b0cfabb update unit tests 2021-02-21 10:59:55 +09:00
John Estropia
d7b852fca4 SwiftUI utilities done (for now) 2021-02-21 10:56:27 +09:00
John Estropia
f2efe175e5 deprecate misleading API for sectionIndexTransformers 2021-02-21 10:17:58 +09:00
John Estropia
8f3a6638d8 Delete long-deprecated CoreStore namespace 2021-02-21 10:16:08 +09:00
John Estropia
f7471f56a4 Prototyping SwiftUI utilities 2021-02-16 09:12:36 +09:00
John Estropia
edd8ba55d8 fix rare duplication of uniqueID values during import when an import candidate is added by a previous insertion block 2021-01-23 16:51:45 +09:00
John Estropia
18aac84335 fix compiler error 2021-01-02 10:36:33 +09:00
John Estropia
c6be892cb0 added .where(combinedByAnd:) and .where(combinedByOr:) to help compiler with long && and || chains 2021-01-02 10:00:23 +09:00
John Estropia
2cd8101987 Implement ObjectRepresentation on ObjectMonitor, ObjectPublisher, and ObjectSnapshot for future APIs 2021-01-02 09:59:15 +09:00
John Estropia
e1aed37da0 avoid using default queue qos 2020-12-26 23:45:11 +09:00
John Estropia
5de5ecee06 give opportunity for faster equating of ObjectSnapshot 2020-12-26 23:44:35 +09:00
John Estropia
9406901b28 WIP: SwiftUI utils 2020-12-26 19:21:46 +09:00
John Estropia
477f478d85 Add missing Where operators (fixes #410) 2020-12-26 14:02:20 +09:00
John Estropia
668b5ad606 Update playground samples to use Field properties instead of old syntax 2020-12-07 14:08:05 +09:00
John Estropia
f985828f3b cleanup 2020-11-17 18:14:23 +09:00
John Estropia
bb3bc940c2 Remove the dataStack SwiftUI environment key since it's prone to initialization issues 2020-11-11 16:56:20 +09:00
John Estropia
2d5bc77219 Merge branch 'master' into minIOS11
# Conflicts:
#	Sources/ListSnapshot.swift
2020-11-11 13:44:58 +09:00
John Estropia
a40df37192 version bump 2020-11-11 13:29:02 +09:00
John Estropia
63b3d25d78 clear warnings 2020-11-11 13:18:11 +09:00
John Estropia
74721b5c12 allow ObjectSnapshot and ObjectPublisher as parameter to Where clauses 2020-10-10 16:55:35 +09:00
John Estropia
f136549b46 prevent creation of ObjectSnapshot if object is already deleted 2020-10-09 20:14:04 +09:00
John Estropia
4ec2b2e311 Optimize ListSnapshot collection implementation 2020-10-05 23:12:17 +09:00
John Estropia
3d82ee18c7 reinclude LegacyDemo in workspace 2020-10-03 14:36:57 +09:00
John Estropia
d6eae8c091 fix podspec 2020-09-19 15:07:27 +09:00
John Estropia
6f8d86cd8f remove xcuserdata 2020-09-19 14:59:14 +09:00
John Estropia
3b6f226389 version bump 2020-09-19 14:44:55 +09:00
John Estropia
228e4e8e1a rename CoreStoreDemo to LegacyDemo 2020-09-19 14:32:43 +09:00
John Estropia
98a42feb95 demo cleanup 2020-09-19 12:38:09 +09:00
John Estropia
2f93ee7591 Migrations demo done 2020-09-17 23:21:41 +09:00
John Estropia
11f5cb9a05 WIP: demo 2020-09-14 09:46:47 +09:00
John Estropia
2c00fc31bc WIP: migrations demo 2020-09-13 14:17:06 +09:00
John Estropia
2bbf6b34ea WIP: migrations demo 2020-09-08 09:09:36 +09:00
John Estropia
8d7f282743 added demo for classic ListMonitor 2020-08-30 20:16:01 +09:00
John Estropia
007da014f8 cleanup 2020-08-30 10:24:10 +09:00
John Estropia
b26e50f777 add version lock to demo 2020-08-29 23:06:12 +09:00
John Estropia
611bc53c9a cleanup 2020-08-29 23:05:07 +09:00
John Estropia
9d36582c10 minor fix 2020-08-29 20:06:00 +09:00
John Estropia
1c735a9228 improve Pokedex demo 2020-08-29 20:02:05 +09:00
John Estropia
1db91fcec3 make demo compilable on Xcode 11 2020-08-27 09:50:12 +09:00
John Estropia
8b3b947406 pokedex demo 2020-08-20 00:39:03 +09:00
John Estropia
2c0cadf2fa WIP 2020-08-19 18:49:08 +09:00
John Estropia
5e536556da fix for SR-13069 2020-08-19 11:01:12 +09:00
John Estropia
d75029f54b WIP 2020-08-19 08:32:18 +09:00
John Estropia
204c4de1f6 use randomElement in unit test 2020-08-18 17:50:00 +09:00
John Estropia
0f3455a4a4 WIP 2020-08-18 12:05:20 +09:00
John Estropia
72f36e7237 WIP 2020-08-17 17:09:41 +09:00
John Estropia
d988daa025 WIP: new demo app 2020-08-17 09:06:25 +09:00
John Estropia
e720504855 Update README.md 2020-06-20 17:37:12 +09:00
John Estropia
ee51c5ad9c fix readme indentations 2020-06-20 16:47:52 +09:00
John Estropia
4ac7df7364 version bump 2020-06-20 13:16:14 +09:00
John Estropia
56f873ccb3 fix readme table of contents 2020-06-20 13:12:11 +09:00
John Estropia
1f90f846f3 readme update 2020-06-20 13:07:10 +09:00
John Estropia
4a97d5a8dc remove persistentstores during DataStack deinitialization to prevent warnings in Unit tests during teardown 2020-05-26 09:43:39 +09:00
John Estropia
0eb9b6393d add unit testst for Field dynamic initializers 2020-05-24 10:54:16 +09:00
John Estropia
56d0ea46ea Implement dynamic initializers for Field properties (fixes #382) 2020-05-23 12:07:16 +09:00
John Estropia
a7568eebdb fix comments 2020-04-15 16:49:45 +09:00
John Estropia
4049e1944a trigger lazy initialization of ObjectPublisher observation after addObserver() (fixes #383) 2020-04-15 16:48:42 +09:00
811 changed files with 244128 additions and 148484 deletions

2
.gitignore vendored
View File

@@ -12,3 +12,5 @@ Playground_macOS.playground/playground.xcworkspace/xcuserdata
.swiftpm/xcode/package.xcworkspace/xcuserdata
.swiftpm/xcode/xcuserdata
Playground_iOS.playground/playground.xcworkspace/xcuserdata
LegacyDemo/LegacyDemo.xcodeproj/xcuserdata
Demo/Demo.xcodeproj/xcuserdata

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>CoreStore.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
</dict>
</plist>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 61 KiB

View File

@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "CoreStore"
s.version = "7.1.0"
s.swift_version = "5.2"
s.version = "9.3.0"
s.swift_version = "5.9"
s.license = "MIT"
s.homepage = "https://github.com/JohnEstropia/CoreStore"
s.documentation_url = "https://JohnEstropia.github.io/CoreStore"
@@ -9,14 +9,27 @@ Pod::Spec.new do |s|
s.author = { "John Rommel Estropia" => "rommel.estropia@gmail.com" }
s.source = { :git => "https://github.com/JohnEstropia/CoreStore.git", :tag => s.version.to_s }
s.ios.deployment_target = "10.0"
s.osx.deployment_target = "10.12"
s.watchos.deployment_target = "3.0"
s.tvos.deployment_target = "10.0"
s.ios.deployment_target = "16.0"
s.osx.deployment_target = "13.0"
s.tvos.deployment_target = "16.0"
s.watchos.deployment_target = "9.0"
s.source_files = "Sources", "Sources/**/*.{swift,h,m}"
s.source_files = "Sources", "Sources/**/*.swift"
s.public_header_files = "Sources/**/*.h"
s.frameworks = "Foundation", "CoreData"
s.requires_arc = true
s.pod_target_xcconfig = { 'OTHER_SWIFT_FLAGS[config=Debug]' => '-D DEBUG', 'OTHER_LDFLAGS' => '-weak_framework Combine -weak_framework SwiftUI' }
s.test_spec "CoreStoreTests" do |ts|
ts.source_files = "CoreStoreTests", "CoreStoreTests/**/*.swift", "CoreStoreTests/**/*.xcdatamodeld", "CoreStoreTests/**/*.xcdatamodel"
ts.public_header_files = "CoreStoreTests/**/*.h"
ts.resources = [ "CoreStoreTests/**/*.xcdatamodeld", "CoreStoreTests/**/*.xcdatamodel" ]
ts.preserve_paths = "CoreStoreTests/**/*.xcdatamodeld"
ts.resource_bundles = { 'CoreStoreTests' => ["CoreStoreTests/**/*.momd"] }
ts.frameworks = "Foundation", "CoreData"
ts.requires_arc = true
ts.ios.deployment_target = "13.0"
ts.osx.deployment_target = "10.15"
ts.tvos.deployment_target = "13.0"
end
end

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1600"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1600"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1600"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1600"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -20,6 +20,20 @@
ReferencedContainer = "container:CoreStore.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "NO"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B5114DA328CEEE5400EEAE78"
BuildableName = "CoreStoreTests.xctest"
BlueprintName = "CoreStoreTests watchOS"
ReferencedContainer = "container:CoreStore.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
@@ -28,6 +42,16 @@
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B5114DA328CEEE5400EEAE78"
BuildableName = "CoreStoreTests.xctest"
BlueprintName = "CoreStoreTests watchOS"
ReferencedContainer = "container:CoreStore.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction

View File

@@ -2,9 +2,9 @@
<Workspace
version = "1.0">
<FileRef
location = "group:CoreStore.xcodeproj">
location = "group:Demo/Demo.xcodeproj">
</FileRef>
<FileRef
location = "group:CoreStoreDemo/CoreStoreDemo.xcodeproj">
location = "group:CoreStore.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

View File

@@ -1,595 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
B50132242344E24300FC238B /* SwiftUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50132232344E24300FC238B /* SwiftUIView.swift */; };
B50132282344E5E900FC238B /* SwiftUIContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50132272344E5E900FC238B /* SwiftUIContainerViewController.swift */; };
B501323523477D2300FC238B /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B501323423477D2300FC238B /* SwiftUI.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
B503FADF1AFDC71700F90881 /* ListObserverDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADB1AFDC71700F90881 /* ListObserverDemoViewController.swift */; };
B503FAE01AFDC71700F90881 /* ObjectObserverDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADC1AFDC71700F90881 /* ObjectObserverDemoViewController.swift */; };
B503FAE11AFDC71700F90881 /* Palette.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADD1AFDC71700F90881 /* Palette.swift */; };
B503FAE21AFDC71700F90881 /* PaletteTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADE1AFDC71700F90881 /* PaletteTableViewCell.swift */; };
B5125C121B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = B5125C111B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel */; };
B52977D91B120B80003D50A5 /* ObserversViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52977D81B120B80003D50A5 /* ObserversViewController.swift */; };
B52977DD1B120F3B003D50A5 /* TransactionsDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52977DC1B120F3B003D50A5 /* TransactionsDemoViewController.swift */; };
B52977DF1B120F83003D50A5 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B52977DE1B120F83003D50A5 /* MapKit.framework */; };
B52977E11B120F8A003D50A5 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B52977E01B120F8A003D50A5 /* CoreLocation.framework */; };
B52977E41B121635003D50A5 /* Place.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52977E31B121635003D50A5 /* Place.swift */; };
B54AAD4F1AF4D26E00848AE0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54AAD4E1AF4D26E00848AE0 /* AppDelegate.swift */; };
B54AAD521AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B54AAD501AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodeld */; };
B54AAD591AF4D26E00848AE0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B54AAD571AF4D26E00848AE0 /* Main.storyboard */; };
B54AAD5B1AF4D26E00848AE0 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B54AAD5A1AF4D26E00848AE0 /* Images.xcassets */; };
B54AAD5E1AF4D26E00848AE0 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = B54AAD5C1AF4D26E00848AE0 /* LaunchScreen.xib */; };
B560070F1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B560070E1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift */; };
B5635D192357F9F700B80E6B /* CollectionViewDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5635D182357F9F700B80E6B /* CollectionViewDemoViewController.swift */; };
B5635D1B2357FA4B00B80E6B /* PaletteCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5635D1A2357FA4B00B80E6B /* PaletteCollectionViewCell.swift */; };
B566E32A1B117B1F00F4F0C6 /* StackSetupDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B566E3291B117B1F00F4F0C6 /* StackSetupDemoViewController.swift */; };
B566E3321B11DF3200F4F0C6 /* UserAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = B566E3311B11DF3200F4F0C6 /* UserAccount.swift */; };
B56964C91B20AC780075EE4A /* CustomLoggerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56964C81B20AC780075EE4A /* CustomLoggerViewController.swift */; };
B56964D71B231AE90075EE4A /* StackSetupDemo.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B56964D51B231AE90075EE4A /* StackSetupDemo.xcdatamodeld */; };
B56964DA1B231BCA0075EE4A /* MaleAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56964D91B231BCA0075EE4A /* MaleAccount.swift */; };
B56964DC1B231BCB0075EE4A /* FemaleAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56964DB1B231BCB0075EE4A /* FemaleAccount.swift */; };
B569650C1B2B36E10075EE4A /* FetchingAndQueryingDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B569650B1B2B36E10075EE4A /* FetchingAndQueryingDemoViewController.swift */; };
B56965181B2E20CC0075EE4A /* TimeZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56965171B2E20CC0075EE4A /* TimeZone.swift */; };
B569651A1B30888A0075EE4A /* FetchingResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56965191B30888A0075EE4A /* FetchingResultsViewController.swift */; };
B569651C1B30889A0075EE4A /* QueryingResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B569651B1B30889A0075EE4A /* QueryingResultsViewController.swift */; };
B56965291B3582D30075EE4A /* MigrationDemo.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B56965271B3582D30075EE4A /* MigrationDemo.xcdatamodeld */; };
B5AA37EF2357D30300FFD4B9 /* ColorsDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5AA37EE2357D30300FFD4B9 /* ColorsDemo.swift */; };
B5C37EE52357FEBE0035A20D /* PaletteCollectionSectionHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C37EE42357FEBE0035A20D /* PaletteCollectionSectionHeaderView.swift */; };
B5E599321B5240F50084BD5F /* OrganismTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E599311B5240F50084BD5F /* OrganismTableViewCell.swift */; };
B5E89AD01C5292A2003B04A9 /* CoreStore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5BDC9211C202429008147CD /* CoreStore.framework */; };
B5E89AD11C5292A2003B04A9 /* CoreStore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B5BDC9211C202429008147CD /* CoreStore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
B5EE25851B36E23C0000406B /* OrganismV1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE25841B36E23C0000406B /* OrganismV1.swift */; };
B5EE25871B36E2520000406B /* OrganismV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE25861B36E2520000406B /* OrganismV2.swift */; };
B5EE258C1B36E40D0000406B /* MigrationsDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE258B1B36E40D0000406B /* MigrationsDemoViewController.swift */; };
B5EE259B1B3EA4890000406B /* OrganismV3.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE259A1B3EA4890000406B /* OrganismV3.swift */; };
B5EE259E1B3EC1B20000406B /* OrganismProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE259D1B3EC1B20000406B /* OrganismProtocol.swift */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
B5E89ACF1C52929C003B04A9 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
B5E89AD11C5292A2003B04A9 /* CoreStore.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
B50132232344E24300FC238B /* SwiftUIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIView.swift; sourceTree = "<group>"; };
B50132272344E5E900FC238B /* SwiftUIContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIContainerViewController.swift; sourceTree = "<group>"; };
B501323423477D2300FC238B /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
B503FADB1AFDC71700F90881 /* ListObserverDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListObserverDemoViewController.swift; sourceTree = "<group>"; };
B503FADC1AFDC71700F90881 /* ObjectObserverDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectObserverDemoViewController.swift; sourceTree = "<group>"; };
B503FADD1AFDC71700F90881 /* Palette.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Palette.swift; sourceTree = "<group>"; };
B503FADE1AFDC71700F90881 /* PaletteTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaletteTableViewCell.swift; sourceTree = "<group>"; };
B5125C111B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = OrganismV2ToV3.xcmappingmodel; sourceTree = "<group>"; };
B5125C131B521BA7003A42C7 /* OrganismV3ToV2.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = OrganismV3ToV2.xcmappingmodel; sourceTree = "<group>"; };
B52977D81B120B80003D50A5 /* ObserversViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObserversViewController.swift; sourceTree = "<group>"; };
B52977DC1B120F3B003D50A5 /* TransactionsDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionsDemoViewController.swift; sourceTree = "<group>"; };
B52977DE1B120F83003D50A5 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; };
B52977E01B120F8A003D50A5 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
B52977E31B121635003D50A5 /* Place.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Place.swift; sourceTree = "<group>"; };
B54AAD491AF4D26E00848AE0 /* CoreStoreDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CoreStoreDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
B54AAD4D1AF4D26E00848AE0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
B54AAD4E1AF4D26E00848AE0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
B54AAD511AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = CoreStoreDemo.xcdatamodel; sourceTree = "<group>"; };
B54AAD581AF4D26E00848AE0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
B54AAD5A1AF4D26E00848AE0 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
B54AAD5D1AF4D26E00848AE0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
B560070E1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrganismV2ToV3MigrationPolicy.swift; sourceTree = "<group>"; };
B5635D182357F9F700B80E6B /* CollectionViewDemoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewDemoViewController.swift; sourceTree = "<group>"; };
B5635D1A2357FA4B00B80E6B /* PaletteCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaletteCollectionViewCell.swift; sourceTree = "<group>"; };
B566E3291B117B1F00F4F0C6 /* StackSetupDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StackSetupDemoViewController.swift; sourceTree = "<group>"; };
B566E3311B11DF3200F4F0C6 /* UserAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserAccount.swift; sourceTree = "<group>"; };
B56964C81B20AC780075EE4A /* CustomLoggerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomLoggerViewController.swift; sourceTree = "<group>"; };
B56964D61B231AE90075EE4A /* StackSetupDemo.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = StackSetupDemo.xcdatamodel; sourceTree = "<group>"; };
B56964D91B231BCA0075EE4A /* MaleAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaleAccount.swift; sourceTree = "<group>"; };
B56964DB1B231BCB0075EE4A /* FemaleAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FemaleAccount.swift; sourceTree = "<group>"; };
B569650B1B2B36E10075EE4A /* FetchingAndQueryingDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchingAndQueryingDemoViewController.swift; sourceTree = "<group>"; };
B56965171B2E20CC0075EE4A /* TimeZone.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimeZone.swift; sourceTree = "<group>"; };
B56965191B30888A0075EE4A /* FetchingResultsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchingResultsViewController.swift; sourceTree = "<group>"; };
B569651B1B30889A0075EE4A /* QueryingResultsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryingResultsViewController.swift; sourceTree = "<group>"; };
B56965281B3582D30075EE4A /* MigrationDemo.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MigrationDemo.xcdatamodel; sourceTree = "<group>"; };
B5AA37EE2357D30300FFD4B9 /* ColorsDemo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorsDemo.swift; sourceTree = "<group>"; };
B5BDC9211C202429008147CD /* CoreStore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CoreStore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
B5C37EE42357FEBE0035A20D /* PaletteCollectionSectionHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaletteCollectionSectionHeaderView.swift; sourceTree = "<group>"; };
B5E599311B5240F50084BD5F /* OrganismTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = OrganismTableViewCell.swift; path = "CoreStoreDemo/MIgrations Demo/OrganismTableViewCell.swift"; sourceTree = SOURCE_ROOT; };
B5EE25801B36E1B00000406B /* MigrationDemoV2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MigrationDemoV2.xcdatamodel; sourceTree = "<group>"; };
B5EE25841B36E23C0000406B /* OrganismV1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrganismV1.swift; sourceTree = "<group>"; };
B5EE25861B36E2520000406B /* OrganismV2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrganismV2.swift; sourceTree = "<group>"; };
B5EE25881B36E2750000406B /* MigrationDemoV3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MigrationDemoV3.xcdatamodel; sourceTree = "<group>"; };
B5EE258B1B36E40D0000406B /* MigrationsDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationsDemoViewController.swift; sourceTree = "<group>"; };
B5EE259A1B3EA4890000406B /* OrganismV3.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrganismV3.swift; sourceTree = "<group>"; };
B5EE259D1B3EC1B20000406B /* OrganismProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrganismProtocol.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
B54AAD461AF4D26E00848AE0 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
B501323523477D2300FC238B /* SwiftUI.framework in Frameworks */,
B5E89AD01C5292A2003B04A9 /* CoreStore.framework in Frameworks */,
B52977E11B120F8A003D50A5 /* CoreLocation.framework in Frameworks */,
B52977DF1B120F83003D50A5 /* MapKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
B50132222344E20B00FC238B /* SwiftUI Demo */ = {
isa = PBXGroup;
children = (
B50132232344E24300FC238B /* SwiftUIView.swift */,
B50132272344E5E900FC238B /* SwiftUIContainerViewController.swift */,
);
path = "SwiftUI Demo";
sourceTree = "<group>";
};
B503FADA1AFDC71700F90881 /* List and Object Observers Demo */ = {
isa = PBXGroup;
children = (
B5AA37EE2357D30300FFD4B9 /* ColorsDemo.swift */,
B52977D81B120B80003D50A5 /* ObserversViewController.swift */,
B503FADB1AFDC71700F90881 /* ListObserverDemoViewController.swift */,
B5635D182357F9F700B80E6B /* CollectionViewDemoViewController.swift */,
B503FADC1AFDC71700F90881 /* ObjectObserverDemoViewController.swift */,
B503FADD1AFDC71700F90881 /* Palette.swift */,
B503FADE1AFDC71700F90881 /* PaletteTableViewCell.swift */,
B5635D1A2357FA4B00B80E6B /* PaletteCollectionViewCell.swift */,
B5C37EE42357FEBE0035A20D /* PaletteCollectionSectionHeaderView.swift */,
);
path = "List and Object Observers Demo";
sourceTree = "<group>";
};
B52977DB1B120F2C003D50A5 /* Transactions Demo */ = {
isa = PBXGroup;
children = (
B52977E31B121635003D50A5 /* Place.swift */,
B52977DC1B120F3B003D50A5 /* TransactionsDemoViewController.swift */,
);
path = "Transactions Demo";
sourceTree = "<group>";
};
B52977E21B120F90003D50A5 /* Frameworks */ = {
isa = PBXGroup;
children = (
B501323423477D2300FC238B /* SwiftUI.framework */,
B52977E01B120F8A003D50A5 /* CoreLocation.framework */,
B5BDC9211C202429008147CD /* CoreStore.framework */,
B52977DE1B120F83003D50A5 /* MapKit.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
B54AAD401AF4D26E00848AE0 = {
isa = PBXGroup;
children = (
B52977E21B120F90003D50A5 /* Frameworks */,
B54AAD4B1AF4D26E00848AE0 /* CoreStoreDemo */,
B54AAD4A1AF4D26E00848AE0 /* Products */,
);
sourceTree = "<group>";
};
B54AAD4A1AF4D26E00848AE0 /* Products */ = {
isa = PBXGroup;
children = (
B54AAD491AF4D26E00848AE0 /* CoreStoreDemo.app */,
);
name = Products;
sourceTree = "<group>";
};
B54AAD4B1AF4D26E00848AE0 /* CoreStoreDemo */ = {
isa = PBXGroup;
children = (
B54AAD4E1AF4D26E00848AE0 /* AppDelegate.swift */,
B50132222344E20B00FC238B /* SwiftUI Demo */,
B566E3271B117AE700F4F0C6 /* Stack Setup Demo */,
B503FADA1AFDC71700F90881 /* List and Object Observers Demo */,
B52977DB1B120F2C003D50A5 /* Transactions Demo */,
B56965091B2B35370075EE4A /* Fetching and Querying Demo */,
B569652F1B3591460075EE4A /* Migrations Demo */,
B56964C61B20AC200075EE4A /* Loggers Demo */,
B54AAD571AF4D26E00848AE0 /* Main.storyboard */,
B54AAD5A1AF4D26E00848AE0 /* Images.xcassets */,
B54AAD5C1AF4D26E00848AE0 /* LaunchScreen.xib */,
B54AAD501AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodeld */,
B56964D51B231AE90075EE4A /* StackSetupDemo.xcdatamodeld */,
B56965271B3582D30075EE4A /* MigrationDemo.xcdatamodeld */,
B54AAD4C1AF4D26E00848AE0 /* Supporting Files */,
);
path = CoreStoreDemo;
sourceTree = "<group>";
};
B54AAD4C1AF4D26E00848AE0 /* Supporting Files */ = {
isa = PBXGroup;
children = (
B54AAD4D1AF4D26E00848AE0 /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
B566E3271B117AE700F4F0C6 /* Stack Setup Demo */ = {
isa = PBXGroup;
children = (
B56964DB1B231BCB0075EE4A /* FemaleAccount.swift */,
B56964D91B231BCA0075EE4A /* MaleAccount.swift */,
B566E3311B11DF3200F4F0C6 /* UserAccount.swift */,
B566E3291B117B1F00F4F0C6 /* StackSetupDemoViewController.swift */,
);
path = "Stack Setup Demo";
sourceTree = "<group>";
};
B56964C61B20AC200075EE4A /* Loggers Demo */ = {
isa = PBXGroup;
children = (
B56964C81B20AC780075EE4A /* CustomLoggerViewController.swift */,
);
path = "Loggers Demo";
sourceTree = "<group>";
};
B56965091B2B35370075EE4A /* Fetching and Querying Demo */ = {
isa = PBXGroup;
children = (
B56965171B2E20CC0075EE4A /* TimeZone.swift */,
B569650B1B2B36E10075EE4A /* FetchingAndQueryingDemoViewController.swift */,
B56965191B30888A0075EE4A /* FetchingResultsViewController.swift */,
B569651B1B30889A0075EE4A /* QueryingResultsViewController.swift */,
);
path = "Fetching and Querying Demo";
sourceTree = "<group>";
};
B569652F1B3591460075EE4A /* Migrations Demo */ = {
isa = PBXGroup;
children = (
B5EE259D1B3EC1B20000406B /* OrganismProtocol.swift */,
B5EE259A1B3EA4890000406B /* OrganismV3.swift */,
B5EE25861B36E2520000406B /* OrganismV2.swift */,
B5EE25841B36E23C0000406B /* OrganismV1.swift */,
B5EE258B1B36E40D0000406B /* MigrationsDemoViewController.swift */,
B5E599311B5240F50084BD5F /* OrganismTableViewCell.swift */,
B5125C111B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel */,
B560070E1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift */,
B5125C131B521BA7003A42C7 /* OrganismV3ToV2.xcmappingmodel */,
);
path = "Migrations Demo";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
B54AAD481AF4D26E00848AE0 /* CoreStoreDemo */ = {
isa = PBXNativeTarget;
buildConfigurationList = B54AAD6D1AF4D26E00848AE0 /* Build configuration list for PBXNativeTarget "CoreStoreDemo" */;
buildPhases = (
B54AAD451AF4D26E00848AE0 /* Sources */,
B54AAD461AF4D26E00848AE0 /* Frameworks */,
B54AAD471AF4D26E00848AE0 /* Resources */,
B5E89ACF1C52929C003B04A9 /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = CoreStoreDemo;
productName = CoreStoreDemo;
productReference = B54AAD491AF4D26E00848AE0 /* CoreStoreDemo.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
B54AAD411AF4D26E00848AE0 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0930;
ORGANIZATIONNAME = "John Rommel Estropia";
TargetAttributes = {
B54AAD481AF4D26E00848AE0 = {
CreatedOnToolsVersion = 6.3;
DevelopmentTeam = 2JT32EJ5BH;
LastSwiftMigration = 0900;
};
};
};
buildConfigurationList = B54AAD441AF4D26E00848AE0 /* Build configuration list for PBXProject "CoreStoreDemo" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = B54AAD401AF4D26E00848AE0;
productRefGroup = B54AAD4A1AF4D26E00848AE0 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
B54AAD481AF4D26E00848AE0 /* CoreStoreDemo */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
B54AAD471AF4D26E00848AE0 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B54AAD591AF4D26E00848AE0 /* Main.storyboard in Resources */,
B54AAD5E1AF4D26E00848AE0 /* LaunchScreen.xib in Resources */,
B54AAD5B1AF4D26E00848AE0 /* Images.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
B54AAD451AF4D26E00848AE0 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B56965181B2E20CC0075EE4A /* TimeZone.swift in Sources */,
B5C37EE52357FEBE0035A20D /* PaletteCollectionSectionHeaderView.swift in Sources */,
B56965291B3582D30075EE4A /* MigrationDemo.xcdatamodeld in Sources */,
B5E599321B5240F50084BD5F /* OrganismTableViewCell.swift in Sources */,
B5EE25851B36E23C0000406B /* OrganismV1.swift in Sources */,
B52977DD1B120F3B003D50A5 /* TransactionsDemoViewController.swift in Sources */,
B52977E41B121635003D50A5 /* Place.swift in Sources */,
B569650C1B2B36E10075EE4A /* FetchingAndQueryingDemoViewController.swift in Sources */,
B569651A1B30888A0075EE4A /* FetchingResultsViewController.swift in Sources */,
B5EE25871B36E2520000406B /* OrganismV2.swift in Sources */,
B503FAE01AFDC71700F90881 /* ObjectObserverDemoViewController.swift in Sources */,
B52977D91B120B80003D50A5 /* ObserversViewController.swift in Sources */,
B56964C91B20AC780075EE4A /* CustomLoggerViewController.swift in Sources */,
B5635D192357F9F700B80E6B /* CollectionViewDemoViewController.swift in Sources */,
B566E32A1B117B1F00F4F0C6 /* StackSetupDemoViewController.swift in Sources */,
B56964DA1B231BCA0075EE4A /* MaleAccount.swift in Sources */,
B566E3321B11DF3200F4F0C6 /* UserAccount.swift in Sources */,
B54AAD521AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodeld in Sources */,
B5EE259B1B3EA4890000406B /* OrganismV3.swift in Sources */,
B503FAE11AFDC71700F90881 /* Palette.swift in Sources */,
B503FAE21AFDC71700F90881 /* PaletteTableViewCell.swift in Sources */,
B560070F1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift in Sources */,
B503FADF1AFDC71700F90881 /* ListObserverDemoViewController.swift in Sources */,
B54AAD4F1AF4D26E00848AE0 /* AppDelegate.swift in Sources */,
B50132282344E5E900FC238B /* SwiftUIContainerViewController.swift in Sources */,
B5635D1B2357FA4B00B80E6B /* PaletteCollectionViewCell.swift in Sources */,
B56964D71B231AE90075EE4A /* StackSetupDemo.xcdatamodeld in Sources */,
B56964DC1B231BCB0075EE4A /* FemaleAccount.swift in Sources */,
B5AA37EF2357D30300FFD4B9 /* ColorsDemo.swift in Sources */,
B5EE259E1B3EC1B20000406B /* OrganismProtocol.swift in Sources */,
B5EE258C1B36E40D0000406B /* MigrationsDemoViewController.swift in Sources */,
B50132242344E24300FC238B /* SwiftUIView.swift in Sources */,
B569651C1B30889A0075EE4A /* QueryingResultsViewController.swift in Sources */,
B5125C121B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
B54AAD571AF4D26E00848AE0 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
B54AAD581AF4D26E00848AE0 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
B54AAD5C1AF4D26E00848AE0 /* LaunchScreen.xib */ = {
isa = PBXVariantGroup;
children = (
B54AAD5D1AF4D26E00848AE0 /* Base */,
);
name = LaunchScreen.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
B54AAD6B1AF4D26E00848AE0 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
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_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_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_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_SYMBOLS_PRIVATE_EXTERN = NO;
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 = 10.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
B54AAD6C1AF4D26E00848AE0 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
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_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_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 = 10.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 5.0;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
B54AAD6E1AF4D26E00848AE0 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = 2JT32EJ5BH;
INFOPLIST_FILE = CoreStoreDemo/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.corestore.demo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
};
name = Debug;
};
B54AAD6F1AF4D26E00848AE0 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = 2JT32EJ5BH;
INFOPLIST_FILE = CoreStoreDemo/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.corestore.demo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
B54AAD441AF4D26E00848AE0 /* Build configuration list for PBXProject "CoreStoreDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
B54AAD6B1AF4D26E00848AE0 /* Debug */,
B54AAD6C1AF4D26E00848AE0 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
B54AAD6D1AF4D26E00848AE0 /* Build configuration list for PBXNativeTarget "CoreStoreDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
B54AAD6E1AF4D26E00848AE0 /* Debug */,
B54AAD6F1AF4D26E00848AE0 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCVersionGroup section */
B54AAD501AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodeld */ = {
isa = XCVersionGroup;
children = (
B54AAD511AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodel */,
);
currentVersion = B54AAD511AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodel */;
path = CoreStoreDemo.xcdatamodeld;
sourceTree = "<group>";
versionGroupType = wrapper.xcdatamodel;
};
B56964D51B231AE90075EE4A /* StackSetupDemo.xcdatamodeld */ = {
isa = XCVersionGroup;
children = (
B56964D61B231AE90075EE4A /* StackSetupDemo.xcdatamodel */,
);
currentVersion = B56964D61B231AE90075EE4A /* StackSetupDemo.xcdatamodel */;
path = StackSetupDemo.xcdatamodeld;
sourceTree = "<group>";
versionGroupType = wrapper.xcdatamodel;
};
B56965271B3582D30075EE4A /* MigrationDemo.xcdatamodeld */ = {
isa = XCVersionGroup;
children = (
B5EE25881B36E2750000406B /* MigrationDemoV3.xcdatamodel */,
B5EE25801B36E1B00000406B /* MigrationDemoV2.xcdatamodel */,
B56965281B3582D30075EE4A /* MigrationDemo.xcdatamodel */,
);
currentVersion = B5EE25881B36E2750000406B /* MigrationDemoV3.xcdatamodel */;
path = MigrationDemo.xcdatamodeld;
sourceTree = "<group>";
versionGroupType = wrapper.xcdatamodel;
};
/* End XCVersionGroup section */
};
rootObject = B54AAD411AF4D26E00848AE0 /* Project object */;
}

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:CoreStoreDemo.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -1,53 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
<false/>
<key>IDESourceControlProjectIdentifier</key>
<string>B6855E48-4B19-4321-B1C7-CB2706E12777</string>
<key>IDESourceControlProjectName</key>
<string>CoreStoreDemo</string>
<key>IDESourceControlProjectOriginsDictionary</key>
<dict>
<key>4B60F1BCB491FF717C56441AE7783C74F417BE48</key>
<string>github.com:JohnEstropia/CoreStore.git</string>
<key>8B2E522D57154DFA93A06982C36315ECBEA4FA97</key>
<string>github.com:JohnEstropia/GCDKit.git</string>
</dict>
<key>IDESourceControlProjectPath</key>
<string>CoreStoreDemo/CoreStoreDemo.xcodeproj</string>
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
<dict>
<key>4B60F1BCB491FF717C56441AE7783C74F417BE48</key>
<string>../../..</string>
<key>8B2E522D57154DFA93A06982C36315ECBEA4FA97</key>
<string>../../..Libraries/GCDKit</string>
</dict>
<key>IDESourceControlProjectURL</key>
<string>github.com:JohnEstropia/CoreStore.git</string>
<key>IDESourceControlProjectVersion</key>
<integer>111</integer>
<key>IDESourceControlProjectWCCIdentifier</key>
<string>4B60F1BCB491FF717C56441AE7783C74F417BE48</string>
<key>IDESourceControlProjectWCConfigurations</key>
<array>
<dict>
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
<string>public.vcs.git</string>
<key>IDESourceControlWCCIdentifierKey</key>
<string>4B60F1BCB491FF717C56441AE7783C74F417BE48</string>
<key>IDESourceControlWCCName</key>
<string>CoreStore</string>
</dict>
<dict>
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
<string>public.vcs.git</string>
<key>IDESourceControlWCCIdentifierKey</key>
<string>8B2E522D57154DFA93A06982C36315ECBEA4FA97</string>
<key>IDESourceControlWCCName</key>
<string>GCDKit</string>
</dict>
</array>
</dict>
</plist>

View File

@@ -1,30 +0,0 @@
{
"DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "4B60F1BCB491FF717C56441AE7783C74F417BE48",
"DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
},
"DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
"8B2E522D57154DFA93A06982C36315ECBEA4FA97" : 0,
"4B60F1BCB491FF717C56441AE7783C74F417BE48" : 0
},
"DVTSourceControlWorkspaceBlueprintIdentifierKey" : "B6855E48-4B19-4321-B1C7-CB2706E12777",
"DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
"8B2E522D57154DFA93A06982C36315ECBEA4FA97" : "CoreStoreLibraries\/GCDKit",
"4B60F1BCB491FF717C56441AE7783C74F417BE48" : "CoreStore"
},
"DVTSourceControlWorkspaceBlueprintNameKey" : "CoreStoreDemo",
"DVTSourceControlWorkspaceBlueprintVersion" : 203,
"DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "CoreStoreDemo\/CoreStoreDemo.xcodeproj",
"DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
{
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:JohnEstropia\/CoreStore.git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "4B60F1BCB491FF717C56441AE7783C74F417BE48"
},
{
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:JohnEstropia\/GCDKit.git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "8B2E522D57154DFA93A06982C36315ECBEA4FA97"
}
]
}

View File

@@ -1,53 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
<false/>
<key>IDESourceControlProjectIdentifier</key>
<string>7C5E31AC-5DD0-43DA-A5C6-AF73B4532D86</string>
<key>IDESourceControlProjectName</key>
<string>project</string>
<key>IDESourceControlProjectOriginsDictionary</key>
<dict>
<key>4B60F1BCB491FF717C56441AE7783C74F417BE48</key>
<string>github.com:JohnEstropia/HardcoreData.git</string>
<key>8B2E522D57154DFA93A06982C36315ECBEA4FA97</key>
<string>github.com:JohnEstropia/GCDKit.git</string>
</dict>
<key>IDESourceControlProjectPath</key>
<string>HardcoreDataDemo/HardcoreDataDemo.xcodeproj/project.xcworkspace</string>
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
<dict>
<key>4B60F1BCB491FF717C56441AE7783C74F417BE48</key>
<string>../../..</string>
<key>8B2E522D57154DFA93A06982C36315ECBEA4FA97</key>
<string>../../..Libraries/GCDKit</string>
</dict>
<key>IDESourceControlProjectURL</key>
<string>github.com:JohnEstropia/HardcoreData.git</string>
<key>IDESourceControlProjectVersion</key>
<integer>111</integer>
<key>IDESourceControlProjectWCCIdentifier</key>
<string>4B60F1BCB491FF717C56441AE7783C74F417BE48</string>
<key>IDESourceControlProjectWCConfigurations</key>
<array>
<dict>
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
<string>public.vcs.git</string>
<key>IDESourceControlWCCIdentifierKey</key>
<string>8B2E522D57154DFA93A06982C36315ECBEA4FA97</string>
<key>IDESourceControlWCCName</key>
<string>GCDKit</string>
</dict>
<dict>
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
<string>public.vcs.git</string>
<key>IDESourceControlWCCIdentifierKey</key>
<string>4B60F1BCB491FF717C56441AE7783C74F417BE48</string>
<key>IDESourceControlWCCName</key>
<string>HardcoreData</string>
</dict>
</array>
</dict>
</plist>

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges</key>
<true/>
<key>SnapshotAutomaticallyBeforeSignificantChanges</key>
<true/>
</dict>
</plist>

View File

@@ -1,26 +0,0 @@
//
// AppDelegate.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/02.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit
// MARK: - AppDelegate
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
// MARK: UIApplicationDelegate
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
return true
}
}

View File

@@ -1,52 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14283.14"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright © 2018 John Rommel Estropia. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
<rect key="frame" x="20" y="439" width="440" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.90744441747665405" green="0.9265514612197876" blue="0.93116652965545654" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="CoreStoreIcon" translatesAutoresizingMaskIntoConstraints="NO" id="q8C-V6-gXH">
<rect key="frame" x="155" y="83" width="170" height="170"/>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="CoreStore" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
<rect key="frame" x="20" y="273" width="440" height="57.5"/>
<fontDescription key="fontDescription" name="HelveticaNeue-UltraLight" family="Helvetica Neue" pointSize="50"/>
<color key="textColor" red="0.90744441747665405" green="0.9265514612197876" blue="0.93116652965545654" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="0.15542715787887573" green="0.2203737199306488" blue="0.2959403395652771" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
<constraint firstItem="q8C-V6-gXH" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" multiplier="0.7" id="QW6-8Y-w15"/>
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
<constraint firstItem="q8C-V6-gXH" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="fRb-1V-9iD"/>
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
<constraint firstItem="kId-c2-rCX" firstAttribute="top" secondItem="q8C-V6-gXH" secondAttribute="bottom" constant="20" id="s63-MP-ush"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="548" y="455"/>
</view>
</objects>
<resources>
<image name="CoreStoreIcon" width="170" height="170"/>
</resources>
</document>

View File

@@ -1,53 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<<<<<<< Updated upstream
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
=======
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9532" systemVersion="15D21" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9530"/>
>>>>>>> Stashed changes
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<<<<<<< Updated upstream
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright © 2015 John Rommel Estropia. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
<rect key="frame" x="20" y="439" width="441" height="21"/>
=======
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2015 John Rommel Estropia. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
<rect key="frame" x="20" y="439.5" width="441" height="20.5"/>
>>>>>>> Stashed changes
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.92549019607843142" green="0.94117647058823528" blue="0.94509803921568625" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="CoreStore" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
<rect key="frame" x="20" y="133" width="441" height="57.5"/>
<fontDescription key="fontDescription" name="HelveticaNeue-UltraLight" family="Helvetica Neue" pointSize="50"/>
<color key="textColor" red="0.92549019607843142" green="0.94117647058823528" blue="0.94509803921568625" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="0.20392156862745098" green="0.28627450980392155" blue="0.36862745098039218" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="548" y="455"/>
</view>
</objects>
</document>

File diff suppressed because it is too large Load Diff

View File

@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="15702" systemVersion="18G1012" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<entity name="Place" representedClassName="CoreStoreDemo.Place" syncable="YES">
<attribute name="latitude" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="longitude" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="subtitle" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="title" optional="YES" attributeType="String" syncable="YES"/>
</entity>
<entity name="TimeZone" representedClassName="CoreStoreDemo.TimeZone" syncable="YES">
<attribute name="abbreviation" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="daylightSavingTimeOffset" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="hasDaylightSavingTime" optional="YES" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="secondsFromGMT" optional="YES" attributeType="Integer 32" defaultValueString="0.0" usesScalarValueType="NO" syncable="YES"/>
</entity>
<configuration name="FetchingAndQueryingDemo">
<memberEntity name="TimeZone"/>
</configuration>
<configuration name="TransactionsDemo">
<memberEntity name="Place"/>
</configuration>
<elements>
<element name="Place" positionX="261" positionY="225" width="128" height="103"/>
<element name="TimeZone" positionX="297" positionY="270" width="128" height="120"/>
</elements>
</model>

View File

@@ -1,319 +0,0 @@
//
// FetchingAndQueryingDemoViewController.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/12.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit
import CoreStore
private struct Static {
static let timeZonesStack: DataStack = {
let dataStack = DataStack()
try! dataStack.addStorageAndWait(
SQLiteStore(
fileName: "TimeZoneDemo.sqlite",
configuration: "FetchingAndQueryingDemo",
localStorageOptions: .recreateStoreOnModelMismatch
)
)
_ = try? dataStack.perform(
synchronous: { (transaction) in
try transaction.deleteAll(From<TimeZone>())
for name in NSTimeZone.knownTimeZoneNames {
let rawTimeZone = NSTimeZone(name: name)!
let cachedTimeZone = transaction.create(Into<TimeZone>())
cachedTimeZone.name = rawTimeZone.name
cachedTimeZone.abbreviation = rawTimeZone.abbreviation ?? ""
cachedTimeZone.secondsFromGMT = Int32(rawTimeZone.secondsFromGMT)
cachedTimeZone.hasDaylightSavingTime = rawTimeZone.isDaylightSavingTime
cachedTimeZone.daylightSavingTimeOffset = rawTimeZone.daylightSavingTimeOffset
}
}
)
return dataStack
}()
}
// MARK: - FetchingAndQueryingDemoViewController
class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
// MARK: UIViewController
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if self.didAppearOnce {
return
}
self.didAppearOnce = true
let alert = UIAlertController(
title: "Fetch and Query Demo",
message: "This demo shows how to execute fetches and queries.\n\nEach menu item executes and displays a preconfigured fetch/query.",
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
if let indexPath = sender as? IndexPath {
switch segue.destination {
case let controller as FetchingResultsViewController:
let item = self.fetchingItems[indexPath.row]
controller.set(timeZones: item.fetch(), title: item.title)
case let controller as QueryingResultsViewController:
let item = self.queryingItems[indexPath.row]
controller.set(value: item.query(), title: item.title)
default:
break
}
}
}
// MARK: UITableViewDataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch self.segmentedControl?.selectedSegmentIndex {
case Section.fetching.rawValue?:
return self.fetchingItems.count
case Section.querying.rawValue?:
return self.queryingItems.count
default:
return 0
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell")!
switch self.segmentedControl?.selectedSegmentIndex {
case Section.fetching.rawValue?:
cell.textLabel?.text = self.fetchingItems[indexPath.row].title
case Section.querying.rawValue?:
cell.textLabel?.text = self.queryingItems[indexPath.row].title
default:
cell.textLabel?.text = nil
}
return cell
}
// MARK: UITableViewDelegate
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
switch self.segmentedControl?.selectedSegmentIndex {
case Section.fetching.rawValue?:
self.performSegue(withIdentifier: "FetchingResultsViewController", sender: indexPath)
case Section.querying.rawValue?:
self.performSegue(withIdentifier: "QueryingResultsViewController", sender: indexPath)
default:
break
}
}
// MARK: Private
private enum Section: Int {
case fetching
case querying
}
private let fetchingItems = [
(
title: "All Time Zones",
fetch: { () -> [TimeZone] in
return try! Static.timeZonesStack.fetchAll(
From<TimeZone>()
.orderBy(.ascending(\.name))
)
}
),
(
title: "Time Zones in Asia",
fetch: { () -> [TimeZone] in
return try! Static.timeZonesStack.fetchAll(
From<TimeZone>()
.where(
format: "%K BEGINSWITH[c] %@",
#keyPath(TimeZone.name),
"Asia"
)
.orderBy(.ascending(\.secondsFromGMT))
)
}
),
(
title: "Time Zones in America and Europe",
fetch: { () -> [TimeZone] in
return try! Static.timeZonesStack.fetchAll(
From<TimeZone>()
.where(
format: "%K BEGINSWITH[c] %@ OR %K BEGINSWITH[c] %@",
#keyPath(TimeZone.name),
"America",
#keyPath(TimeZone.name),
"Europe"
)
.orderBy(.ascending(\.secondsFromGMT))
)
}
),
(
title: "All Time Zones Except America",
fetch: { () -> [TimeZone] in
return try! Static.timeZonesStack.fetchAll(
From<TimeZone>()
.where(
format: "%K BEGINSWITH[c] %@",
#keyPath(TimeZone.name),
"America"
)
.orderBy(.ascending(\.secondsFromGMT))
)
}
),
(
title: "Time Zones with Summer Time",
fetch: { () -> [TimeZone] in
return try! Static.timeZonesStack.fetchAll(
From<TimeZone>()
.where(\.hasDaylightSavingTime == true)
.orderBy(.ascending(\.name))
)
}
)
]
private let queryingItems: [(title: String, query: () -> Any)] = [
(
title: "Number of Time Zones",
query: { () -> Any in
return try! Static.timeZonesStack.queryValue(
From<TimeZone>()
.select(NSNumber.self, .count(\.name))
)!
}
),
(
title: "Abbreviation For Tokyo's Time Zone",
query: { () -> Any in
return try! Static.timeZonesStack.queryValue(
From<TimeZone>()
.select(String.self, .attribute(\.abbreviation))
.where(format: "%K ENDSWITH[c] %@", #keyPath(TimeZone.name), "Tokyo")
)!
}
),
(
title: "All Abbreviations",
query: { () -> Any in
return try! Static.timeZonesStack.queryAttributes(
From<TimeZone>()
.select(
NSDictionary.self,
.attribute(\.name),
.attribute(\.abbreviation)
)
.orderBy(.ascending(\.name))
)
}
),
(
title: "Number of Countries per Time Zone",
query: { () -> Any in
return try! Static.timeZonesStack.queryAttributes(
From<TimeZone>()
.select(
NSDictionary.self,
.count(\.abbreviation),
.attribute(\.abbreviation)
)
.groupBy(\.abbreviation)
.orderBy(
.ascending(\.secondsFromGMT),
.ascending(\.name)
)
)
}
),
(
title: "Number of Countries with Summer Time",
query: { () -> Any in
return try! Static.timeZonesStack.queryAttributes(
From<TimeZone>()
.select(
NSDictionary.self,
.count(\.hasDaylightSavingTime, as: "numberOfCountries"),
.attribute(\.hasDaylightSavingTime)
)
.groupBy(\.hasDaylightSavingTime)
.orderBy(
.descending(\.hasDaylightSavingTime),
.ascending(\.name)
)
)
}
)
]
var didAppearOnce = false
@IBOutlet dynamic weak var segmentedControl: UISegmentedControl?
@IBOutlet dynamic weak var tableView: UITableView?
@IBAction dynamic func segmentedControlValueChanged(_ sender: AnyObject?) {
self.tableView?.reloadData()
}
}

View File

@@ -1,68 +0,0 @@
//
// FetchingResultsViewController.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/17.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit
// MARK: - FetchingResultsViewController
class FetchingResultsViewController: UITableViewController {
// MARK: Public
func set(timeZones: [TimeZone]?, title: String) {
self.timeZones += timeZones ?? []
self.sectionTitle = title
self.tableView?.reloadData()
}
// MARK: UIViewController
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.estimatedRowHeight = 60
self.tableView.rowHeight = UITableView.automaticDimension
}
// MARK: UITableViewDataSource
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.timeZones.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath)
let timeZone = self.timeZones[indexPath.row]
cell.textLabel?.text = timeZone.name
cell.detailTextLabel?.text = timeZone.abbreviation
return cell
}
// MARK: UITableViewDelegate
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return self.sectionTitle
}
// MARK: Private
var timeZones = [TimeZone]()
var sectionTitle: String?
}

View File

@@ -1,88 +0,0 @@
//
// QueryingResultsViewController.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/17.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit
class QueryingResultsViewController: UITableViewController {
// MARK: Public
func set(value: Any?, title: String) {
switch value {
case (let array as [Any])?:
self.values = array.map { (item: Any) -> (title: String, detail: String) in
(
title: String(describing: item),
detail: String(reflecting: type(of: item))
)
}
case let item?:
self.values = [
(
title: String(describing: item),
detail: String(reflecting: type(of: item))
)
]
default:
self.values = []
}
self.sectionTitle = title
self.tableView?.reloadData()
}
// MARK: UIViewController
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.estimatedRowHeight = 60
self.tableView.rowHeight = UITableView.automaticDimension
}
// MARK: UITableViewDataSource
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.values.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath)
let value = self.values[indexPath.row]
cell.textLabel?.text = value.title
cell.detailTextLabel?.text = value.detail
return cell
}
// MARK: UITableViewDelegate
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return self.sectionTitle
}
// MARK: Private
var values: [(title: String, detail: String)] = []
var sectionTitle: String?
}

View File

@@ -1,20 +0,0 @@
//
// TimeZone.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/15.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import Foundation
import CoreData
class TimeZone: NSManagedObject {
@NSManaged var secondsFromGMT: Int32
@NSManaged var abbreviation: String
@NSManaged var hasDaylightSavingTime: Bool
@NSManaged var daylightSavingTimeOffset: Double
@NSManaged var name: String
}

View File

@@ -1,6 +0,0 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -1,21 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "CoreStoreIcon@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -1,12 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "first.pdf"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -1,12 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "second.pdf"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -1,169 +0,0 @@
//
// CollectionViewDemoViewController.swift
// CoreStoreDemo
//
// Created by John Estropia on 2019/10/17.
// Copyright © 2019 John Rommel Estropia. All rights reserved.
//
import UIKit
import CoreStore
// MARK: - CollectionViewDemoViewController
final class CollectionViewDemoViewController: UICollectionViewController {
// MARK: UIViewController
override func viewDidLoad() {
super.viewDidLoad()
let navigationItem = self.navigationItem
navigationItem.leftBarButtonItems = [
self.editButtonItem,
UIBarButtonItem(
barButtonSystemItem: .trash,
target: self,
action: #selector(self.resetBarButtonItemTouched(_:))
)
]
let filterBarButton = UIBarButtonItem(
title: ColorsDemo.filter.rawValue,
style: .plain,
target: self,
action: #selector(self.filterBarButtonItemTouched(_:))
)
navigationItem.rightBarButtonItems = [
UIBarButtonItem(
barButtonSystemItem: .add,
target: self,
action: #selector(self.addBarButtonItemTouched(_:))
),
UIBarButtonItem(
barButtonSystemItem: .refresh,
target: self,
action: #selector(self.shuffleBarButtonItemTouched(_:))
),
filterBarButton
]
self.filterBarButton = filterBarButton
self.dataSource = DiffableDataSource.CollectionViewAdapter<Palette>(
collectionView: self.collectionView,
dataStack: ColorsDemo.stack,
cellProvider: { (collectionView, indexPath, palette) in
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PaletteCollectionViewCell", for: indexPath) as! PaletteCollectionViewCell
cell.colorView?.backgroundColor = palette.color
cell.label?.text = palette.colorText
return cell
},
supplementaryViewProvider: { (collectionView, kind, indexPath) in
switch kind {
case UICollectionView.elementKindSectionHeader:
let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "PaletteCollectionSectionHeaderView", for: indexPath) as! PaletteCollectionSectionHeaderView
view.label?.text = ColorsDemo.palettes.snapshot.sectionIDs[indexPath.section]
return view
default:
return nil
}
}
)
ColorsDemo.palettes.addObserver(self) { [weak self] (listPublisher) in
guard let self = self else {
return
}
self.filterBarButton?.title = ColorsDemo.filter.rawValue
self.dataSource?.apply(listPublisher.snapshot, animatingDifferences: true)
}
self.dataSource?.apply(ColorsDemo.palettes.snapshot, animatingDifferences: false)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
switch (segue.identifier, segue.destination, sender) {
case ("ObjectObserverDemoViewController"?, let destinationViewController as ObjectObserverDemoViewController, let palette as ObjectPublisher<Palette>):
destinationViewController.setPalette(palette)
default:
break
}
}
// MARK: UICollectionViewDelegate
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionView.deselectItem(at: indexPath, animated: true)
self.performSegue(
withIdentifier: "ObjectObserverDemoViewController",
sender: ColorsDemo.palettes.snapshot[indexPath]
)
}
// MARK: Private
private var filterBarButton: UIBarButtonItem?
private var dataSource: DiffableDataSource.CollectionViewAdapter<Palette>?
deinit {
ColorsDemo.palettes.removeObserver(self)
}
@IBAction private dynamic func resetBarButtonItemTouched(_ sender: AnyObject?) {
ColorsDemo.stack.perform(
asynchronous: { (transaction) in
try transaction.deleteAll(From<Palette>())
},
completion: { _ in }
)
}
@IBAction private dynamic func filterBarButtonItemTouched(_ sender: AnyObject?) {
ColorsDemo.filter = ColorsDemo.filter.next()
}
@IBAction private dynamic func addBarButtonItemTouched(_ sender: AnyObject?) {
ColorsDemo.stack.perform(
asynchronous: { (transaction) in
let palette = transaction.create(Into<Palette>())
palette.setInitialValues(in: transaction)
},
completion: { _ in }
)
}
@IBAction private dynamic func shuffleBarButtonItemTouched(_ sender: AnyObject?) {
ColorsDemo.stack.perform(
asynchronous: { (transaction) in
for palette in try transaction.fetchAll(From<Palette>()) {
palette.hue .= Palette.randomHue()
palette.colorName .= nil
}
},
completion: { _ in }
)
}
}

View File

@@ -1,88 +0,0 @@
//
// ColorsDemo.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2019/10/17.
// Copyright © 2019 John Rommel Estropia. All rights reserved.
//
import Foundation
import CoreStore
// MARK: - ColorsDemo
struct ColorsDemo {
enum Filter: String {
case all = "All Colors"
case light = "Light Colors"
case dark = "Dark Colors"
func next() -> Filter {
switch self {
case .all: return .light
case .light: return .dark
case .dark: return .all
}
}
func whereClause() -> Where<Palette> {
switch self {
case .all: return .init()
case .light: return (\Palette.brightness >= 0.9)
case .dark: return (\Palette.brightness <= 0.4)
}
}
}
static var filter = Filter.all {
didSet {
try! self.palettes.refetch(
From<Palette>()
.sectionBy(\.colorName)
.where(self.filter.whereClause())
.orderBy(.ascending(\.hue))
)
}
}
static let stack: DataStack = {
let dataStack = DataStack(
CoreStoreSchema(
modelVersion: "ColorsDemo",
entities: [
Entity<Palette>("Palette"),
],
versionLock: [
"Palette": [0x8c25aa53c7c90a28, 0xa243a34d25f1a3a7, 0x56565b6935b6055a, 0x4f988bb257bf274f]
]
)
)
try! dataStack.addStorageAndWait(
SQLiteStore(
fileName: "ColorsDemo.sqlite",
localStorageOptions: .recreateStoreOnModelMismatch
)
)
return dataStack
}()
static let palettes: ListPublisher<Palette> = {
return ColorsDemo.stack.publishList(
From<Palette>()
.sectionBy(\.colorName)
.orderBy(.ascending(\.hue))
)
}()
}

View File

@@ -1,182 +0,0 @@
//
// ListObserverDemoViewController.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/02.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit
import CoreStore
// MARK: - ListObserverDemoViewController
final class ListObserverDemoViewController: UITableViewController {
// MARK: - EditableDataSource
final class EditableDataSource: DiffableDataSource.TableViewAdapter<Palette> {
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
switch editingStyle {
case .delete:
let palette = ColorsDemo.palettes.snapshot[indexPath]
ColorsDemo.stack.perform(
asynchronous: { (transaction) in
transaction.delete(palette)
},
completion: { _ in }
)
default:
break
}
}
}
// MARK: UIViewController
override func viewDidLoad() {
super.viewDidLoad()
let navigationItem = self.navigationItem
navigationItem.leftBarButtonItems = [
self.editButtonItem,
UIBarButtonItem(
barButtonSystemItem: .trash,
target: self,
action: #selector(self.resetBarButtonItemTouched(_:))
)
]
let filterBarButton = UIBarButtonItem(
title: ColorsDemo.filter.rawValue,
style: .plain,
target: self,
action: #selector(self.filterBarButtonItemTouched(_:))
)
navigationItem.rightBarButtonItems = [
UIBarButtonItem(
barButtonSystemItem: .add,
target: self,
action: #selector(self.addBarButtonItemTouched(_:))
),
UIBarButtonItem(
barButtonSystemItem: .refresh,
target: self,
action: #selector(self.shuffleBarButtonItemTouched(_:))
),
filterBarButton
]
self.filterBarButton = filterBarButton
self.dataSource = EditableDataSource(
tableView: self.tableView,
dataStack: ColorsDemo.stack,
cellProvider: { (tableView, indexPath, palette) in
let cell = tableView.dequeueReusableCell(withIdentifier: "PaletteTableViewCell") as! PaletteTableViewCell
cell.colorView?.backgroundColor = palette.color
cell.label?.text = palette.colorText
return cell
}
)
ColorsDemo.palettes.addObserver(self) { [weak self] (listPublisher) in
guard let self = self else {
return
}
self.filterBarButton?.title = ColorsDemo.filter.rawValue
self.dataSource?.apply(listPublisher.snapshot, animatingDifferences: true)
}
self.dataSource?.apply(ColorsDemo.palettes.snapshot, animatingDifferences: false)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
switch (segue.identifier, segue.destination, sender) {
case ("ObjectObserverDemoViewController"?, let destinationViewController as ObjectObserverDemoViewController, let palette as ObjectPublisher<Palette>):
destinationViewController.setPalette(palette)
default:
break
}
}
// MARK: UITableViewDelegate
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
self.performSegue(
withIdentifier: "ObjectObserverDemoViewController",
sender: ColorsDemo.palettes.snapshot[indexPath]
)
}
// MARK: Private
private var filterBarButton: UIBarButtonItem?
private var dataSource: DiffableDataSource.TableViewAdapter<Palette>?
deinit {
ColorsDemo.palettes.removeObserver(self)
}
@IBAction private dynamic func resetBarButtonItemTouched(_ sender: AnyObject?) {
ColorsDemo.stack.perform(
asynchronous: { (transaction) in
try transaction.deleteAll(From<Palette>())
},
completion: { _ in }
)
}
@IBAction private dynamic func filterBarButtonItemTouched(_ sender: AnyObject?) {
ColorsDemo.filter = ColorsDemo.filter.next()
}
@IBAction private dynamic func addBarButtonItemTouched(_ sender: AnyObject?) {
ColorsDemo.stack.perform(
asynchronous: { (transaction) in
let palette = transaction.create(Into<Palette>())
palette.setInitialValues(in: transaction)
},
completion: { _ in }
)
}
@IBAction private dynamic func shuffleBarButtonItemTouched(_ sender: AnyObject?) {
ColorsDemo.stack.perform(
asynchronous: { (transaction) in
for palette in try transaction.fetchAll(From<Palette>()) {
palette.hue .= Palette.randomHue()
palette.colorName .= nil
}
},
completion: { _ in }
)
}
}

View File

@@ -1,193 +0,0 @@
//
// ObjectObserverDemoViewController.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/06.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit
import CoreStore
// MARK: - ObjectObserverDemoViewController
class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
func setPalette<O: ObjectRepresentation>(_ newValue: O?) where O.ObjectType == Palette {
guard self.monitor?.object?.objectID() != newValue?.objectID() else {
return
}
if let newValue = newValue {
self.monitor = newValue.asReadOnly(in: ColorsDemo.stack).map(ColorsDemo.stack.monitorObject(_:))
}
else {
self.monitor = nil
}
}
// MARK: NSObject
deinit {
self.monitor?.removeObserver(self)
}
// MARK: UIViewController
required init?(coder aDecoder: NSCoder) {
if let palette = try! ColorsDemo.stack.fetchOne(From<Palette>().orderBy(.ascending(\.hue))) {
self.monitor = ColorsDemo.stack.monitorObject(palette)
}
else {
_ = try? ColorsDemo.stack.perform(
synchronous: { (transaction) in
let palette = transaction.create(Into<Palette>())
palette.setInitialValues(in: transaction)
}
)
let palette = try! ColorsDemo.stack.fetchOne(From<Palette>().orderBy(.ascending(\.hue)))!
self.monitor = ColorsDemo.stack.monitorObject(palette)
}
super.init(coder: aDecoder)
}
override func viewDidLoad() {
super.viewDidLoad()
self.monitor?.addObserver(self)
if let palette = self.monitor?.object {
self.reloadPaletteInfo(palette, changedKeys: nil)
}
}
// MARK: ObjectObserver
func objectMonitor(_ monitor: ObjectMonitor<Palette>, didUpdateObject object: Palette, changedPersistentKeys: Set<KeyPathString>) {
self.reloadPaletteInfo(object, changedKeys: changedPersistentKeys)
}
func objectMonitor(_ monitor: ObjectMonitor<Palette>, didDeleteObject object: Palette) {
self.navigationItem.rightBarButtonItem?.isEnabled = false
self.colorNameLabel?.alpha = 0.3
self.colorView?.alpha = 0.3
self.hsbLabel?.text = "Deleted"
self.hsbLabel?.textColor = UIColor.red
self.hueSlider?.isEnabled = false
self.saturationSlider?.isEnabled = false
self.brightnessSlider?.isEnabled = false
}
// MARK: Private
var monitor: ObjectMonitor<Palette>?
@IBOutlet weak var colorNameLabel: UILabel?
@IBOutlet weak var colorView: UIView?
@IBOutlet weak var hsbLabel: UILabel?
@IBOutlet weak var dateLabel: UILabel?
@IBOutlet weak var hueSlider: UISlider?
@IBOutlet weak var saturationSlider: UISlider?
@IBOutlet weak var brightnessSlider: UISlider?
@IBAction dynamic func hueSliderValueDidChange(_ sender: AnyObject?) {
let hue = self.hueSlider?.value ?? 0
ColorsDemo.stack.perform(
asynchronous: { [weak self] (transaction) in
if let palette = transaction.edit(self?.monitor?.object) {
palette.hue .= Int(hue)
}
},
completion: { _ in }
)
}
@IBAction dynamic func saturationSliderValueDidChange(_ sender: AnyObject?) {
let saturation = self.saturationSlider?.value ?? 0
ColorsDemo.stack.perform(
asynchronous: { [weak self] (transaction) in
if let palette = transaction.edit(self?.monitor?.object) {
palette.saturation .= saturation
}
},
completion: { _ in }
)
}
@IBAction dynamic func brightnessSliderValueDidChange(_ sender: AnyObject?) {
let brightness = self.brightnessSlider?.value ?? 0
ColorsDemo.stack.perform(
asynchronous: { [weak self] (transaction) in
if let palette = transaction.edit(self?.monitor?.object) {
palette.brightness .= brightness
}
},
completion: { _ in }
)
}
@IBAction dynamic func deleteBarButtonTapped(_ sender: AnyObject?) {
ColorsDemo.stack.perform(
asynchronous: { [weak self] (transaction) in
transaction.delete(self?.monitor?.object)
},
completion: { _ in }
)
}
func reloadPaletteInfo(_ palette: Palette, changedKeys: Set<String>?) {
self.colorNameLabel?.text = palette.colorName.value
let color = palette.color
self.colorNameLabel?.textColor = color
self.colorView?.backgroundColor = color
self.hsbLabel?.text = palette.colorText
if changedKeys == nil || changedKeys?.contains(String(keyPath: \Palette.hue)) == true {
self.hueSlider?.value = Float(palette.hue.value)
}
if changedKeys == nil || changedKeys?.contains(String(keyPath: \Palette.saturation)) == true {
self.saturationSlider?.value = palette.saturation.value
}
if changedKeys == nil || changedKeys?.contains(String(keyPath: \Palette.brightness)) == true {
self.brightnessSlider?.value = palette.brightness.value
}
}
}

View File

@@ -1,59 +0,0 @@
//
// ObserversViewController.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit
// MARK: - ObserversViewController
class ObserversViewController: UIViewController {
// MARK: UIViewController
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let alert = UIAlertController(
title: "Observers Demo",
message: "This demo shows how to observe changes to a list of objects. The top and bottom view controllers both observe a single shared \"ListMonitor\" instance.\n\nTap on a row to see how to observe changes made to a single object using a \"ObjectMonitor\".",
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
// MARK: Private
@IBOutlet private dynamic weak var toggleTopBarButtonItem: UIBarButtonItem?
@IBOutlet private dynamic weak var toggleBottomBarButtonItem: UIBarButtonItem?
@IBOutlet private dynamic weak var stackView: UIStackView?
@IBOutlet private dynamic weak var topContainerView: UIView?
@IBOutlet private dynamic weak var bottomContainerView: UIView?
@IBAction private dynamic func toggleTopContainerView() {
UIView.animate(withDuration: 0.2) {
self.topContainerView!.isHidden.toggle()
}
self.toggleTopBarButtonItem!.isEnabled = !self.bottomContainerView!.isHidden
self.toggleBottomBarButtonItem!.isEnabled = !self.topContainerView!.isHidden
}
@IBAction private dynamic func toggleBottomContainerView() {
UIView.animate(withDuration: 0.2) {
self.bottomContainerView!.isHidden.toggle()
}
self.toggleTopBarButtonItem!.isEnabled = !self.bottomContainerView!.isHidden
self.toggleBottomBarButtonItem!.isEnabled = !self.topContainerView!.isHidden
}
}

View File

@@ -1,86 +0,0 @@
//
// Palette.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/05.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import Foundation
import UIKit
import CoreData
import CoreStore
// MARK: - Palette
final class Palette: CoreStoreObject {
let hue = Value.Required<Int>("hue", initial: 0)
let saturation = Value.Required<Float>("saturation", initial: 0)
let brightness = Value.Required<Float>("brightness", initial: 0)
let colorName = Value.Optional<String>(
"colorName",
isTransient: true,
customGetter: Palette.getColorName
)
static func randomHue() -> Int {
return Int(arc4random_uniform(360))
}
private static func getColorName(_ partialObject: PartialObject<Palette>) -> String? {
if let colorName = partialObject.primitiveValue(for: { $0.colorName }) {
return colorName
}
let colorName: String
switch partialObject.value(for: { $0.hue }) % 360 {
case 0 ..< 20: colorName = "Lower Reds"
case 20 ..< 57: colorName = "Oranges and Browns"
case 57 ..< 90: colorName = "Yellow-Greens"
case 90 ..< 159: colorName = "Greens"
case 159 ..< 197: colorName = "Blue-Greens"
case 197 ..< 241: colorName = "Blues"
case 241 ..< 297: colorName = "Violets"
case 297 ..< 331: colorName = "Magentas"
default: colorName = "Upper Reds"
}
partialObject.setPrimitiveValue(colorName, for: { $0.colorName })
return colorName
}
}
extension Palette {
var color: UIColor {
return UIColor(
hue: CGFloat(self.hue.value) / 360.0,
saturation: CGFloat(self.saturation.value),
brightness: CGFloat(self.brightness.value),
alpha: 1.0
)
}
var colorText: String {
return "H: \(self.hue.value)˚, S: \(round(self.saturation.value * 100.0))%, B: \(round(self.brightness.value * 100.0))%"
}
}
extension Palette {
func setInitialValues(in transaction: BaseDataTransaction) {
self.hue .= Palette.randomHue()
self.saturation .= Float(1.0)
self.brightness .= Float(arc4random_uniform(70) + 30) / 100.0
}
}

View File

@@ -1,17 +0,0 @@
//
// PaletteCollectionSectionHeaderView.swift
// CoreStoreDemo
//
// Created by John Estropia on 2019/10/17.
// Copyright © 2019 John Rommel Estropia. All rights reserved.
//
import UIKit
// MARK: - PaletteCollectionSectionHeaderView
final class PaletteCollectionSectionHeaderView: UICollectionReusableView {
@IBOutlet weak var label: UILabel?
}

View File

@@ -1,18 +0,0 @@
//
// PaletteCollectionViewCell.swift
// CoreStoreDemo
//
// Created by John Estropia on 2019/10/17.
// Copyright © 2019 John Rommel Estropia. All rights reserved.
//
import UIKit
// MARK: - PaletteCollectionViewCell
final class PaletteCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var colorView: UIView?
@IBOutlet weak var label: UILabel?
}

View File

@@ -1,18 +0,0 @@
//
// PaletteTableViewCell.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/05.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit
// MARK: - PaletteTableViewCell
final class PaletteTableViewCell: UITableViewCell {
@IBOutlet weak var colorView: UIView?
@IBOutlet weak var label: UILabel?
}

View File

@@ -1,126 +0,0 @@
//
// CustomLoggerViewController.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/05.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit
import CoreStore
// MARK: - CustomLoggerViewController
class CustomLoggerViewController: UIViewController, CoreStoreLogger {
// MARK: NSObject
let dataStack = DataStack()
// MARK: UIViewController
override func viewDidLoad() {
super.viewDidLoad()
try! self.dataStack.addStorageAndWait(SQLiteStore(fileName: "emptyStore.sqlite"))
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
CoreStoreDefaults.logger = self
let alert = UIAlertController(
title: "Logger Demo",
message: "This demo shows how to plug-in any logging framework to CoreStore.\n\nThe view controller implements CoreStoreLogger and appends all logs to the text view.",
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
CoreStoreDefaults.logger = DefaultLogger()
}
// MARK: CoreStoreLogger
func log(level: LogLevel, message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) {
DispatchQueue.main.async { [weak self] in
let levelString: String
switch level {
case .trace: levelString = "Trace"
case .notice: levelString = "Notice"
case .warning: levelString = "Warning"
case .fatal: levelString = "Fatal"
}
self?.textView?.insertText("\((String(describing: fileName) as NSString).lastPathComponent):\(lineNumber) \(functionName)\n ↪︎ [Log:\(levelString)] \(message)\n\n")
}
}
func log(error: CoreStoreError, message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) {
DispatchQueue.main.async { [weak self] in
self?.textView?.insertText("\((String(describing: fileName) as NSString).lastPathComponent):\(lineNumber) \(functionName)\n ↪︎ [Error] \(message): \(error)\n\n")
}
}
func assert(_ condition: @autoclosure () -> Bool, message: @autoclosure () -> String, fileName: StaticString, lineNumber: Int, functionName: StaticString) {
if condition() {
return
}
let messageString = message()
DispatchQueue.main.async { [weak self] in
self?.textView?.insertText("\((String(describing: fileName) as NSString).lastPathComponent):\(lineNumber) \(functionName)\n ↪︎ [Assert] \(messageString)\n\n")
}
}
// MARK: Private
@IBOutlet dynamic weak var textView: UITextView?
@IBOutlet dynamic weak var segmentedControl: UISegmentedControl?
@IBAction dynamic func segmentedControlValueChanged(_ sender: AnyObject?) {
switch self.segmentedControl?.selectedSegmentIndex {
case 0?:
let request = NSFetchRequest<NSFetchRequestResult>()
Where<NSManagedObject>(true).applyToFetchRequest(request)
Where<NSManagedObject>(false).applyToFetchRequest(request)
case 1?:
_ = try? dataStack.addStorageAndWait(
SQLiteStore(
fileName: "emptyStore.sqlite",
configuration: "invalidStore"
)
)
case 2?:
DispatchQueue.global(qos: .background).async {
_ = try! self.dataStack.fetchOne(From<Place>())
}
default:
return
}
}
}

View File

@@ -1,445 +0,0 @@
//
// MigrationsDemoViewController.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/21.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit
import CoreStore
// MARK: - MigrationsDemoViewController
class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewDataSource, UITableViewDelegate {
// MARK: UIViewController
override func viewDidLoad() {
super.viewDidLoad()
if let segmentedControl = self.segmentedControl {
for (index, model) in self.models.enumerated() {
segmentedControl.setTitle(
model.label,
forSegmentAt: index
)
}
}
self.set(dataStack: nil, model: nil, scrollToSelection: false)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let alert = UIAlertController(
title: "Migrations Demo",
message: "This demo shows how to run progressive migrations and how to support multiple model versions in a single project.\n\nThe persistent store contains 10000 organisms, which gain/lose properties when the migration evolves/devolves them.\n\nYou can use the \"mutate\" button to change an organism's properties then migrate to a different model to see how its value gets affected.",
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
let modelMetadata = withExtendedLifetime(DataStack(xcodeModelName: "MigrationDemo")) {
(dataStack: DataStack) -> ModelMetadata in
let models = self.models
let migrations = try! dataStack.requiredMigrationsForStorage(
SQLiteStore(fileName: "MigrationDemo.sqlite")
)
guard let storeVersion = migrations.first?.sourceVersion else {
return models.first!
}
for model in models {
if model.schemaHistory.currentModelVersion == storeVersion {
return model
}
}
return models.first!
}
self.selectModelVersion(modelMetadata)
}
// MARK: ListObserver
func listMonitorWillChange(_ monitor: ListMonitor<NSManagedObject>) { }
func listMonitorDidChange(_ monitor: ListMonitor<NSManagedObject>) {
if self.lastSelectedIndexPath == nil,
let numberOfObjectsInSection = self.listMonitor?.numberOfObjects(in: 0),
numberOfObjectsInSection > 0 {
self.tableView?.reloadData()
self.setSelectedIndexPath(IndexPath(row: 0, section: 0), scrollToSelection: false)
}
else {
self.updateDisplay(reloadData: true, scrollToSelection: true, animated: true)
}
}
func listMonitorDidRefetch(_ monitor: ListMonitor<NSManagedObject>) {
self.listMonitorDidChange(monitor)
}
// MARK: UITableViewDataSource
@objc dynamic func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.listMonitor?.numberOfObjects(in: 0) ?? 0
}
@objc dynamic func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "OrganismTableViewCell", for: indexPath) as! OrganismTableViewCell
let dna = (self.listMonitor?[indexPath] as? OrganismProtocol)?.dna.description ?? ""
cell.dnaLabel?.text = "DNA: \(dna)"
cell.mutateButtonHandler = { [weak self] () -> Void in
guard let `self` = self,
let dataStack = self.dataStack,
let organism = self.listMonitor?[indexPath] else {
return
}
self.setSelectedIndexPath(indexPath, scrollToSelection: false)
self.setEnabled(false)
dataStack.perform(
asynchronous: { (transaction) in
let organism = transaction.edit(organism) as! OrganismProtocol
organism.mutate()
},
completion: { [weak self] _ in
self?.setEnabled(true)
}
)
}
return cell
}
// MARK: UITableViewDelegate
@objc dynamic func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.setSelectedIndexPath(indexPath, scrollToSelection: false)
}
// MARK: Private
private typealias ModelMetadata = (label: String, entityType: NSManagedObject.Type, schemaHistory: SchemaHistory)
private let models: [ModelMetadata] = [
(
label: "Model V1",
entityType: OrganismV1.self,
schemaHistory: SchemaHistory(
XcodeDataModelSchema.from(
modelName: "MigrationDemo",
migrationChain: ["MigrationDemoV3", "MigrationDemoV2", "MigrationDemo"]
),
migrationChain: ["MigrationDemoV3", "MigrationDemoV2", "MigrationDemo"]
)
),
(
label: "Model V2",
entityType: OrganismV2.self,
schemaHistory: SchemaHistory(
XcodeDataModelSchema.from(
modelName: "MigrationDemo",
migrationChain: [
"MigrationDemo": "MigrationDemoV2",
"MigrationDemoV3": "MigrationDemoV2"
]
),
migrationChain: [
"MigrationDemo": "MigrationDemoV2",
"MigrationDemoV3": "MigrationDemoV2"
]
)
),
(
label: "Model V3",
entityType: OrganismV3.self,
schemaHistory: SchemaHistory(
XcodeDataModelSchema.from(
modelName: "MigrationDemo",
migrationChain: ["MigrationDemo", "MigrationDemoV2", "MigrationDemoV3"]
),
migrationChain: ["MigrationDemo", "MigrationDemoV2", "MigrationDemoV3"]
)
)
]
private var _listMonitor: ListMonitor<NSManagedObject>?
private var listMonitor: ListMonitor<NSManagedObject>? {
return self._listMonitor
}
private var _dataStack: DataStack?
private var dataStack: DataStack? {
return self._dataStack
}
private var _lastSelectedIndexPath: IndexPath?
private var lastSelectedIndexPath: IndexPath? {
return self._lastSelectedIndexPath
}
private func setSelectedIndexPath(_ indexPath: IndexPath, scrollToSelection: Bool) {
self._lastSelectedIndexPath = indexPath
self.updateDisplay(reloadData: false, scrollToSelection: scrollToSelection, animated: true)
}
@IBOutlet private dynamic weak var headerContainer: UIView?
@IBOutlet private dynamic weak var titleLabel: UILabel?
@IBOutlet private dynamic weak var organismLabel: UILabel?
@IBOutlet private dynamic weak var segmentedControl: UISegmentedControl?
@IBOutlet private dynamic weak var progressView: UIProgressView?
@IBOutlet private dynamic weak var tableView: UITableView?
@IBAction private dynamic func segmentedControlValueChanged(_ sender: AnyObject?) {
guard let index = self.segmentedControl?.selectedSegmentIndex else {
return
}
self.selectModelVersion(self.models[index])
}
private func selectModelVersion(_ model: ModelMetadata) {
if self.dataStack?.modelVersion == model.schemaHistory.currentModelVersion {
return
}
self.set(dataStack: nil, model: nil, scrollToSelection: false) // explicitly trigger NSPersistentStore cleanup by deallocating the stack
let dataStack = DataStack(schemaHistory: model.schemaHistory)
self.setEnabled(false)
let progress = dataStack.addStorage(
SQLiteStore(
fileName: "MigrationDemo.sqlite",
migrationMappingProviders: [
CustomSchemaMappingProvider(
from: "MigrationDemoV3",
to: "MigrationDemoV2",
entityMappings: [
.transformEntity(
sourceEntity: "Organism",
destinationEntity: "Organism",
transformer: { (source, createDestination) in
let destination = createDestination()
destination.enumerateAttributes { (attribute, sourceAttribute) in
if let sourceAttribute = sourceAttribute {
destination[attribute] = source[sourceAttribute]
}
}
destination["numberOfFlippers"] = source["numberOfLimbs"]
}
)
]
)
]
),
completion: { [weak self] (result) -> Void in
guard let `self` = self else {
return
}
guard case .success = result else {
self.setEnabled(true)
return
}
self.set(dataStack: dataStack, model: model, scrollToSelection: true)
let count = try! dataStack.queryValue(
From<NSManagedObject>(model.entityType)
.select(Int.self, .count(#keyPath(OrganismV1.dna))))!
if count > 0 {
self.setEnabled(true)
}
else {
for i: Int64 in 0 ..< 20 {
dataStack.perform(
asynchronous: { (transaction) in
for j: Int64 in 0 ..< 500 {
let organism = transaction.create(Into(model.entityType)) as! OrganismProtocol
organism.dna = (i * 500) + j + 1
organism.mutate()
}
},
completion: { _ in }
)
}
dataStack.perform(
asynchronous: { _ in },
completion: { [weak self] _ in
self?.setEnabled(true)
}
)
}
}
)
if let progress = progress {
progress.setProgressHandler { [weak self] (progress) -> Void in
self?.reloadTableHeaderWithProgress(progress)
}
}
}
private func setEnabled(_ enabled: Bool) {
UIView.animate(
withDuration: 0.2,
delay: 0,
options: .beginFromCurrentState,
animations: { () -> Void in
let navigationItem = self.navigationItem
navigationItem.leftBarButtonItem?.isEnabled = enabled
navigationItem.rightBarButtonItem?.isEnabled = enabled
navigationItem.hidesBackButton = !enabled
self.segmentedControl?.isEnabled = enabled
if let tableView = self.tableView {
tableView.alpha = enabled ? 1.0 : 0.5
tableView.isUserInteractionEnabled = enabled
}
},
completion: nil
)
}
private func set(dataStack: DataStack?, model: ModelMetadata?, scrollToSelection: Bool) {
if let dataStack = dataStack, let model = model {
self.segmentedControl?.selectedSegmentIndex = self.models
.firstIndex(
where: { (arg) -> Bool in
let (_, _, schemaHistory) = arg
return schemaHistory.currentModelVersion == model.schemaHistory.currentModelVersion
}
)!
self._dataStack = dataStack
let listMonitor = dataStack.monitorList(
From(model.entityType),
OrderBy<NSManagedObject>(.descending(#keyPath(OrganismV1.dna)))
)
listMonitor.addObserver(self)
self._listMonitor = listMonitor
if self.lastSelectedIndexPath == nil {
if listMonitor.numberOfObjects(in: 0) > 0 {
self.setSelectedIndexPath(IndexPath(row: 0, section: 0), scrollToSelection: true)
}
}
}
else {
self.segmentedControl?.selectedSegmentIndex = UISegmentedControl.noSegment
self._listMonitor = nil
self._dataStack = nil
}
self.updateDisplay(reloadData: true, scrollToSelection: scrollToSelection, animated: false)
}
private func reloadTableHeaderWithProgress(_ progress: Progress) {
self.progressView?.setProgress(Float(progress.fractionCompleted), animated: true)
self.titleLabel?.text = "Migrating: \(progress.localizedDescription ?? "")"
self.organismLabel?.text = "Progressive step \(progress.localizedAdditionalDescription ?? "")"
}
private func updateDisplay(reloadData: Bool, scrollToSelection: Bool, animated: Bool) {
var lines = [String]()
var organismType = ""
if let indexPath = self.lastSelectedIndexPath, let organism = self.listMonitor?[indexPath] {
for property in organism.entity.properties {
let value = organism.value(forKey: property.name) ?? NSNull()
lines.append("\(property.name): \(value)")
}
organismType = organism.entity.managedObjectClassName
}
self.titleLabel?.text = organismType
self.organismLabel?.text = lines.joined(separator: "\n")
self.progressView?.progress = 0
self.headerContainer?.setNeedsLayout()
guard let tableView = self.tableView else {
return
}
if reloadData {
tableView.reloadData()
}
tableView.layoutIfNeeded()
if let indexPath = self.lastSelectedIndexPath,
indexPath.row < tableView.numberOfRows(inSection: 0) {
tableView.selectRow(at: indexPath,
animated: scrollToSelection && animated,
scrollPosition: scrollToSelection ? .middle : .none
)
}
}
}

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="8166.2" systemVersion="14E46" minimumToolsVersion="Xcode 7.0">
<elements/>
</model>

View File

@@ -1,16 +0,0 @@
//
// OrganismProtocol.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/27.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import Foundation
protocol OrganismProtocol: AnyObject {
var dna: Int64 { get set }
func mutate()
}

View File

@@ -1,22 +0,0 @@
//
// OrganismTableViewCell.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/07/12.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit
class OrganismTableViewCell: UITableViewCell {
@IBOutlet weak dynamic var dnaLabel: UILabel?
@IBOutlet weak dynamic var mutateButton: UIButton?
var mutateButtonHandler: (() -> Void)?
@IBAction dynamic func mutateButtonTouchUpInside(_ sender: UIButton?) {
self.mutateButtonHandler?()
}
}

View File

@@ -1,25 +0,0 @@
//
// OrganismV1.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/21.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import Foundation
import CoreData
class OrganismV1: NSManagedObject, OrganismProtocol {
@NSManaged var dna: Int64
@NSManaged var hasHead: Bool
@NSManaged var hasTail: Bool
// MARK: OrganismProtocol
func mutate() {
self.hasHead = arc4random_uniform(2) == 1
self.hasTail = arc4random_uniform(2) == 1
}
}

View File

@@ -1,27 +0,0 @@
//
// OrganismV2.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/21.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import Foundation
import CoreData
class OrganismV2: NSManagedObject, OrganismProtocol {
@NSManaged var dna: Int64
@NSManaged var hasHead: Bool
@NSManaged var hasTail: Bool
@NSManaged var numberOfFlippers: Int32
// MARK: OrganismProtocol
func mutate() {
self.hasHead = arc4random_uniform(2) == 1
self.hasTail = arc4random_uniform(2) == 1
self.numberOfFlippers = Int32(arc4random_uniform(9) / 2 * 2)
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,29 +0,0 @@
//
// OrganismV2ToV3MigrationPolicy.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/27.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import CoreData
class OrganismV2ToV3MigrationPolicy: NSEntityMigrationPolicy {
override func createDestinationInstances(forSource sInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws {
try super.createDestinationInstances(forSource: sInstance, in: mapping, manager: manager)
for dInstance in manager.destinationInstances(forEntityMappingName: mapping.name, sourceInstances: [sInstance]) {
dInstance.setValue(
false,
forKey: #keyPath(OrganismV3.hasVertebrae)
)
dInstance.setValue(
sInstance.value(forKey: #keyPath(OrganismV2.numberOfFlippers)),
forKey: #keyPath(OrganismV3.numberOfLimbs)
)
}
}
}

View File

@@ -1,29 +0,0 @@
//
// OrganismV3.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/27.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import Foundation
import CoreData
class OrganismV3: NSManagedObject, OrganismProtocol {
@NSManaged var dna: Int64
@NSManaged var hasHead: Bool
@NSManaged var hasTail: Bool
@NSManaged var numberOfLimbs: Int32
@NSManaged var hasVertebrae: Bool
// MARK: OrganismProtocol
func mutate() {
self.hasHead = arc4random_uniform(2) == 1
self.hasTail = arc4random_uniform(2) == 1
self.numberOfLimbs = Int32(arc4random_uniform(9) / 2 * 2)
self.hasVertebrae = arc4random_uniform(2) == 1
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="11198.3" systemVersion="15F34" minimumToolsVersion="Xcode 4.3" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="Organism" representedClassName="CoreStoreDemo.OrganismV1" syncable="YES">
<attribute name="dna" optional="YES" attributeType="Integer 64" usesScalarValueType="NO" syncable="YES"/>
<attribute name="hasHead" optional="YES" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
<attribute name="hasTail" optional="YES" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
</entity>
<elements>
<element name="Organism" positionX="-36" positionY="9" width="128" height="90"/>
</elements>
</model>

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="11198.3" systemVersion="15F34" minimumToolsVersion="Xcode 4.3" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="Organism" representedClassName="CoreStoreDemo.OrganismV2" syncable="YES">
<attribute name="dna" optional="YES" attributeType="Integer 64" usesScalarValueType="NO" syncable="YES"/>
<attribute name="hasHead" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
<attribute name="hasTail" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
<attribute name="numberOfFlippers" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
</entity>
<elements>
<element name="Organism" positionX="-36" positionY="9" width="128" height="105"/>
</elements>
</model>

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="12141" systemVersion="16E195" minimumToolsVersion="Xcode 4.3" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="Organism" representedClassName="CoreStoreDemo.OrganismV3" syncable="YES">
<attribute name="dna" optional="YES" attributeType="Integer 64" usesScalarValueType="NO" syncable="YES"/>
<attribute name="hasHead" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
<attribute name="hasTail" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
<attribute name="hasVertebrae" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
<attribute name="numberOfLimbs" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" elementID="numberOfFlippers" syncable="YES"/>
</entity>
<elements>
<element name="Organism" positionX="-36" positionY="9" width="128" height="120"/>
</elements>
</model>

View File

@@ -1,15 +0,0 @@
//
// FemaleAccount.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/06.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import Foundation
import CoreData
class FemaleAccount: UserAccount {
}

View File

@@ -1,15 +0,0 @@
//
// MaleAccount.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/06.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import Foundation
import CoreData
class MaleAccount: UserAccount {
}

View File

@@ -1,196 +0,0 @@
//
// StackSetupDemoViewController.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit
import CoreStore
private struct Static {
static let maleConfiguration = "MaleAccounts"
static let femaleConfiguration = "FemaleAccounts"
static let facebookStack: DataStack = {
let dataStack = DataStack(xcodeModelName: "StackSetupDemo")
try! dataStack.addStorageAndWait(
SQLiteStore(
fileName: "AccountsDemo_FB_Male.sqlite",
configuration: maleConfiguration,
localStorageOptions: .recreateStoreOnModelMismatch
)
)
try! dataStack.addStorageAndWait(
SQLiteStore(
fileName: "AccountsDemo_FB_Female.sqlite",
configuration: femaleConfiguration,
localStorageOptions: .recreateStoreOnModelMismatch
)
)
_ = try? dataStack.perform(
synchronous: { (transaction) in
try transaction.deleteAll(From<UserAccount>())
let account1 = transaction.create(Into<MaleAccount>(maleConfiguration))
account1.accountType = "Facebook"
account1.name = "John Smith HCD"
account1.friends = 42
let account2 = transaction.create(Into<FemaleAccount>(femaleConfiguration))
account2.accountType = "Facebook"
account2.name = "Jane Doe HCD"
account2.friends = 314
}
)
return dataStack
}()
static let twitterStack: DataStack = {
let dataStack = DataStack(xcodeModelName: "StackSetupDemo")
try! dataStack.addStorageAndWait(
SQLiteStore(
fileName: "AccountsDemo_TW_Male.sqlite",
configuration: maleConfiguration,
localStorageOptions: .recreateStoreOnModelMismatch
)
)
try! dataStack.addStorageAndWait(
SQLiteStore(
fileName: "AccountsDemo_TW_Female.sqlite",
configuration: femaleConfiguration,
localStorageOptions: .recreateStoreOnModelMismatch
)
)
_ = try? dataStack.perform(
synchronous: { (transaction) in
try transaction.deleteAll(From<UserAccount>())
let account1 = transaction.create(Into<MaleAccount>(maleConfiguration))
account1.accountType = "Twitter"
account1.name = "#johnsmith_hcd"
account1.friends = 7
let account2 = transaction.create(Into<FemaleAccount>(femaleConfiguration))
account2.accountType = "Twitter"
account2.name = "#janedoe_hcd"
account2.friends = 100
}
)
return dataStack
}()
}
// MARK: - StackSetupDemoViewController
class StackSetupDemoViewController: UITableViewController {
let accounts = [
try! Static.facebookStack.fetchAll(From<UserAccount>()),
try! Static.twitterStack.fetchAll(From<UserAccount>())
]
// MARK: UIViewController
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.tableView.reloadData()
let indexPath = IndexPath(row: 0, section: 0)
self.tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
self.updateDetails(account: self.accounts[indexPath.section][indexPath.row])
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let alert = UIAlertController(
title: "Setup Demo",
message: "This demo shows how to initialize 2 DataStacks with 2 configurations each, for a total of 4 SQLite files, each with 1 instance of a \"UserAccount\" entity.",
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
// MARK: UITableViewDataSource
override func numberOfSections(in tableView: UITableView) -> Int {
return self.accounts.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.accounts[section].count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell")!
let account = self.accounts[indexPath.section][indexPath.row]
cell.textLabel?.text = account.name
cell.detailTextLabel?.text = "\(account.friends) friends"
return cell
}
// MARK: UITableViewDelegate
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let account = self.accounts[indexPath.section][indexPath.row]
self.updateDetails(account: account)
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
switch section {
case 0:
let count = self.accounts[section].count
return "Facebook Accounts (\(count) users)"
case 1:
let count = self.accounts[section].count
return "Twitter Accounts (\(count) users)"
default:
return nil
}
}
// MARK: Private
@IBOutlet private dynamic weak var accountTypeLabel: UILabel?
@IBOutlet private dynamic weak var nameLabel: UILabel?
@IBOutlet private dynamic weak var friendsLabel: UILabel?
private func updateDetails(account: UserAccount) {
self.accountTypeLabel?.text = account.accountType
self.nameLabel?.text = account.name
self.friendsLabel?.text = "\(account.friends) friends"
}
}

View File

@@ -1,20 +0,0 @@
//
// UserAccount.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import Foundation
import CoreData
// MARK: - UserAccount
class UserAccount: NSManagedObject {
@NSManaged var accountType: String?
@NSManaged var name: String?
@NSManaged var friends: Int32
}

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="7701" systemVersion="14D136" minimumToolsVersion="Xcode 4.3" macOSVersion="Automatic" iOSVersion="Automatic">
<entity name="FemaleAccount" representedClassName="CoreStoreDemo.FemaleAccount" parentEntity="UserAccount" syncable="YES"/>
<entity name="MaleAccount" representedClassName="CoreStoreDemo.MaleAccount" parentEntity="UserAccount" syncable="YES"/>
<entity name="UserAccount" representedClassName="CoreStoreDemo.UserAccount" isAbstract="YES" syncable="YES">
<attribute name="accountType" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="friends" optional="YES" attributeType="Integer 32" defaultValueString="0" syncable="YES"/>
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
</entity>
<configuration name="FemaleAccounts">
<memberEntity name="FemaleAccount"/>
<memberEntity name="UserAccount"/>
</configuration>
<configuration name="MaleAccounts">
<memberEntity name="MaleAccount"/>
<memberEntity name="UserAccount"/>
</configuration>
<elements>
<element name="UserAccount" positionX="-63" positionY="-18" width="128" height="90"/>
<element name="MaleAccount" positionX="-54" positionY="18" width="128" height="45"/>
<element name="FemaleAccount" positionX="-36" positionY="27" width="128" height="45"/>
</elements>
</model>

View File

@@ -1,53 +0,0 @@
//
// SwiftUIContainerViewController.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2019/10/02.
// Copyright © 2019 John Rommel Estropia. All rights reserved.
//
import UIKit
import CoreStore
#if canImport(SwiftUI)
import SwiftUI
#endif
#if canImport(Combine)
import Combine
#endif
import Compression
final class SwiftUIContainerViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
#if canImport(SwiftUI) && canImport(Combine)
if #available(iOS 13, *) {
let hostingController = UIHostingController(
rootView: SwiftUIView(
palettes: ColorsDemo.stack.publishList(
From<Palette>()
.sectionBy(\.colorName)
.orderBy(.ascending(\.hue))
)
)
.environment(\.dataStack, ColorsDemo.stack)
)
self.addChild(hostingController)
hostingController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
hostingController.view.frame = self.view.bounds.inset(by: self.view.safeAreaInsets)
self.view.addSubview(hostingController.view)
hostingController.didMove(toParent: self)
}
#endif
}
}

View File

@@ -1,184 +0,0 @@
//
// SwiftUIView.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2019/10/02.
// Copyright © 2019 John Rommel Estropia. All rights reserved.
//
#if canImport(SwiftUI) && canImport(Combine)
import SwiftUI
import Combine
import CoreStore
@available(iOS 13.0.0, *)
struct SwiftUIView: View {
@Environment(\.dataStack)
var dataStack: DataStack
@ObservedObject
var palettes: ListPublisher<Palette>
var body: some View {
NavigationView {
List {
ForEach(palettes.snapshot.sectionIDs, id: \.self) { (sectionID) in
Section(header: Text(sectionID)) {
ForEach(self.palettes.snapshot.items(inSectionWithID: sectionID), id: \.self) { palette in
NavigationLink(
destination: DetailView(palette: palette),
label: { ColorCell(palette: palette) }
)
}
.onDelete { itemIndices in
let objectIDsToDelete = self.palettes.snapshot.itemIDs(
inSectionWithID: sectionID,
atIndices: itemIndices
)
self.dataStack.perform(
asynchronous: { transaction in
transaction.delete(objectIDs: objectIDsToDelete)
},
completion: { _ in }
)
}
}
}
}
.navigationBarTitle(Text("SwiftUI (\(palettes.snapshot.numberOfItems) objects)"))
.navigationBarItems(
leading: EditButton(),
trailing: HStack {
Button(
action: {
self.dataStack.perform(
asynchronous: { transaction in
for palette in try transaction.fetchAll(From<Palette>()) {
palette.hue .= Palette.randomHue()
palette.colorName .= nil
}
},
completion: { _ in }
)
},
label: {
Image(systemName: "goforward")
}
)
.frame(width: 30)
Button(
action: {
self.dataStack.perform(
asynchronous: { transaction in
let palette = transaction.create(Into<Palette>())
palette.setInitialValues(in: transaction)
},
completion: { _ in }
)
},
label: {
Image(systemName: "plus")
}
)
.frame(width: 30)
}
)
.alert(
isPresented: $needsShowAlert,
content: {
Alert(
title: Text("SwiftUI Binding Demo"),
message: Text("This demo shows how to bind to ListPublisher and to CoreStoreObject when using SwiftUI"),
dismissButton: .cancel(Text("OK"))
)
}
)
.onAppear {
self.needsShowAlert = true
}
}
}
@State
private var needsShowAlert = false
}
@available(iOS 13.0.0, *)
struct ColorCell: View {
@ObservedObject
var palette: ObjectPublisher<Palette>
var body: some View {
HStack {
Color(palette.color ?? UIColor.clear)
.cornerRadius(5)
.frame(width: 30, height: 30, alignment: .leading)
Text(palette.colorText ?? "<Deleted>")
}
}
}
@available(iOS 13.0.0, *)
struct DetailView: View {
@Environment(\.dataStack)
var dataStack: DataStack
@ObservedObject
var palette: ObjectPublisher<Palette>
@State var hue: Float = 0
@State var saturation: Float = 0
@State var brightness: Float = 0
init(palette: ObjectPublisher<Palette>) {
self.palette = palette
self.hue = Float(palette.hue ?? 0)
self.saturation = palette.saturation ?? 0
self.brightness = palette.brightness ?? 0
}
var body: some View {
ZStack {
Color(palette.color ?? UIColor.clear)
.cornerRadius(20)
.padding(20)
VStack {
Text(palette.colorText ?? "<Deleted>")
.navigationBarTitle(Text("Color"))
Slider(value: $hue, in: 0.0 ... 359.0 as ClosedRange<Float>)
Slider(value: $saturation, in: 0.0 ... 1.0 as ClosedRange<Float>)
Slider(value: $brightness, in: 0.0 ... 0.1 as ClosedRange<Float>)
}
}
}
}
@available(iOS 13.0.0, *)
struct SwiftUIView_Previews: PreviewProvider {
static var previews: some View {
SwiftUIView(
palettes: ColorsDemo.stack.publishList(
From<Palette>()
.sectionBy(\.colorName)
.orderBy(.ascending(\.hue))
)
)
.environment(\.dataStack, ColorsDemo.stack)
}
}
#endif

View File

@@ -1,50 +0,0 @@
//
// Place.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import Foundation
import CoreData
import MapKit
// MARK: - Place
class Place: NSManagedObject, MKAnnotation {
@NSManaged var latitude: Double
@NSManaged var longitude: Double
@NSManaged var title: String?
@NSManaged var subtitle: String?
func setInitialValues() {
self.latitude = Double(arc4random_uniform(180)) - 90
self.longitude = Double(arc4random_uniform(360)) - 180
self.title = "\(self.latitude), \(self.longitude)"
self.subtitle = nil
}
// MARK: MKAnnotation
var coordinate: CLLocationCoordinate2D {
get {
return CLLocationCoordinate2DMake(
self.latitude,
self.longitude
)
}
set {
self.latitude = newValue.latitude
self.longitude = newValue.longitude
self.title = "\(self.latitude), \(self.longitude)"
self.subtitle = nil
}
}
}

View File

@@ -1,233 +0,0 @@
//
// TransactionsDemoViewController.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit
import Contacts
import CoreLocation
import MapKit
import AddressBookUI
import CoreStore
private struct Static {
static let dataStack = DataStack()
static let placeController: ObjectMonitor<Place> = {
try! Static.dataStack.addStorageAndWait(
SQLiteStore(
fileName: "PlaceDemo.sqlite",
configuration: "TransactionsDemo",
localStorageOptions: .recreateStoreOnModelMismatch
)
)
var place = try! Static.dataStack.fetchOne(From<Place>())
if place == nil {
_ = try? Static.dataStack.perform(
synchronous: { (transaction) in
let place = transaction.create(Into<Place>())
place.setInitialValues()
}
)
place = try! Static.dataStack.fetchOne(From<Place>())
}
return Static.dataStack.monitorObject(place!)
}()
}
// MARK: - TransactionsDemoViewController
class TransactionsDemoViewController: UIViewController, MKMapViewDelegate, ObjectObserver {
// MARK: NSObject
deinit {
Static.placeController.removeObserver(self)
}
// MARK: UIViewController
override func viewDidLoad() {
super.viewDidLoad()
let longPressGesture = UILongPressGestureRecognizer(
target: self,
action: #selector(self.longPressGestureRecognized(_:))
)
self.mapView?.addGestureRecognizer(longPressGesture)
Static.placeController.addObserver(self)
self.navigationItem.rightBarButtonItem = UIBarButtonItem(
barButtonSystemItem: .refresh,
target: self,
action: #selector(self.refreshButtonTapped(_:))
)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let alert = UIAlertController(
title: "Transactions Demo",
message: "This demo shows how to use the 3 types of transactions to save updates: synchronous, asynchronous, and unsafe.\n\nTap and hold on the map to change the pin location.",
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let mapView = self.mapView, let place = Static.placeController.object {
mapView.addAnnotation(place)
mapView.setCenter(place.coordinate, animated: false)
mapView.selectAnnotation(place, animated: false)
}
}
// MARK: MKMapViewDelegate
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let identifier = "MKAnnotationView"
var annotationView: MKPinAnnotationView! = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView
if annotationView == nil {
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView.isEnabled = true
annotationView.canShowCallout = true
annotationView.animatesDrop = true
}
else {
annotationView.annotation = annotation
}
return annotationView
}
// MARK: ObjectObserver
func objectMonitor(_ monitor: ObjectMonitor<Place>, willUpdateObject object: Place) {
// none
}
func objectMonitor(_ monitor: ObjectMonitor<Place>, didUpdateObject object: Place, changedPersistentKeys: Set<KeyPathString>) {
if let mapView = self.mapView {
mapView.removeAnnotations(mapView.annotations)
mapView.addAnnotation(object)
mapView.setCenter(object.coordinate, animated: true)
mapView.selectAnnotation(object, animated: true)
if changedPersistentKeys.contains(#keyPath(Place.latitude)) || changedPersistentKeys.contains(#keyPath(Place.longitude)) {
self.geocode(place: object)
}
}
}
func objectMonitor(_ monitor: ObjectMonitor<Place>, didDeleteObject object: Place) {
// none
}
// MARK: Private
var geocoder: CLGeocoder?
@IBOutlet weak var mapView: MKMapView?
@IBAction dynamic func longPressGestureRecognized(_ sender: AnyObject?) {
if let mapView = self.mapView,
let gesture = sender as? UILongPressGestureRecognizer,
gesture.state == .began {
let coordinate = mapView.convert(
gesture.location(in: mapView),
toCoordinateFrom: mapView
)
Static.dataStack.perform(
asynchronous: { (transaction) in
let place = transaction.edit(Static.placeController.object)
place?.coordinate = coordinate
},
completion: { _ in }
)
}
}
@IBAction dynamic func refreshButtonTapped(_ sender: AnyObject?) {
_ = try? Static.dataStack.perform(
synchronous: { (transaction) in
let place = transaction.edit(Static.placeController.object)
place?.setInitialValues()
}
)
}
func geocode(place: Place) {
let transaction = Static.dataStack.beginUnsafe()
self.geocoder?.cancelGeocode()
let geocoder = CLGeocoder()
self.geocoder = geocoder
geocoder.reverseGeocodeLocation(
CLLocation(latitude: place.latitude, longitude: place.longitude),
completionHandler: { [weak self] (placemarks, error) -> Void in
if let placemark = placemarks?.first, let dictionary = placemark.addressDictionary {
let place = transaction.edit(Static.placeController.object)
place?.title = placemark.name
place?.subtitle = CNPostalAddressFormatter.string(
from: autoreleasepool {
let address = CNMutablePostalAddress()
(dictionary["Street"] as? String).flatMap({ address.street = $0 })
(dictionary["State"] as? String).flatMap({ address.state = $0 })
(dictionary["City"] as? String).flatMap({ address.city = $0 })
(dictionary["Country"] as? String).flatMap({ address.country = $0 })
(dictionary["ZIP"] as? String).flatMap({ address.postalCode = $0 })
return address
},
style: .mailingAddress
)
transaction.commit { (_) -> Void in }
}
self?.geocoder = nil
}
)
}
}

Binary file not shown.

View File

@@ -28,6 +28,17 @@ import XCTest
@testable
import CoreStore
#if !SWIFT_PACKAGE
extension Bundle {
static var module: Bundle {
return Bundle(for: BaseTestCase.self)
}
}
#endif
// MARK: - BaseTestCase
@@ -40,7 +51,7 @@ class BaseTestCase: XCTestCase {
let stack = DataStack(
xcodeModelName: "Model",
bundle: Bundle(for: Self.self)
bundle: Bundle.module
)
do {
@@ -62,6 +73,9 @@ class BaseTestCase: XCTestCase {
XCTFail(error.coreStoreDumpString)
}
self.addTeardownBlock {
stack.unsafeRemoveAllPersistentStoresAndWait()
}
}
@nonobjc

View File

@@ -1,269 +0,0 @@
//
// BridgingTests.m
// CoreStore
//
// Copyright © 2018 John Rommel Estropia
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#import "BridgingTests.h"
#import <CoreStore/CoreStore.h>
#import <CoreStore/CoreStore-Swift.h>
#import "CoreStoreTests-Swift.h"
@import CoreData;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
// MARK: - BridgingTests
@implementation BridgingTests
- (void)test_ThatFlags_HaveCorrectValues {
XCTAssertEqual(CSLocalStorageOptionsNone, 0);
XCTAssertEqual(CSLocalStorageOptionsRecreateStoreOnModelMismatch, 1);
XCTAssertEqual(CSLocalStorageOptionsPreventProgressiveMigration, 2);
XCTAssertEqual(CSLocalStorageOptionsAllowSynchronousLightweightMigration, 4);
}
- (void)test_ThatKeyPaths_AreCorrect {
XCTAssertEqualObjects(CSKeyPath(TestEntity1, testNumber), @"testNumber");
XCTAssertEqualObjects(CSKeyPath(TestEntity1, testString), @"testString");
XCTAssertEqualObjects(CSKeyPathOperator(count, TestEntity1, testString), @"@count.testString");
XCTAssertEqualObjects(CSKeyPathOperator(max, TestEntity1, testNumber), @"@max.testNumber");
}
- (void)test_ThatFromClauses_BridgeCorrectly {
{
CSFrom *from = CSFromClass([TestEntity1 class]);
XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]);
XCTAssertNil(from.configurations);
}
{
CSFrom *from = CSFromClass([TestEntity1 class], [NSNull null]);
XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]);
NSArray *configurations = @[[NSNull null]];
XCTAssertEqualObjects(from.configurations, configurations);
}
{
CSFrom *from = CSFromClass([TestEntity1 class], @"Config1");
XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]);
NSArray *configurations = @[@"Config1"];
XCTAssertEqualObjects(from.configurations, configurations);
}
{
CSFrom *from = CSFromClass([TestEntity1 class], @[[NSNull null], @"Config2"]);
XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]);
NSArray *configurations = @[[NSNull null], @"Config2"];
XCTAssertEqualObjects(from.configurations, configurations);
}
}
- (void)test_ThatWhereClauses_BridgeCorrectly {
{
CSWhere *where = CSWhereFormat(@"%K == %@", @"key", @"value");
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"];
XCTAssertEqualObjects(where.predicate, predicate);
}
{
CSWhere *where = CSWhereValue(YES);
NSPredicate *predicate = [NSPredicate predicateWithValue:YES];
XCTAssertEqualObjects(where.predicate, predicate);
}
{
CSWhere *where = CSWherePredicate([NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"]);
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"];
XCTAssertEqualObjects(where.predicate, predicate);
}
}
- (void)test_ThatOrderByClauses_BridgeCorrectly {
{
CSOrderBy *orderBy = CSOrderByKey(CSSortAscending(@"key"));
XCTAssertEqualObjects(orderBy.sortDescriptors, @[[NSSortDescriptor sortDescriptorWithKey:@"key" ascending:YES]]);
}
{
CSOrderBy *orderBy = CSOrderByKey(CSSortDescending(@"key"));
XCTAssertEqualObjects(orderBy.sortDescriptors, @[[NSSortDescriptor sortDescriptorWithKey:@"key" ascending:NO]]);
}
{
CSOrderBy *orderBy = CSOrderByKeys(CSSortAscending(@"key1"), CSSortDescending(@"key2"), nil);
NSArray *sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"key1" ascending:YES],
[NSSortDescriptor sortDescriptorWithKey:@"key2" ascending:NO]];
XCTAssertEqualObjects(orderBy.sortDescriptors, sortDescriptors);
}
}
- (void)test_ThatGroupByClauses_BridgeCorrectly {
{
CSGroupBy *groupBy = CSGroupByKeyPath(@"key");
XCTAssertEqualObjects(groupBy.keyPaths, @[@"key"]);
}
{
CSGroupBy *groupBy = CSGroupByKeyPaths(@[@"key1", @"key2"]);
NSArray *keyPaths = @[@"key1", @"key2"];
XCTAssertEqualObjects(groupBy.keyPaths, keyPaths);
}
}
- (void)test_ThatTweakClauses_BridgeCorrectly {
CSTweak *tweak = CSTweakRequest(^(NSFetchRequest * _Nonnull fetchRequest) {
fetchRequest.fetchLimit = 100;
});
NSFetchRequest *request = [NSFetchRequest new];
tweak.block(request);
XCTAssertEqual(request.fetchLimit, 100);
}
- (void)test_ThatIntoClauses_BridgeCorrectly {
{
CSInto *into = CSIntoClass([TestEntity1 class]);
XCTAssertEqualObjects(into.entityClass, [TestEntity1 class]);
}
{
CSInto *into = CSIntoClass([TestEntity1 class], [NSNull null]);
XCTAssertEqualObjects(into.entityClass, [TestEntity1 class]);
XCTAssertNil(into.configuration);
}
{
CSInto *into = CSIntoClass([TestEntity1 class], @"Config1");
XCTAssertEqualObjects(into.entityClass, [TestEntity1 class]);
XCTAssertEqualObjects(into.configuration, @"Config1");
}
}
- (void)test_ThatDataStacks_BridgeCorrectly {
CSDataStack *dataStack = [[CSDataStack alloc]
initWithXcodeModelName:@"Model"
bundle:[NSBundle bundleForClass:[self class]]
versionChain:nil];
XCTAssertNotNil(dataStack);
NSError *memoryError;
CSInMemoryStore *memoryStorage = [dataStack
addInMemoryStorageAndWait:[CSInMemoryStore new]
error:&memoryError];
XCTAssertNotNil(memoryStorage);
XCTAssertEqualObjects([[memoryStorage class] storeType], [CSInMemoryStore storeType]);
XCTAssertEqualObjects([[memoryStorage class] storeType], NSInMemoryStoreType);
XCTAssertNil(memoryStorage.configuration);
XCTAssertNil(memoryStorage.storeOptions);
XCTAssertNil(memoryError);
NSError *sqliteError;
CSSQLiteStore *sqliteStorage = [dataStack
addSQLiteStorageAndWait:[CSSQLiteStore new]
error:&sqliteError];
XCTAssertNotNil(sqliteStorage);
XCTAssertEqualObjects([[sqliteStorage class] storeType], [CSSQLiteStore storeType]);
XCTAssertEqualObjects([[sqliteStorage class] storeType], NSSQLiteStoreType);
XCTAssertNil(sqliteStorage.configuration);
NSDictionary *storeOptions;
if (@available(iOS 11.0, macOS 10.13, tvOS 11.0, *)) {
storeOptions = @{ NSSQLitePragmasOption: @{ @"journal_mode": @"WAL" },
NSBinaryStoreInsecureDecodingCompatibilityOption: @YES };
}
else {
storeOptions = @{ NSSQLitePragmasOption: @{ @"journal_mode": @"WAL" }};
}
XCTAssertEqualObjects(sqliteStorage.storeOptions, storeOptions);
XCTAssertNil(sqliteError);
}
- (void)test_ThatTransactions_BridgeCorrectly {
CSDataStack *dataStack = [[CSDataStack alloc]
initWithXcodeModelName:@"Model"
bundle:[NSBundle bundleForClass:[self class]]
versionChain:nil];
XCTAssertNotNil(dataStack);
[dataStack
addInMemoryStorageAndWait:[CSInMemoryStore new]
error:nil];
{
CSUnsafeDataTransaction *transaction = [dataStack beginUnsafe];
XCTAssertNotNil(transaction);
XCTAssert([transaction isKindOfClass:[CSUnsafeDataTransaction class]]);
NSError *error;
BOOL result = [transaction commitAndWaitWithError:&error];
XCTAssertTrue(result);
XCTAssertNil(error);
}
{
XCTestExpectation *expectation = [self expectationWithDescription:@"sync"];
NSError *error;
BOOL result =
[dataStack
beginSynchronous:^(CSSynchronousDataTransaction * _Nonnull transaction) {
XCTAssertNotNil(transaction);
XCTAssert([transaction isKindOfClass:[CSSynchronousDataTransaction class]]);
NSError *error;
XCTAssertTrue([transaction commitAndWaitWithError:&error]);
XCTAssertNil(error);
[expectation fulfill];
}
error:&error];
XCTAssertTrue(result);
XCTAssertNil(error);
}
{
XCTestExpectation *expectation = [self expectationWithDescription:@"async"];
[dataStack beginAsynchronous:^(CSAsynchronousDataTransaction * _Nonnull transaction) {
XCTAssertNotNil(transaction);
XCTAssert([transaction isKindOfClass:[CSAsynchronousDataTransaction class]]);
[transaction
commitWithSuccess:^{
[expectation fulfill];
}
failure:^(CSError *error){
XCTFail();
}];
}];
}
[self waitForExpectationsWithTimeout:10 handler:nil];
}
@end
#pragma clang diagnostic pop

View File

@@ -23,13 +23,15 @@
// SOFTWARE.
//
import CoreData
import XCTest
@testable
import CoreStore
// MARK: - ConvenienceTests
@available(macOS 10.12, *)
class ConvenienceTests: BaseTestCase {
@objc
@@ -64,7 +66,7 @@ class ConvenienceTests: BaseTestCase {
self.prepareStack { (stack) in
_ = withExtendedLifetime(stack.beginUnsafe()) { (transaction: UnsafeDataTransaction) in
withExtendedLifetime(stack.beginUnsafe()) { (transaction: UnsafeDataTransaction) in
let controller = transaction.createFetchedResultsController(
From<TestEntity1>(),

View File

@@ -1,5 +0,0 @@
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#import "BridgingTests.h"

View File

@@ -49,9 +49,16 @@ class Animal: CoreStoreObject {
}
class Dog: Animal {
static let commonNicknames = ["Spot", "Benjie", "Max", "Milo"]
@Field.Stored("nickname")
var nickname: String?
@Field.Stored(
"nickname",
dynamicInitialValue: {
commonNicknames.randomElement()!
}
)
var nickname: String
@Field.Stored("age")
var age: Int = 1
@@ -67,7 +74,7 @@ struct CustomType {
var string = "customString"
}
enum Job: String {
enum Job: String, CaseIterable {
case unemployed
case engineer
@@ -139,9 +146,12 @@ class Person: CoreStoreObject {
coder: (
encode: { $0.toData() },
decode: { $0.flatMap(Job.init(data:)) ?? .unemployed }
)
),
dynamicInitialValue: {
Job.allCases.randomElement()!
}
)
var job: Job = .unemployed
var job: Job
@Field.Relationship("spouse")
var spouse: Person?
@@ -152,7 +162,7 @@ class Person: CoreStoreObject {
@Field.Relationship("_spouseInverse", inverse: \.$spouse)
private var spouseInverse: Person?
static func getDisplayName(_ object: ObjectProxy<Person>, _ field: ObjectProxy<Person>.FieldProxy<String?>) -> String? {
private static func getDisplayName(_ object: ObjectProxy<Person>, _ field: ObjectProxy<Person>.FieldProxy<String?>) -> String? {
if let value = field.primitiveValue {
@@ -165,7 +175,7 @@ class Person: CoreStoreObject {
return value
}
static func keyPathsAffectingDisplayName() -> Set<String> {
private static func keyPathsAffectingDisplayName() -> Set<String> {
return [
String(keyPath: \Person.$title),
@@ -187,12 +197,12 @@ class DynamicModelTests: BaseTestDataTestCase {
modelVersion: "V1",
entities: [
Entity<Animal>("Animal"),
Entity<Dog>("Dog"),
Entity<Dog>("Dog", indexes: [[\Dog.$nickname, \Dog.$age]]),
Entity<Person>("Person")
],
versionLock: [
"Animal": [0x1b59d511019695cf, 0xdeb97e86c5eff179, 0x1cfd80745646cb3, 0x4ff99416175b5b9a],
"Dog": [0xe3f0afeb109b283a, 0x29998d292938eb61, 0x6aab788333cfc2a3, 0x492ff1d295910ea7],
"Dog": [0xad6de93adc5565d, 0x7897e51253eba5a3, 0xd12b9ce0b13600f3, 0x5a4827cd794cd15e],
"Person": [0xf3e6ba6016bbedc6, 0x50dedf64f0eba490, 0xa32088a0ee83468d, 0xb72d1d0b37bd0992]
]
)
@@ -247,8 +257,8 @@ class DynamicModelTests: BaseTestDataTestCase {
let dog = transaction.create(Into<Dog>())
XCTAssertEqual(dog.species, "Swift")
XCTAssertEqual(dog.nickname, nil)
XCTAssertEqual(dog.age, 1)
XCTAssertTrue(Dog.commonNicknames.contains(dog.nickname))
for property in Dog.metaProperties(includeSuperclasses: true) {
@@ -264,7 +274,7 @@ class DynamicModelTests: BaseTestDataTestCase {
XCTAssertTrue(property is FieldContainer<Animal>.Coded<Color?>)
case String(keyPath: \Dog.$nickname):
XCTAssertTrue(property is FieldContainer<Dog>.Stored<String?>)
XCTAssertTrue(property is FieldContainer<Dog>.Stored<String>)
case String(keyPath: \Dog.$age):
XCTAssertTrue(property is FieldContainer<Dog>.Stored<Int>)
@@ -280,19 +290,6 @@ class DynamicModelTests: BaseTestDataTestCase {
}
}
// #if swift(>=5.1)
//
// let dogKeyPathBuilder = Dog.keyPathBuilder()
// XCTAssertEqual(dogKeyPathBuilder.species.keyPathString, "SELF.species")
// XCTAssertEqual(dogKeyPathBuilder.master.title.keyPathString, "SELF.master.title")
// let a = dogKeyPathBuilder.master
// let b = dogKeyPathBuilder.master.spouse
// let c = dogKeyPathBuilder.master.spouse.pets
// let d = dogKeyPathBuilder.master.spouse.pets.color
// XCTAssertEqual(dogKeyPathBuilder.master.spouse.pets.color.keyPathString, "SELF.master.spouse.pets.color")
//
// #endif
let didSetObserver = dog.observe(\.$species, options: [.new, .old]) { (object, change) in
XCTAssertEqual(object, dog)
@@ -335,7 +332,8 @@ class DynamicModelTests: BaseTestDataTestCase {
let person = transaction.create(Into<Person>())
XCTAssertTrue(person.pets.isEmpty)
XCTAssertEqual(person.customField.string, "customString")
XCTAssertEqual(person.job, .unemployed)
let initialJob = person.job
XCTAssertTrue(Job.allCases.contains(initialJob))
XCTAssertEqual(
person.rawObject!
@@ -385,7 +383,7 @@ class DynamicModelTests: BaseTestDataTestCase {
personSnapshot3.$name = "James"
XCTAssertEqual(personSnapshot1.$name, "John")
XCTAssertEqual(personSnapshot1.$displayName, "Mr. John")
XCTAssertEqual(personSnapshot1.$job, .unemployed)
XCTAssertEqual(personSnapshot1.$job, initialJob)
XCTAssertEqual(personSnapshot2.$name, "John")
XCTAssertEqual(personSnapshot2.$displayName, "Sir John")
XCTAssertEqual(personSnapshot2.$job, .engineer)
@@ -494,7 +492,12 @@ class DynamicModelTests: BaseTestDataTestCase {
XCTFail()
}
)
self.waitAndCheckExpectations()
}
self.waitForExpectations(timeout: 10, handler: { _ in })
self.addTeardownBlock {
dataStack.unsafeRemoveAllPersistentStoresAndWait()
}
}

View File

@@ -31,7 +31,6 @@ import CoreStore
// MARK: - ErrorTests
@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.")
final class ErrorTests: XCTestCase {
@objc
@@ -43,14 +42,12 @@ final class ErrorTests: XCTestCase {
let userInfo: NSDictionary = [:]
let objcError = error.bridgeToObjectiveC
XCTAssertEqual(error, objcError.bridgeToSwift)
let objcError = error as NSError
XCTAssertEqual(objcError.domain, CoreStoreErrorDomain)
XCTAssertEqual(objcError.code, CoreStoreErrorCode.unknownError.rawValue)
XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo)
let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC
XCTAssertEqual(error, objcError2.bridgeToSwift)
let objcError2 = CoreStoreError(objcError) as NSError
XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain)
XCTAssertEqual(objcError2.code, CoreStoreErrorCode.unknownError.rawValue)
XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo)
@@ -68,14 +65,12 @@ final class ErrorTests: XCTestCase {
let userInfo: NSDictionary = [
"existingPersistentStoreURL": dummyURL
]
let objcError = error.bridgeToObjectiveC
XCTAssertEqual(error, objcError.bridgeToSwift)
let objcError = error as NSError
XCTAssertEqual(objcError.domain, CoreStoreErrorDomain)
XCTAssertEqual(objcError.code, CoreStoreErrorCode.differentStorageExistsAtURL.rawValue)
XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo)
let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC
XCTAssertEqual(error, objcError2.bridgeToSwift)
let objcError2 = CoreStoreError(objcError) as NSError
XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain)
XCTAssertEqual(objcError2.code, CoreStoreErrorCode.differentStorageExistsAtURL.rawValue)
XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo)
@@ -89,7 +84,7 @@ final class ErrorTests: XCTestCase {
let schemaHistory = SchemaHistory(
XcodeDataModelSchema.from(
modelName: "Model",
bundle: Bundle(for: Self.self)
bundle: Bundle.module
)
)
let version = "1.0.0"
@@ -103,14 +98,12 @@ final class ErrorTests: XCTestCase {
"targetModel": schemaHistory.rawModel,
"targetModelVersion": version
]
let objcError = error.bridgeToObjectiveC
XCTAssertEqual(error, objcError.bridgeToSwift)
let objcError = error as NSError
XCTAssertEqual(objcError.domain, CoreStoreErrorDomain)
XCTAssertEqual(objcError.code, CoreStoreErrorCode.mappingModelNotFound.rawValue)
XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo)
let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC
XCTAssertEqual(error, objcError2.bridgeToSwift)
let objcError2 = CoreStoreError(objcError) as NSError
XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain)
XCTAssertEqual(objcError2.code, CoreStoreErrorCode.mappingModelNotFound.rawValue)
XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo)
@@ -128,14 +121,12 @@ final class ErrorTests: XCTestCase {
let userInfo: NSDictionary = [
"localStoreURL": dummyURL
]
let objcError = error.bridgeToObjectiveC
XCTAssertEqual(error, objcError.bridgeToSwift)
let objcError = error as NSError
XCTAssertEqual(objcError.domain, CoreStoreErrorDomain)
XCTAssertEqual(objcError.code, CoreStoreErrorCode.progressiveMigrationRequired.rawValue)
XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo)
let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC
XCTAssertEqual(error, objcError2.bridgeToSwift)
let objcError2 = CoreStoreError(objcError) as NSError
XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain)
XCTAssertEqual(objcError2.code, CoreStoreErrorCode.progressiveMigrationRequired.rawValue)
XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo)
@@ -160,14 +151,12 @@ final class ErrorTests: XCTestCase {
let userInfo: NSDictionary = [
"NSError": internalError
]
let objcError = error.bridgeToObjectiveC
XCTAssertEqual(error, objcError.bridgeToSwift)
let objcError = error as NSError
XCTAssertEqual(objcError.domain, CoreStoreErrorDomain)
XCTAssertEqual(objcError.code, CoreStoreErrorCode.internalError.rawValue)
XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo)
let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC
XCTAssertEqual(error, objcError2.bridgeToSwift)
let objcError2 = CoreStoreError(objcError) as NSError
XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain)
XCTAssertEqual(objcError2.code, CoreStoreErrorCode.internalError.rawValue)
XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo)

View File

@@ -132,8 +132,8 @@ final class FetchTests: BaseTestDataTestCase {
}
)
}
self.waitAndCheckExpectations()
}
self.waitAndCheckExpectations()
}
@objc
@@ -267,8 +267,8 @@ final class FetchTests: BaseTestDataTestCase {
}
)
}
self.waitAndCheckExpectations()
}
self.waitAndCheckExpectations()
}
@objc

View File

@@ -23,6 +23,7 @@
// SOFTWARE.
//
import CoreData
import XCTest
@testable

View File

@@ -23,6 +23,7 @@
// SOFTWARE.
//
import CoreData
import XCTest
@testable

View File

@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>6.2.1</string>
<string>9.3.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View File

@@ -23,6 +23,7 @@
// SOFTWARE.
//
import CoreData
import XCTest
@testable
@@ -125,15 +126,4 @@ final class IntoTests: XCTestCase {
XCTAssertNotEqual(into, Into<TestEntity1>("Config2"))
}
}
@objc
dynamic func test_ThatIntoClauses_BridgeCorrectly() {
do {
let into = Into<NSManagedObject>()
let objcInto = into.bridgeToObjectiveC
XCTAssertEqual(into, objcInto.bridgeToSwift)
}
}
}

View File

@@ -23,6 +23,7 @@
// SOFTWARE.
//
import CoreData
import XCTest
@testable
@@ -31,7 +32,6 @@ import CoreStore
// MARK: - ListObserverTests
@available(macOS 10.12, *)
class ListObserverTests: BaseTestDataTestCase {
@objc
@@ -101,9 +101,9 @@ class ListObserverTests: BaseTestDataTestCase {
["indexPath", "object"]
)
let indexPath = userInfo?["indexPath"] as? NSIndexPath
XCTAssertEqual(indexPath?.index(atPosition: 0), 0)
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
let indexPath = userInfo?["indexPath"] as? IndexPath
XCTAssertEqual(indexPath?.section, 0)
XCTAssertEqual(indexPath?.item, 0)
let object = userInfo?["object"] as? TestEntity1
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
@@ -213,14 +213,14 @@ class ListObserverTests: BaseTestDataTestCase {
["indexPath", "object"]
)
let indexPath = userInfo?["indexPath"] as? NSIndexPath
let indexPath = userInfo?["indexPath"] as? IndexPath
let object = userInfo?["object"] as? TestEntity1
switch object?.testEntityID {
case NSNumber(value: 101)?:
XCTAssertEqual(indexPath?.index(atPosition: 0), 1)
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
XCTAssertEqual(indexPath?.section, 1)
XCTAssertEqual(indexPath?.item, 0)
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
XCTAssertEqual(object?.testNumber, NSNumber(value: 11))
@@ -230,8 +230,8 @@ class ListObserverTests: BaseTestDataTestCase {
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-11T00:00:00Z")!)
case NSNumber(value: 102)?:
XCTAssertEqual(indexPath?.index(atPosition: 0), 0)
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
XCTAssertEqual(indexPath?.section, 0)
XCTAssertEqual(indexPath?.item, 0)
XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
XCTAssertEqual(object?.testNumber, NSNumber(value: 22))
@@ -357,13 +357,13 @@ class ListObserverTests: BaseTestDataTestCase {
["fromIndexPath", "toIndexPath", "object"]
)
let fromIndexPath = userInfo?["fromIndexPath"] as? NSIndexPath
XCTAssertEqual(fromIndexPath?.index(atPosition: 0), 0)
XCTAssertEqual(fromIndexPath?.index(atPosition: 1), 0)
let fromIndexPath = userInfo?["fromIndexPath"] as? IndexPath
XCTAssertEqual(fromIndexPath?.section, 0)
XCTAssertEqual(fromIndexPath?.item, 0)
let toIndexPath = userInfo?["toIndexPath"] as? NSIndexPath
XCTAssertEqual(toIndexPath?.index(atPosition: 0), 1)
XCTAssertEqual(toIndexPath?.index(atPosition: 1), 1)
let toIndexPath = userInfo?["toIndexPath"] as? IndexPath
XCTAssertEqual(toIndexPath?.section, 1)
XCTAssertEqual(toIndexPath?.item, 1)
let object = userInfo?["object"] as? TestEntity1
XCTAssertEqual(object?.testEntityID, NSNumber(value: 102))
@@ -465,10 +465,10 @@ class ListObserverTests: BaseTestDataTestCase {
["indexPath", "object"]
)
let indexPath = userInfo?["indexPath"] as? NSIndexPath
let indexPath = userInfo?["indexPath"] as? IndexPath
XCTAssertEqual(indexPath?.section, 0)
XCTAssert(indexPath?.index(atPosition: 1) == 0 || indexPath?.index(atPosition: 1) == 1)
XCTAssert(indexPath?.item == 0 || indexPath?.item == 1)
let object = userInfo?["object"] as? TestEntity1
XCTAssertEqual(object?.isDeleted, true)
@@ -551,7 +551,6 @@ class ListObserverTests: BaseTestDataTestCase {
// MARK: TestListObserver
@available(macOS 10.12, *)
class TestListObserver: ListSectionObserver {
// MARK: ListObserver

View File

@@ -33,7 +33,6 @@ import CoreStore
// MARK: - ListPublisherTests
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
class ListPublisherTests: BaseTestDataTestCase {
@objc

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14460.32" systemVersion="17G2307" minimumToolsVersion="Xcode 4.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<entity name="TestEntity1AAA" representedClassName="CoreStoreTests.TestEntity1" syncable="YES">
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22222" systemVersion="22G91" minimumToolsVersion="Xcode 4.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<entity name="TestEntity1AAA" representedClassName=".TestEntity1" syncable="YES">
<attribute name="testBoolean" optional="YES" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
<attribute name="testData" optional="YES" attributeType="Binary" syncable="YES"/>
<attribute name="testDate" optional="YES" attributeType="Date" usesScalarValueType="NO" syncable="YES"/>
@@ -12,7 +12,7 @@
<relationship name="testToManyUnordered" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="TestEntity1AAA" inverseName="testToOne" inverseEntity="TestEntity1AAA" syncable="YES"/>
<relationship name="testToOne" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="TestEntity1AAA" inverseName="testToManyUnordered" inverseEntity="TestEntity1AAA" syncable="YES"/>
</entity>
<entity name="TestEntity2" representedClassName="CoreStoreTests.TestEntity2" syncable="YES">
<entity name="TestEntity2" representedClassName=".TestEntity2" syncable="YES">
<attribute name="testBoolean" optional="YES" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
<attribute name="testData" optional="YES" attributeType="Binary" syncable="YES"/>
<attribute name="testDate" optional="YES" attributeType="Date" usesScalarValueType="NO" syncable="YES"/>
@@ -30,8 +30,4 @@
<configuration name="Config2">
<memberEntity name="TestEntity2"/>
</configuration>
<elements>
<element name="TestEntity1AAA" positionX="-63" positionY="-18" width="128" height="195"/>
<element name="TestEntity2" positionX="-63" positionY="9" width="128" height="195"/>
</elements>
</model>

View File

@@ -31,7 +31,6 @@ import CoreStore
// MARK: - ObjectObserverTests
@available(macOS 10.12, *)
class ObjectObserverTests: BaseTestDataTestCase {
@objc
@@ -203,7 +202,6 @@ class ObjectObserverTests: BaseTestDataTestCase {
// MARK: TestObjectObserver
@available(macOS 10.12, *)
class TestObjectObserver: ObjectObserver {
typealias ObjectEntityType = TestEntity1

View File

@@ -31,7 +31,6 @@ import CoreStore
// MARK: - ObjectPublisherTests
@available(macOS 10.12, *)
class ObjectPublisherTests: BaseTestDataTestCase {
@objc
@@ -144,6 +143,7 @@ class ObjectPublisherTests: BaseTestDataTestCase {
XCTFail()
}
)
self.waitAndCheckExpectations()
withExtendedLifetime(objectPublisher, {})

View File

@@ -23,6 +23,7 @@
// SOFTWARE.
//
import CoreData
import XCTest
@testable

View File

@@ -23,6 +23,7 @@
// SOFTWARE.
//
import CoreData
import XCTest
@testable

View File

@@ -23,6 +23,7 @@
// SOFTWARE.
//
import CoreData
import XCTest
@testable
@@ -31,7 +32,6 @@ import CoreStore
//MARK: - SectionByTests
@available(macOS 10.12, *)
final class SectionByTests: XCTestCase {
@objc
@@ -41,11 +41,14 @@ final class SectionByTests: XCTestCase {
let sectionBy = SectionBy<NSManagedObject>("key")
XCTAssertEqual(sectionBy.sectionKeyPath, "key")
XCTAssertEqual(sectionBy.sectionIndexTransformer("key"), "key")
XCTAssertNil(sectionBy.sectionIndexTransformer("key"))
}
do {
let sectionBy = SectionBy<NSManagedObject>("key") { $0.flatMap { "\($0):suffix" } }
let sectionBy = SectionBy<NSManagedObject>(
"key",
sectionIndexTransformer: { $0.flatMap { "\($0):suffix" } }
)
XCTAssertEqual(sectionBy.sectionKeyPath, "key")
XCTAssertEqual(sectionBy.sectionIndexTransformer("key"), "key:suffix")
XCTAssertNil(sectionBy.sectionIndexTransformer(nil))

View File

@@ -23,6 +23,7 @@
// SOFTWARE.
//
import CoreData
import XCTest
@testable

View File

@@ -23,6 +23,9 @@
// SOFTWARE.
//
import CoreData
import XCTest
@testable
import CoreStore
@@ -39,7 +42,7 @@ class SetupTests: BaseTestDataTestCase {
let schemaHistory = SchemaHistory(
XcodeDataModelSchema.from(
modelName: "Model",
bundle: Bundle(for: Self.self)
bundle: Bundle.module
)
)
let stack = DataStack(schemaHistory: schemaHistory)
@@ -65,7 +68,7 @@ class SetupTests: BaseTestDataTestCase {
DataStack(
xcodeModelName: "Model",
bundle: Bundle(for: Self.self),
bundle: Bundle.module,
migrationChain: migrationChain
)
}
@@ -79,7 +82,7 @@ class SetupTests: BaseTestDataTestCase {
let stack = DataStack(
xcodeModelName: "Model",
bundle: Bundle(for: Self.self)
bundle: Bundle.module
)
do {
@@ -134,7 +137,7 @@ class SetupTests: BaseTestDataTestCase {
let stack = DataStack(
xcodeModelName: "Model",
bundle: Bundle(for: Self.self)
bundle: Bundle.module
)
do {
@@ -202,7 +205,7 @@ class SetupTests: BaseTestDataTestCase {
let stack = DataStack(
xcodeModelName: "Model",
bundle: Bundle(for: Self.self)
bundle: Bundle.module
)
try! stack.addStorageAndWait(sqliteStore)
self.prepareTestDataForStack(stack)
@@ -221,7 +224,7 @@ class SetupTests: BaseTestDataTestCase {
let metadata = try createStore()
let stack = DataStack(
xcodeModelName: "Model",
bundle: Bundle(for: Self.self)
bundle: Bundle.module
)
try sqliteStore.cs_eraseStorageAndWait(
metadata: metadata,
@@ -254,7 +257,7 @@ class SetupTests: BaseTestDataTestCase {
let stack = DataStack(
xcodeModelName: "Model",
bundle: Bundle(for: Self.self)
bundle: Bundle.module
)
do {
@@ -322,7 +325,7 @@ class SetupTests: BaseTestDataTestCase {
let stack = DataStack(
xcodeModelName: "Model",
bundle: Bundle(for: Self.self)
bundle: Bundle.module
)
try! stack.addStorageAndWait(
SQLiteStore.legacy(
@@ -348,7 +351,7 @@ class SetupTests: BaseTestDataTestCase {
let metadata = try createStore()
let stack = DataStack(
xcodeModelName: "Model",
bundle: Bundle(for: Self.self)
bundle: Bundle.module
)
try sqliteStore.cs_eraseStorageAndWait(
metadata: metadata,

View File

@@ -23,6 +23,7 @@
// SOFTWARE.
//
import CoreData
import XCTest
@testable
@@ -83,21 +84,11 @@ final class StorageInterfaceTests: XCTestCase {
let store = SQLiteStore()
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
XCTAssertNil(store.configuration)
if #available(iOS 11.0, macOS 10.13, tvOS 11.0, *) {
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSBinaryStoreInsecureDecodingCompatibilityOption: true] as NSDictionary
)
}
else {
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary
)
}
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSBinaryStoreInsecureDecodingCompatibilityOption: true] as NSDictionary
)
XCTAssertEqual(store.fileURL, SQLiteStore.defaultFileURL)
XCTAssertTrue(store.migrationMappingProviders.isEmpty)
@@ -112,7 +103,7 @@ final class StorageInterfaceTests: XCTestCase {
.appendingPathExtension("db")
let mappingProvider = XcodeSchemaMappingProvider(
from: "V1", to: "V2",
mappingModelBundle: Bundle(for: Self.self)
mappingModelBundle: Bundle.module
)
let store = SQLiteStore(
@@ -123,21 +114,11 @@ final class StorageInterfaceTests: XCTestCase {
)
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
XCTAssertEqual(store.configuration, "config1")
if #available(iOS 11.0, macOS 10.13, tvOS 11.0, *) {
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSBinaryStoreInsecureDecodingCompatibilityOption: true] as NSDictionary
)
}
else {
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary
)
}
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSBinaryStoreInsecureDecodingCompatibilityOption: true] as NSDictionary
)
XCTAssertEqual(store.fileURL, fileURL)
XCTAssertEqual(store.migrationMappingProviders as! [XcodeSchemaMappingProvider], [mappingProvider])
@@ -150,7 +131,7 @@ final class StorageInterfaceTests: XCTestCase {
let fileName = UUID().uuidString + ".db"
let mappingProvider = XcodeSchemaMappingProvider(
from: "V1", to: "V2",
mappingModelBundle: Bundle(for: Self.self)
mappingModelBundle: Bundle.module
)
let store = SQLiteStore(
fileName: fileName,
@@ -160,21 +141,11 @@ final class StorageInterfaceTests: XCTestCase {
)
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
XCTAssertEqual(store.configuration, "config1")
if #available(iOS 11.0, macOS 10.13, tvOS 11.0, *) {
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSBinaryStoreInsecureDecodingCompatibilityOption: true] as NSDictionary
)
}
else {
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary
)
}
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSBinaryStoreInsecureDecodingCompatibilityOption: true] as NSDictionary
)
XCTAssertEqual(store.fileURL.deletingLastPathComponent(), SQLiteStore.defaultRootDirectory)
XCTAssertEqual(store.fileURL.lastPathComponent, fileName)
@@ -209,21 +180,11 @@ final class StorageInterfaceTests: XCTestCase {
let store = SQLiteStore.legacy()
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
XCTAssertNil(store.configuration)
if #available(iOS 11.0, macOS 10.13, tvOS 11.0, *) {
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSBinaryStoreInsecureDecodingCompatibilityOption: true] as NSDictionary
)
}
else {
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary
)
}
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSBinaryStoreInsecureDecodingCompatibilityOption: true] as NSDictionary
)
XCTAssertEqual(store.fileURL, SQLiteStore.legacyDefaultFileURL)
XCTAssertTrue(store.migrationMappingProviders.isEmpty)
@@ -236,7 +197,7 @@ final class StorageInterfaceTests: XCTestCase {
let fileName = UUID().uuidString + ".db"
let mappingProvider = XcodeSchemaMappingProvider(
from: "V1", to: "V2",
mappingModelBundle: Bundle(for: Self.self)
mappingModelBundle: Bundle.module
)
let store = SQLiteStore.legacy(
fileName: fileName,
@@ -246,21 +207,11 @@ final class StorageInterfaceTests: XCTestCase {
)
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
XCTAssertEqual(store.configuration, "config1")
if #available(iOS 11.0, macOS 10.13, tvOS 11.0, *) {
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSBinaryStoreInsecureDecodingCompatibilityOption: true] as NSDictionary
)
}
else {
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary
)
}
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSBinaryStoreInsecureDecodingCompatibilityOption: true] as NSDictionary
)
XCTAssertEqual(store.fileURL.deletingLastPathComponent(), SQLiteStore.legacyDefaultRootDirectory)
XCTAssertEqual(store.fileURL.lastPathComponent, fileName)

View File

@@ -23,6 +23,7 @@
// SOFTWARE.
//
import Foundation
import XCTest
@testable
@@ -383,8 +384,6 @@ final class TransactionTests: BaseTestCase {
}
}
@available(macOS 10.12, *)
@objc
dynamic func test_ThatSynchronousTransactions_CanCommitWithoutWaitingForMerges() {
@@ -428,9 +427,9 @@ final class TransactionTests: BaseTestCase {
["indexPath", "object"]
)
let indexPath = userInfo?["indexPath"] as? NSIndexPath
XCTAssertEqual(indexPath?.index(atPosition: 0), 0)
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
let indexPath = userInfo?["indexPath"] as? IndexPath
XCTAssertEqual(indexPath?.section, 0)
XCTAssertEqual(indexPath?.item, 0)
let object = userInfo?["object"] as? TestEntity1
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
@@ -622,8 +621,8 @@ final class TransactionTests: BaseTestCase {
}
)
}
self.waitAndCheckExpectations()
}
self.waitAndCheckExpectations()
}
@objc
@@ -755,8 +754,8 @@ final class TransactionTests: BaseTestCase {
}
)
}
self.waitAndCheckExpectations()
}
self.waitAndCheckExpectations()
}
@objc
@@ -896,8 +895,8 @@ final class TransactionTests: BaseTestCase {
}
)
}
self.waitAndCheckExpectations()
}
self.waitAndCheckExpectations()
}
@objc

View File

@@ -23,6 +23,7 @@
// SOFTWARE.
//
import CoreData
import XCTest
@testable

View File

@@ -23,6 +23,7 @@
// SOFTWARE.
//
import CoreData
import XCTest
@testable
@@ -77,17 +78,10 @@ final class WhereTests: XCTestCase {
do {
// let keyPathBuilder = TestEntity1.keyPathBuilder()
// let kp = \TestEntity1.testToOne
// print(keyPathBuilder.testString)
// print(keyPathBuilder.testToOne)
// print(keyPathBuilder.testToOne.testEntityID)
XCTAssertAllEqual(
#keyPath(TestEntity1.testToOne.testEntityID),
(\TestEntity1.testToOne ~ \.testEntityID).description,
String(keyPath: \TestEntity1.testToOne ~ \.testEntityID)
// keyPathBuilder.testToOne.testEntityID.keyPathString
)
XCTAssertAllEqual(
#keyPath(TestEntity1.testToOne.testToOne.testToManyUnordered),

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1600"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -14,10 +14,10 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B54AAD481AF4D26E00848AE0"
BuildableName = "CoreStoreDemo.app"
BlueprintName = "CoreStoreDemo"
ReferencedContainer = "container:CoreStoreDemo.xcodeproj">
BlueprintIdentifier = "B5A3911824E5429200E7E8BD"
BuildableName = "Demo.app"
BlueprintName = "Demo"
ReferencedContainer = "container:Demo.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
@@ -27,15 +27,6 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B54AAD481AF4D26E00848AE0"
BuildableName = "CoreStoreDemo.app"
BlueprintName = "CoreStoreDemo"
ReferencedContainer = "container:CoreStoreDemo.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
</Testables>
</TestAction>
@@ -53,10 +44,10 @@
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B54AAD481AF4D26E00848AE0"
BuildableName = "CoreStoreDemo.app"
BlueprintName = "CoreStoreDemo"
ReferencedContainer = "container:CoreStoreDemo.xcodeproj">
BlueprintIdentifier = "B5A3911824E5429200E7E8BD"
BuildableName = "Demo.app"
BlueprintName = "Demo"
ReferencedContainer = "container:Demo.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
@@ -70,10 +61,10 @@
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B54AAD481AF4D26E00848AE0"
BuildableName = "CoreStoreDemo.app"
BlueprintName = "CoreStoreDemo"
ReferencedContainer = "container:CoreStoreDemo.xcodeproj">
BlueprintIdentifier = "B5A3911824E5429200E7E8BD"
BuildableName = "Demo.app"
BlueprintName = "Demo"
ReferencedContainer = "container:Demo.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>

View File

@@ -3,9 +3,7 @@
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>CoreStore</string>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
@@ -15,25 +13,36 @@
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>6.3.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>4</string>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
</dict>
</array>
</dict>
</dict>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
<key>UIStatusBarTintParameters</key>
<dict>
<key>UINavigationBar</key>
@@ -47,10 +56,15 @@
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>UIUserInterfaceStyle</key>
<string>Light</string>
</dict>
</plist>

42
Demo/Rakefile Normal file
View File

@@ -0,0 +1,42 @@
# coding: utf-8
task :format do
require 'xcodeproj'
require 'fileutils'
project_path = 'Demo.xcodeproj'
ignore_targets = []
# http://www.rubydoc.info/github/CocoaPods/Xcodeproj
project = Xcodeproj::Project.open(project_path)
validTargets = project.targets.select { |target| target.respond_to?(:product_type) }
validTargets.each do |target|
if ignore_targets.include?(target.display_name)
next
end
case target.product_type
when 'com.apple.product-type.application', 'com.apple.product-type.framework'
target.source_build_phase.files.sort! do |f1, f2|
result = (f1.display_name.count "+") <=> (f2.display_name.count "+")
if result != 0
next -result
end
result = (f1.display_name.count "-") <=> (f2.display_name.count "-")
if result != 0
next -result
end
result = (f1.display_name.count ".") <=> (f2.display_name.count ".")
if result != 0
next result
end
(f1.display_name <=> f2.display_name)
end
end
end
project.save()
end

View File

@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097.2" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController interfaceStyle="dark" id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Bp2-lt-3DL">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright © 2020 John Rommel Estropia. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="Yn3-8H-uzI">
<rect key="frame" x="20" y="827" width="374" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="CoreStoreIcon" translatesAutoresizingMaskIntoConstraints="NO" id="IrK-8p-pit">
<rect key="frame" x="122" y="228.5" width="170" height="170"/>
<constraints>
<constraint firstAttribute="width" secondItem="IrK-8p-pit" secondAttribute="height" multiplier="1:1" id="WaM-8F-33r"/>
<constraint firstAttribute="width" constant="170" id="dlo-1N-ikz"/>
</constraints>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="CoreStore" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="8Vu-0U-3hd">
<rect key="frame" x="20" y="418.5" width="374" height="57.5"/>
<fontDescription key="fontDescription" name="HelveticaNeue-UltraLight" family="Helvetica Neue" pointSize="50"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<constraints>
<constraint firstItem="Yn3-8H-uzI" firstAttribute="leading" secondItem="Bp2-lt-3DL" secondAttribute="leading" constant="20" symbolic="YES" id="7Dq-xP-k2v"/>
<constraint firstItem="IrK-8p-pit" firstAttribute="centerY" secondItem="Bp2-lt-3DL" secondAttribute="centerY" multiplier="0.7" id="HUz-XL-l27"/>
<constraint firstItem="IrK-8p-pit" firstAttribute="centerX" secondItem="Bp2-lt-3DL" secondAttribute="centerX" id="TSf-yM-hl1"/>
<constraint firstAttribute="centerX" secondItem="8Vu-0U-3hd" secondAttribute="centerX" id="TX2-HT-cKs"/>
<constraint firstItem="Z3i-EZ-UGs" firstAttribute="bottom" secondItem="Yn3-8H-uzI" secondAttribute="bottom" constant="14" id="hAb-SJ-Qnm"/>
<constraint firstAttribute="centerX" secondItem="Yn3-8H-uzI" secondAttribute="centerX" id="pNf-eo-RXZ"/>
<constraint firstItem="8Vu-0U-3hd" firstAttribute="leading" secondItem="Bp2-lt-3DL" secondAttribute="leading" constant="20" symbolic="YES" id="pef-yD-C5e"/>
<constraint firstItem="8Vu-0U-3hd" firstAttribute="top" secondItem="IrK-8p-pit" secondAttribute="bottom" constant="20" id="xQP-tq-hNL"/>
</constraints>
<viewLayoutGuide key="safeArea" id="Z3i-EZ-UGs"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="CoreStoreIcon" width="170" height="170"/>
</resources>
</document>

View File

@@ -2,113 +2,114 @@
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
"scale" : "3x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
"scale" : "3x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
"scale" : "3x",
"size" : "40x40"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"filename" : "Icon-60@3x-1.png",
"scale" : "3x"
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
"scale" : "1x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
"scale" : "1x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
"scale" : "1x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
"scale" : "2x",
"size" : "40x40"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-76.png",
"scale" : "1x"
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-76@2x.png",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
"scale" : "2x",
"size" : "76x76"
},
{
"filename" : "Icon-83.5@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Mask + Oval 1 + Oval 1 + Oval 1.png",
"scale" : "1x"
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
},
{
"idiom" : "car",
"size" : "60x60",
"scale" : "2x"
"scale" : "2x",
"size" : "60x60"
},
{
"size" : "60x60",
"idiom" : "car",
"filename" : "Icon-60@3x.png",
"scale" : "3x"
"idiom" : "car",
"scale" : "3x",
"size" : "60x60"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
"author" : "xcode",
"version" : 1
}
}
}

Some files were not shown because too many files have changed in this diff Show More