Added setup and transactions demo

This commit is contained in:
John Rommel Estropia
2015-05-26 01:44:49 +09:00
parent cb867c07ab
commit 1cc4f21336
32 changed files with 1184 additions and 334 deletions

View File

@@ -11,24 +11,25 @@
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 */; };
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 /* HardcoreDataDemo.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B54AAD501AF4D26E00848AE0 /* HardcoreDataDemo.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 */; };
B54AAD6A1AF4D26E00848AE0 /* HardcoreDataDemoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54AAD691AF4D26E00848AE0 /* HardcoreDataDemoTests.swift */; };
B566E32A1B117B1F00F4F0C6 /* StackSetupDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B566E3291B117B1F00F4F0C6 /* StackSetupDemoViewController.swift */; };
B566E3321B11DF3200F4F0C6 /* UserAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = B566E3311B11DF3200F4F0C6 /* UserAccount.swift */; };
B583A9201AF5F542001F76AF /* HardcoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B583A91B1AF5F4F4001F76AF /* HardcoreData.framework */; };
B583A9211AF5F542001F76AF /* HardcoreData.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B583A91B1AF5F4F4001F76AF /* HardcoreData.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
B5E7240F1B11F993006FB83F /* TwitterAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E7240E1B11F993006FB83F /* TwitterAccount.swift */; };
B5E724111B11F994006FB83F /* FacebookAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E724101B11F994006FB83F /* FacebookAccount.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
B54AAD641AF4D26E00848AE0 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = B54AAD411AF4D26E00848AE0 /* Project object */;
proxyType = 1;
remoteGlobalIDString = B54AAD481AF4D26E00848AE0;
remoteInfo = HardcoreDataDemo;
};
B583A91A1AF5F4F4001F76AF /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = B583A9141AF5F4F3001F76AF /* HardcoreData.xcodeproj */;
@@ -78,6 +79,11 @@
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>"; };
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 /* HardcoreDataDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HardcoreDataDemo.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>"; };
@@ -85,11 +91,12 @@
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>"; };
B54AAD631AF4D26E00848AE0 /* HardcoreDataDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HardcoreDataDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
B54AAD681AF4D26E00848AE0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
B54AAD691AF4D26E00848AE0 /* HardcoreDataDemoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HardcoreDataDemoTests.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>"; };
B583A9141AF5F4F3001F76AF /* HardcoreData.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = HardcoreData.xcodeproj; path = ../HardcoreData.xcodeproj; sourceTree = "<group>"; };
B583A9251AF5F547001F76AF /* GCDKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; name = GCDKit.framework; path = "/Users/johnestropia/Library/Developer/Xcode/DerivedData/HardcoreDataDemo-ftknhsqfpsthfogvisxisgpbbhsj/Build/Products/Debug-iphoneos/GCDKit.framework"; sourceTree = "<absolute>"; };
B5E7240E1B11F993006FB83F /* TwitterAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TwitterAccount.swift; sourceTree = "<group>"; };
B5E724101B11F994006FB83F /* FacebookAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FacebookAccount.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -97,23 +104,19 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
B52977E11B120F8A003D50A5 /* CoreLocation.framework in Frameworks */,
B52977DF1B120F83003D50A5 /* MapKit.framework in Frameworks */,
B583A9201AF5F542001F76AF /* HardcoreData.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
B54AAD601AF4D26E00848AE0 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
B503FADA1AFDC71700F90881 /* List and Object Observers Demo */ = {
isa = PBXGroup;
children = (
B52977D81B120B80003D50A5 /* ObserversViewController.swift */,
B503FADB1AFDC71700F90881 /* ObjectListObserverDemoViewController.swift */,
B503FADC1AFDC71700F90881 /* ObjectObserverDemoViewController.swift */,
B503FADD1AFDC71700F90881 /* Palette.swift */,
@@ -122,13 +125,31 @@
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 = (
B583A9141AF5F4F3001F76AF /* HardcoreData.xcodeproj */,
B52977E01B120F8A003D50A5 /* CoreLocation.framework */,
B52977DE1B120F83003D50A5 /* MapKit.framework */,
B583A9251AF5F547001F76AF /* GCDKit.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
B54AAD401AF4D26E00848AE0 = {
isa = PBXGroup;
children = (
B583A9251AF5F547001F76AF /* GCDKit.framework */,
B583A9141AF5F4F3001F76AF /* HardcoreData.xcodeproj */,
B52977E21B120F90003D50A5 /* Frameworks */,
B54AAD4B1AF4D26E00848AE0 /* HardcoreDataDemo */,
B54AAD661AF4D26E00848AE0 /* HardcoreDataDemoTests */,
B54AAD4A1AF4D26E00848AE0 /* Products */,
);
sourceTree = "<group>";
@@ -137,7 +158,6 @@
isa = PBXGroup;
children = (
B54AAD491AF4D26E00848AE0 /* HardcoreDataDemo.app */,
B54AAD631AF4D26E00848AE0 /* HardcoreDataDemoTests.xctest */,
);
name = Products;
sourceTree = "<group>";
@@ -146,7 +166,9 @@
isa = PBXGroup;
children = (
B54AAD4E1AF4D26E00848AE0 /* AppDelegate.swift */,
B566E3271B117AE700F4F0C6 /* Stack Setup Demo */,
B503FADA1AFDC71700F90881 /* List and Object Observers Demo */,
B52977DB1B120F2C003D50A5 /* Transactions Demo */,
B54AAD571AF4D26E00848AE0 /* Main.storyboard */,
B54AAD5A1AF4D26E00848AE0 /* Images.xcassets */,
B54AAD5C1AF4D26E00848AE0 /* LaunchScreen.xib */,
@@ -164,21 +186,15 @@
name = "Supporting Files";
sourceTree = "<group>";
};
B54AAD661AF4D26E00848AE0 /* HardcoreDataDemoTests */ = {
B566E3271B117AE700F4F0C6 /* Stack Setup Demo */ = {
isa = PBXGroup;
children = (
B54AAD691AF4D26E00848AE0 /* HardcoreDataDemoTests.swift */,
B54AAD671AF4D26E00848AE0 /* Supporting Files */,
B5E724101B11F994006FB83F /* FacebookAccount.swift */,
B5E7240E1B11F993006FB83F /* TwitterAccount.swift */,
B566E3311B11DF3200F4F0C6 /* UserAccount.swift */,
B566E3291B117B1F00F4F0C6 /* StackSetupDemoViewController.swift */,
);
path = HardcoreDataDemoTests;
sourceTree = "<group>";
};
B54AAD671AF4D26E00848AE0 /* Supporting Files */ = {
isa = PBXGroup;
children = (
B54AAD681AF4D26E00848AE0 /* Info.plist */,
);
name = "Supporting Files";
path = "Stack Setup Demo";
sourceTree = "<group>";
};
B583A9151AF5F4F3001F76AF /* Products */ = {
@@ -213,24 +229,6 @@
productReference = B54AAD491AF4D26E00848AE0 /* HardcoreDataDemo.app */;
productType = "com.apple.product-type.application";
};
B54AAD621AF4D26E00848AE0 /* HardcoreDataDemoTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = B54AAD701AF4D26E00848AE0 /* Build configuration list for PBXNativeTarget "HardcoreDataDemoTests" */;
buildPhases = (
B54AAD5F1AF4D26E00848AE0 /* Sources */,
B54AAD601AF4D26E00848AE0 /* Frameworks */,
B54AAD611AF4D26E00848AE0 /* Resources */,
);
buildRules = (
);
dependencies = (
B54AAD651AF4D26E00848AE0 /* PBXTargetDependency */,
);
name = HardcoreDataDemoTests;
productName = HardcoreDataDemoTests;
productReference = B54AAD631AF4D26E00848AE0 /* HardcoreDataDemoTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
@@ -243,10 +241,6 @@
B54AAD481AF4D26E00848AE0 = {
CreatedOnToolsVersion = 6.3;
};
B54AAD621AF4D26E00848AE0 = {
CreatedOnToolsVersion = 6.3;
TestTargetID = B54AAD481AF4D26E00848AE0;
};
};
};
buildConfigurationList = B54AAD441AF4D26E00848AE0 /* Build configuration list for PBXProject "HardcoreDataDemo" */;
@@ -269,7 +263,6 @@
projectRoot = "";
targets = (
B54AAD481AF4D26E00848AE0 /* HardcoreDataDemo */,
B54AAD621AF4D26E00848AE0 /* HardcoreDataDemoTests */,
);
};
/* End PBXProject section */
@@ -302,13 +295,6 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
B54AAD611AF4D26E00848AE0 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -316,7 +302,14 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B52977DD1B120F3B003D50A5 /* TransactionsDemoViewController.swift in Sources */,
B52977E41B121635003D50A5 /* Place.swift in Sources */,
B503FAE01AFDC71700F90881 /* ObjectObserverDemoViewController.swift in Sources */,
B52977D91B120B80003D50A5 /* ObserversViewController.swift in Sources */,
B566E32A1B117B1F00F4F0C6 /* StackSetupDemoViewController.swift in Sources */,
B5E724111B11F994006FB83F /* FacebookAccount.swift in Sources */,
B5E7240F1B11F993006FB83F /* TwitterAccount.swift in Sources */,
B566E3321B11DF3200F4F0C6 /* UserAccount.swift in Sources */,
B54AAD521AF4D26E00848AE0 /* HardcoreDataDemo.xcdatamodeld in Sources */,
B503FAE11AFDC71700F90881 /* Palette.swift in Sources */,
B503FAE21AFDC71700F90881 /* PaletteTableViewCell.swift in Sources */,
@@ -325,22 +318,9 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
B54AAD5F1AF4D26E00848AE0 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B54AAD6A1AF4D26E00848AE0 /* HardcoreDataDemoTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
B54AAD651AF4D26E00848AE0 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = B54AAD481AF4D26E00848AE0 /* HardcoreDataDemo */;
targetProxy = B54AAD641AF4D26E00848AE0 /* PBXContainerItemProxy */;
};
B583A91F1AF5F512001F76AF /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = HardcoreData;
@@ -463,6 +443,7 @@
"$(USER_LIBRARY_DIR)/Developer/Xcode/DerivedData/HardcoreDataDemo-ftknhsqfpsthfogvisxisgpbbhsj/Build/Products/Debug-iphoneos",
);
INFOPLIST_FILE = HardcoreDataDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
};
@@ -477,45 +458,12 @@
"$(USER_LIBRARY_DIR)/Developer/Xcode/DerivedData/HardcoreDataDemo-ftknhsqfpsthfogvisxisgpbbhsj/Build/Products/Debug-iphoneos",
);
INFOPLIST_FILE = HardcoreDataDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
B54AAD711AF4D26E00848AE0 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
);
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
INFOPLIST_FILE = HardcoreDataDemoTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HardcoreDataDemo.app/HardcoreDataDemo";
};
name = Debug;
};
B54AAD721AF4D26E00848AE0 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
);
INFOPLIST_FILE = HardcoreDataDemoTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HardcoreDataDemo.app/HardcoreDataDemo";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -537,15 +485,6 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
B54AAD701AF4D26E00848AE0 /* Build configuration list for PBXNativeTarget "HardcoreDataDemoTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
B54AAD711AF4D26E00848AE0 /* Debug */,
B54AAD721AF4D26E00848AE0 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCVersionGroup section */

View File

@@ -7,7 +7,6 @@
//
import UIKit
import HardcoreData
// MARK: - AppDelegate
@@ -21,7 +20,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
HardcoreData.addSQLiteStore(resetStoreOnMigrationFailure: true)
return true
}
}

View File

@@ -6,6 +6,87 @@
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
</dependencies>
<scenes>
<!--SNS Accounts-->
<scene sceneID="3If-81-mNf">
<objects>
<tableViewController id="AW4-lY-JNk" customClass="StackSetupDemoViewController" customModule="HardcoreDataDemo" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="S3A-lm-AuA">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<view key="tableHeaderView" contentMode="scaleToFill" id="yud-WH-MPa">
<rect key="frame" x="0.0" y="64" width="600" height="150"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="sns" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="czc-nd-es9">
<rect key="frame" x="20" y="20" width="560" height="21.5"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="name" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1eh-91-O2N">
<rect key="frame" x="20" y="65" width="42.5" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="friends" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p2y-0T-hQs">
<rect key="frame" x="536" y="67" width="44" height="17"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="1eh-91-O2N" firstAttribute="top" secondItem="czc-nd-es9" secondAttribute="bottom" constant="23.5" id="F6q-Jt-glI"/>
<constraint firstItem="p2y-0T-hQs" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="1eh-91-O2N" secondAttribute="trailing" constant="20" id="GVS-6o-rmj"/>
<constraint firstItem="p2y-0T-hQs" firstAttribute="trailing" secondItem="czc-nd-es9" secondAttribute="trailing" id="P5Z-WP-UCj"/>
<constraint firstAttribute="trailing" secondItem="czc-nd-es9" secondAttribute="trailing" constant="20" id="adf-Th-qDC"/>
<constraint firstItem="p2y-0T-hQs" firstAttribute="centerY" secondItem="1eh-91-O2N" secondAttribute="centerY" constant="0.25" id="ccw-e2-zjE"/>
<constraint firstItem="czc-nd-es9" firstAttribute="top" secondItem="yud-WH-MPa" secondAttribute="top" constant="20" id="un5-6w-1o5"/>
<constraint firstItem="czc-nd-es9" firstAttribute="leading" secondItem="yud-WH-MPa" secondAttribute="leading" constant="20" id="xsd-bs-BQL"/>
<constraint firstItem="1eh-91-O2N" firstAttribute="leading" secondItem="czc-nd-es9" secondAttribute="leading" id="ye6-S5-Yil"/>
</constraints>
</view>
<prototypes>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="UITableViewCell" textLabel="8b8-lM-Krq" detailTextLabel="hR1-Zb-BOk" style="IBUITableViewCellStyleValue1" id="dMt-nx-EO5">
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="dMt-nx-EO5" id="gdK-VV-zNb">
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="8b8-lM-Krq">
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Subtitle" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="hR1-Zb-BOk">
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" red="0.55686274509803924" green="0.55686274509803924" blue="0.57647058823529407" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
</prototypes>
<connections>
<outlet property="dataSource" destination="AW4-lY-JNk" id="VFi-3E-pTo"/>
<outlet property="delegate" destination="AW4-lY-JNk" id="7WG-Pm-8Xz"/>
</connections>
</tableView>
<navigationItem key="navigationItem" title="SNS Accounts" id="JVD-bl-r7d"/>
<connections>
<outlet property="accountTypeLabel" destination="czc-nd-es9" id="R9X-mn-dRl"/>
<outlet property="friendsLabel" destination="p2y-0T-hQs" id="4dM-fL-Jau"/>
<outlet property="nameLabel" destination="1eh-91-O2N" id="0wU-tN-YFO"/>
</connections>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="cd4-SX-KET" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="3694" y="650"/>
</scene>
<!--HardcoreData Demos-->
<scene sceneID="0Be-vc-h1W">
<objects>
@@ -22,7 +103,7 @@
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="AXm-KE-45G" id="9te-Wx-hkf">
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Q3n-Df-v1t">
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Accounts" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Q3n-Df-v1t">
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
@@ -36,6 +117,9 @@
</label>
</subviews>
</tableViewCellContentView>
<connections>
<segue destination="AW4-lY-JNk" kind="show" id="u5L-No-Yuk"/>
</connections>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="vpt-cT-gMo" detailTextLabel="ou9-TZ-8bf" style="IBUITableViewCellStyleSubtitle" id="fsb-zw-8Ii">
<autoresizingMask key="autoresizingMask"/>
@@ -65,7 +149,7 @@
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="ekW-PJ-mbo" id="CYq-mg-PVS">
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="UbU-Kd-yrY">
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Placemark" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="UbU-Kd-yrY">
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
@@ -79,6 +163,9 @@
</label>
</subviews>
</tableViewCellContentView>
<connections>
<segue destination="jPl-fH-NlD" kind="show" id="g1J-LG-mxf"/>
</connections>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="ZfY-Aq-Ykq" detailTextLabel="QzD-9b-k1j" style="IBUITableViewCellStyleSubtitle" id="wyK-rk-3tI">
<autoresizingMask key="autoresizingMask"/>
@@ -261,7 +348,7 @@
<!--Colors-->
<scene sceneID="3lD-lX-hIc">
<objects>
<viewController automaticallyAdjustsScrollViewInsets="NO" hidesBottomBarWhenPushed="YES" id="YOI-b7-Nxn" sceneMemberID="viewController">
<viewController automaticallyAdjustsScrollViewInsets="NO" hidesBottomBarWhenPushed="YES" id="YOI-b7-Nxn" customClass="ObserversViewController" customModule="HardcoreDataDemo" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="IML-3o-caw"/>
<viewControllerLayoutGuide type="bottom" id="LNL-mj-D7l"/>
@@ -461,6 +548,43 @@
</objects>
<point key="canvasLocation" x="4404" y="1546"/>
</scene>
<!--Placemark-->
<scene sceneID="LRD-q1-hw1">
<objects>
<viewController id="jPl-fH-NlD" customClass="TransactionsDemoViewController" customModule="HardcoreDataDemo" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="1of-hY-qOU"/>
<viewControllerLayoutGuide type="bottom" id="RZg-hi-T8O"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="k4s-iL-Krh">
<rect key="frame" x="0.0" y="0.0" width="600" height="536"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<mapView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" misplaced="YES" mapType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="V2U-0R-Ts0">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<connections>
<outlet property="delegate" destination="jPl-fH-NlD" id="Sjn-YC-haS"/>
</connections>
</mapView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="RZg-hi-T8O" firstAttribute="top" secondItem="V2U-0R-Ts0" secondAttribute="bottom" id="GcS-Jz-Wcm"/>
<constraint firstItem="V2U-0R-Ts0" firstAttribute="top" secondItem="k4s-iL-Krh" secondAttribute="top" id="S5Z-Da-V6J"/>
<constraint firstAttribute="trailing" secondItem="V2U-0R-Ts0" secondAttribute="trailing" id="YPc-RK-5ib"/>
<constraint firstItem="V2U-0R-Ts0" firstAttribute="leading" secondItem="k4s-iL-Krh" secondAttribute="leading" id="hk5-Rz-FyU"/>
</constraints>
</view>
<extendedEdge key="edgesForExtendedLayout" bottom="YES"/>
<navigationItem key="navigationItem" title="Placemark" id="s5y-WX-W5w"/>
<connections>
<outlet property="mapView" destination="V2U-0R-Ts0" id="X6a-Bp-psg"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="YnG-TD-zxQ" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="3694" y="2020"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="3ih-RN-P43">
<objects>

View File

@@ -7,7 +7,32 @@
<attribute name="saturation" optional="YES" attributeType="Float" defaultValueString="0.0" syncable="YES"/>
<userInfo/>
</entity>
<entity name="Place" representedClassName="HardcoreDataDemo.Place" syncable="YES">
<attribute name="latitude" optional="YES" attributeType="Double" defaultValueString="0.0" syncable="YES"/>
<attribute name="longitude" optional="YES" attributeType="Double" defaultValueString="0.0" syncable="YES"/>
<attribute name="subtitle" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="title" optional="YES" attributeType="String" syncable="YES"/>
</entity>
<entity name="UserAccount" representedClassName="HardcoreDataDemo.UserAccount" 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="ObservingDemo">
<memberEntity name="Palette"/>
</configuration>
<configuration name="SetupDemo_Jane">
<memberEntity name="UserAccount"/>
</configuration>
<configuration name="SetupDemo_John">
<memberEntity name="UserAccount"/>
</configuration>
<configuration name="TransactionsDemo">
<memberEntity name="Place"/>
</configuration>
<elements>
<element name="Palette" positionX="261" positionY="189" width="128" height="105"/>
<element name="UserAccount" positionX="261" positionY="216" width="128" height="90"/>
<element name="Place" positionX="261" positionY="225" width="128" height="105"/>
</elements>
</model>

View File

@@ -10,13 +10,22 @@ import UIKit
import HardcoreData
struct Shared {
private struct Static {
static let palettes = HardcoreData.observeSectionedList(
From(Palette),
SectionedBy("colorName"),
OrderBy(.Ascending("hue"))
)
static let palettes: ManagedObjectListController<Palette> = {
HardcoreData.addSQLiteStore(
"ColorsDemo.sqlite",
configuration: "ObservingDemo",
resetStoreOnMigrationFailure: true
)
return HardcoreData.observeSectionedList(
From(Palette),
SectionedBy("colorName"),
OrderBy(.Ascending("hue"))
)
}()
}
@@ -28,7 +37,7 @@ class ObjectListObserverDemoViewController: UITableViewController, ManagedObject
deinit {
Shared.palettes.removeObserver(self)
Static.palettes.removeObserver(self)
}
@@ -52,7 +61,7 @@ class ObjectListObserverDemoViewController: UITableViewController, ManagedObject
action: "addBarButtonItemTouched:"
)
Shared.palettes.addObserver(self)
Static.palettes.addObserver(self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
@@ -74,19 +83,19 @@ class ObjectListObserverDemoViewController: UITableViewController, ManagedObject
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return Shared.palettes.numberOfSections()
return Static.palettes.numberOfSections()
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return Shared.palettes.numberOfObjectsInSection(section)
return Static.palettes.numberOfObjectsInSection(section)
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("PaletteTableViewCell") as! PaletteTableViewCell
let palette = Shared.palettes[indexPath]
let palette = Static.palettes[indexPath]
cell.colorView?.backgroundColor = palette.color
cell.label?.text = palette.colorText
@@ -102,7 +111,7 @@ class ObjectListObserverDemoViewController: UITableViewController, ManagedObject
self.performSegueWithIdentifier(
"ObjectObserverDemoViewController",
sender: Shared.palettes[indexPath]
sender: Static.palettes[indexPath]
)
}
@@ -111,7 +120,7 @@ class ObjectListObserverDemoViewController: UITableViewController, ManagedObject
switch editingStyle {
case .Delete:
let palette = Shared.palettes[indexPath]
let palette = Static.palettes[indexPath]
HardcoreData.beginAsynchronous{ (transaction) -> Void in
transaction.delete(palette)
@@ -125,7 +134,7 @@ class ObjectListObserverDemoViewController: UITableViewController, ManagedObject
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return Shared.palettes.sectionInfoAtIndex(section).name
return Static.palettes.sectionInfoAtIndex(section).name
}
@@ -158,7 +167,7 @@ class ObjectListObserverDemoViewController: UITableViewController, ManagedObject
if let cell = self.tableView.cellForRowAtIndexPath(indexPath) as? PaletteTableViewCell {
let palette = Shared.palettes[indexPath]
let palette = Static.palettes[indexPath]
cell.colorView?.backgroundColor = palette.color
cell.label?.text = palette.colorText
}
@@ -199,7 +208,7 @@ class ObjectListObserverDemoViewController: UITableViewController, ManagedObject
HardcoreData.beginAsynchronous { (transaction) -> Void in
let palette = transaction.create(Palette)
let palette = transaction.create(Into(Palette))
palette.setInitialValues()
transaction.commit()

View File

@@ -53,7 +53,7 @@ class ObjectObserverDemoViewController: UIViewController, ManagedObjectObserver
HardcoreData.beginSynchronous { (transaction) -> Void in
let palette = transaction.create(Palette)
let palette = transaction.create(Into(Palette))
palette.setInitialValues()
transaction.commit()

View File

@@ -0,0 +1,30 @@
//
// ObserversViewController.swift
// HardcoreDataDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright (c) 2015 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 \"ManagedObjectListController\" instance.\n\nTap on a row to see another demo that shows how to observe changes to a single object using a \"ManagedObjectController\".",
preferredStyle: .Alert
)
alert.addAction(UIAlertAction(title: "OK", style: .Cancel, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}

View File

@@ -0,0 +1,15 @@
//
// FacebookAccount.swift
// HardcoreDataDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
//
import Foundation
import CoreData
// MARK: - FacebookAccount
class FacebookAccount: TwitterAccount { }

View File

@@ -0,0 +1,190 @@
//
// StackSetupDemoViewController.swift
// HardcoreDataDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
//
import UIKit
import HardcoreData
private struct Static {
static let johnConfiguration = "SetupDemo_John"
static let janeConfiguration = "SetupDemo_Jane"
static let facebookStack: DataStack = {
let dataStack = DataStack(modelName: "HardcoreDataDemo")
dataStack.addSQLiteStore(
"AccountsDemo_FB_John.sqlite",
configuration: johnConfiguration,
resetStoreOnMigrationFailure: true
)
dataStack.addSQLiteStore(
"AccountsDemo_FB_Jane.sqlite",
configuration: janeConfiguration,
resetStoreOnMigrationFailure: true
)
dataStack.beginSynchronous { (transaction) -> Void in
transaction.deleteAll(From<UserAccount>(johnConfiguration))
transaction.deleteAll(From<UserAccount>(janeConfiguration))
let account1 = transaction.create(Into<UserAccount>(johnConfiguration))
account1.accountType = "Facebook"
account1.name = "John Smith HCD"
account1.friends = 42
let account2 = transaction.create(Into<UserAccount>(janeConfiguration))
account2.accountType = "Facebook"
account2.name = "Jane Doe HCD"
account2.friends = 314
transaction.commit()
}
return dataStack
}()
static let twitterStack: DataStack = {
let dataStack = DataStack(modelName: "HardcoreDataDemo")
dataStack.addSQLiteStore(
"AccountsDemo_TW_John.sqlite",
configuration: johnConfiguration,
resetStoreOnMigrationFailure: true
)
dataStack.addSQLiteStore(
"AccountsDemo_TW_Jane.sqlite",
configuration: janeConfiguration,
resetStoreOnMigrationFailure: true
)
dataStack.beginSynchronous { (transaction) -> Void in
transaction.deleteAll(From<UserAccount>(johnConfiguration))
transaction.deleteAll(From<UserAccount>(janeConfiguration))
let account1 = transaction.create(Into<UserAccount>(johnConfiguration))
account1.accountType = "Twitter"
account1.name = "#johnsmith_hcd"
account1.friends = 7
let account2 = transaction.create(Into<UserAccount>(janeConfiguration))
account2.accountType = "Twitter"
account2.name = "#janedoe_hcd"
account2.friends = 100
transaction.commit()
}
return dataStack
}()
}
// MARK: - StackSetupDemoViewController
class StackSetupDemoViewController: UITableViewController {
let accounts = [
[
Static.facebookStack.fetchOne(From<UserAccount>(Static.johnConfiguration))!,
Static.facebookStack.fetchOne(From<UserAccount>(Static.janeConfiguration))!
],
[
Static.twitterStack.fetchOne(From<UserAccount>(Static.johnConfiguration))!,
Static.twitterStack.fetchOne(From<UserAccount>(Static.janeConfiguration))!
]
]
// MARK: UIViewController
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.tableView.reloadData()
let indexPath = NSIndexPath(forRow: 0, inSection: 0)
self.tableView.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: .None)
self.updateDetailsWithAccount(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.presentViewController(alert, animated: true, completion: nil)
}
// MARK: UITableViewDataSource
override func numberOfSectionsInTableView(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, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("UITableViewCell") as! 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, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let account = self.accounts[indexPath.section][indexPath.row]
self.updateDetailsWithAccount(account)
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
switch section {
case 0: return "Facebook Accounts"
case 1: return "Twitter Accounts"
default: return nil
}
}
// MARK: Private
@IBOutlet weak var accountTypeLabel: UILabel?
@IBOutlet weak var nameLabel: UILabel?
@IBOutlet weak var friendsLabel: UILabel?
func updateDetailsWithAccount(account: UserAccount) {
self.accountTypeLabel?.text = account.accountType
self.nameLabel?.text = account.name
self.friendsLabel?.text = "\(account.friends) friends"
}
}

View File

@@ -0,0 +1,15 @@
//
// TwitterAccount.swift
// HardcoreDataDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
//
import Foundation
import CoreData
// MARK: - TwitterAccount
class TwitterAccount: UserAccount { }

View File

@@ -0,0 +1,20 @@
//
// UserAccount.swift
// HardcoreDataDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright (c) 2015 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

@@ -0,0 +1,50 @@
//
// Place.swift
// HardcoreDataDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright (c) 2015 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

@@ -0,0 +1,208 @@
//
// TransactionsDemoViewController.swift
// HardcoreDataDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
//
import UIKit
import CoreLocation
import MapKit
import AddressBookUI
import HardcoreData
import GCDKit
private struct Static {
static let placeController: ManagedObjectController<Place> = {
HardcoreData.addSQLiteStore(
"PlaceDemo.sqlite",
configuration: "TransactionsDemo",
resetStoreOnMigrationFailure: true
)
var place = HardcoreData.fetchOne(From(Place))
if place == nil {
HardcoreData.beginSynchronous { (transaction) -> Void in
let place = transaction.create(Into(Place))
place.setInitialValues()
transaction.commit()
}
place = HardcoreData.fetchOne(From(Place))
}
return HardcoreData.observeObject(place!)
}()
}
// MARK: - TransactionsDemoViewController
class TransactionsDemoViewController: UIViewController, MKMapViewDelegate, ManagedObjectObserver {
// MARK: NSObject
deinit {
Static.placeController.removeObserver(self)
}
// MARK: UIViewController
override func viewDidLoad() {
super.viewDidLoad()
let longPressGesture = UILongPressGestureRecognizer(target: self, action: "longPressGestureRecognized:")
self.mapView?.addGestureRecognizer(longPressGesture)
Static.placeController.addObserver(self)
self.navigationItem.rightBarButtonItem = UIBarButtonItem(
barButtonSystemItem: .Refresh,
target: self,
action: "refreshButtonTapped:"
)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
let alert = UIAlertController(
title: "Observers Demo",
message: "This demo shows how to use the 3 types of transactions to save updates: synchronous, asynchronous, and detached. Long-tap on the map to change the pin location.",
preferredStyle: .Alert
)
alert.addAction(UIAlertAction(title: "OK", style: .Cancel, handler: nil))
self.presentViewController(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.setCenterCoordinate(place.coordinate, animated: false)
mapView.selectAnnotation(place, animated: false)
}
}
// MARK: MKMapViewDelegate
func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
let identifier = "MKAnnotationView"
var annotationView: MKPinAnnotationView! = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier) as? MKPinAnnotationView
if annotationView == nil {
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView.enabled = true
annotationView.canShowCallout = true
annotationView.animatesDrop = true
}
else {
annotationView.annotation = annotation
}
return annotationView
}
// MARK: ManagedObjectObserver
func managedObjectWillUpdate(objectController: ManagedObjectController<Place>, object: Place) {
// none
}
func managedObjectWasUpdated(objectController: ManagedObjectController<Place>, object: Place, changedPersistentKeys: Set<KeyPath>) {
if let mapView = self.mapView {
mapView.removeAnnotations(mapView.annotations ?? [])
mapView.addAnnotation(object)
mapView.setCenterCoordinate(object.coordinate, animated: true)
mapView.selectAnnotation(object, animated: true)
if changedPersistentKeys.contains("latitude") || changedPersistentKeys.contains("longitude") {
self.geocodePlace(object)
}
}
}
func managedObjectWasDeleted(objectController: ManagedObjectController<Place>, 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 where gesture.state == .Began {
HardcoreData.beginAsynchronous { (transaction) -> Void in
let place = transaction.fetch(Static.placeController.object)
place?.coordinate = mapView.convertPoint(
gesture.locationInView(mapView),
toCoordinateFromView: mapView
)
transaction.commit { (_) -> Void in }
}
}
}
@IBAction dynamic func refreshButtonTapped(sender: AnyObject?) {
HardcoreData.beginSynchronous { (transaction) -> Void in
let place = transaction.fetch(Static.placeController.object)
place?.setInitialValues()
transaction.commit()
}
}
func geocodePlace(place: Place) {
let transaction = HardcoreData.beginDetached()
self.geocoder?.cancelGeocode()
var geocoder = CLGeocoder()
self.geocoder = geocoder
geocoder.reverseGeocodeLocation(
CLLocation(latitude: place.latitude, longitude: place.longitude),
completionHandler: { [weak self] (placemarks, error) -> Void in
if let strongSelf = self, let placemark = (placemarks as? [CLPlacemark])?.first {
let place = transaction.fetch(Static.placeController.object)
place?.title = placemark.name
place?.subtitle = ABCreateStringWithAddressDictionary(placemark.addressDictionary, true)
transaction.commit { (_) -> Void in }
}
self?.geocoder = nil
}
)
}
}

View File

@@ -1,36 +0,0 @@
//
// HardcoreDataDemoTests.swift
// HardcoreDataDemoTests
//
// Created by John Rommel Estropia on 2015/05/02.
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
//
import UIKit
import XCTest
class HardcoreDataDemoTests: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testExample() {
// This is an example of a functional test case.
XCTAssert(true, "Pass")
}
func testPerformanceExample() {
// This is an example of a performance test case.
self.measureBlock() {
// Put the code you want to measure the time of here.
}
}
}

View File

@@ -1,24 +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>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>com.johnestropia.$(PRODUCT_NAME:rfc1034identifier)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>