Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CloudKitDictionarySyncer.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@
E505A25E1A87DC08004DCFAB /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0610;
LastSwiftUpdateCheck = 0730;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

LastUpgradeCheck = 0730;
ORGANIZATIONNAME = Baresi;
TargetAttributes = {
E505A2651A87DC08004DCFAB = {
Expand Down Expand Up @@ -297,6 +298,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
Expand Down Expand Up @@ -363,6 +365,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
INFOPLIST_FILE = CloudKitDictionarySyncer/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "se.baresi.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
};
Expand All @@ -377,6 +380,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
INFOPLIST_FILE = CloudKitDictionarySyncer/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "se.baresi.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
};
Expand All @@ -396,6 +400,7 @@
);
INFOPLIST_FILE = CloudKitDictionarySyncerTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "se.baresi.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CloudKitDictionarySyncer.app/CloudKitDictionarySyncer";
};
Expand All @@ -411,6 +416,7 @@
);
INFOPLIST_FILE = CloudKitDictionarySyncerTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "se.baresi.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CloudKitDictionarySyncer.app/CloudKitDictionarySyncer";
};
Expand Down
52 changes: 30 additions & 22 deletions CloudKitDictionarySyncer/CloudKitDictionarySyncer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ class CloudKitDictionarySyncer {
self.dictname = dictname
self.debugflag = debug
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
let documentsDirectory = paths[0] as! String
self.plistpath = documentsDirectory.stringByAppendingPathComponent("\(dictname).plist")
let documentsDirectory = NSURL(fileURLWithPath:paths[0] as! String)
self.plistpath = documentsDirectory.URLByAppendingPathComponent("\(dictname).plist").absoluteString
self.container = CKContainer.defaultContainer()
}

// MARK: - Public methods

func loadDictionary(#onComplete: (LoadResult) -> ()) {
func loadDictionary(onComplete: (LoadResult) -> ()) {

load {

Expand All @@ -50,7 +50,7 @@ class CloudKitDictionarySyncer {

} else {
// try to get dict from icloud
self.fetchDictionaryFromiCloud(onComplete: {
self.fetchDictionaryFromiCloud({
_,dictFromiCloud in

var icloudTimestamp:UInt32 = 0
Expand Down Expand Up @@ -96,7 +96,7 @@ class CloudKitDictionarySyncer {

func saveDictionary(dictionary:NSDictionary, onComplete: (String) -> ()) {

load {
// load {
var mutableDict:NSMutableDictionary = dictionary.mutableCopy() as! NSMutableDictionary

// Add save timestamp
Expand All @@ -115,7 +115,7 @@ class CloudKitDictionarySyncer {
} else {
onComplete("CDS: saveDictionary complete, only saved to plist file")
}
}
// }

}

Expand All @@ -125,10 +125,10 @@ class CloudKitDictionarySyncer {
if !self.debugflag {
return
}
println(msg)
print(msg)
}

private func load(#onComplete: () -> ()) {
private func load(onComplete: () -> ()) {
if self.loaded {
onComplete()
return
Expand Down Expand Up @@ -171,7 +171,7 @@ class CloudKitDictionarySyncer {
// MARK: - Private CloudKit methods

private func saveDictionaryToiCloud(dict: NSDictionary, onComplete: (String) -> ()) {
fetchDictionaryFromiCloud(onComplete: {
fetchDictionaryFromiCloud({
fetchedRecord,_ in
var record:CKRecord
if fetchedRecord != nil {
Expand All @@ -180,7 +180,8 @@ class CloudKitDictionarySyncer {
record = CKRecord(recordType: "Plists", recordID: CKRecordID(recordName: self.dictname))
}
var plisterror:NSError?
if let data:NSData = NSPropertyListSerialization.dataWithPropertyList(dict, format:NSPropertyListFormat.XMLFormat_v1_0, options:0, error:&plisterror) {
do{
if let data:NSData = try NSPropertyListSerialization.dataWithPropertyList(dict, format:NSPropertyListFormat.XMLFormat_v1_0, options:0) {
if let datastring = NSString(data:data, encoding:NSUTF8StringEncoding) {
record.setValue(self.dictname, forKey: "dictname")
record.setValue(datastring, forKey: "plistxml")
Expand All @@ -193,7 +194,9 @@ class CloudKitDictionarySyncer {
if plisterror != nil {
onComplete("CDS: Error saving in cloudkit. Searialize error: \(plisterror!)")
}

}catch{
print(plisterror)
}
self.privateDB!.saveRecord(record, completionHandler: { (record, error) -> () in
if error != nil {
onComplete("CDS: Error saving in cloudkit \(error!)")
Expand All @@ -204,13 +207,13 @@ class CloudKitDictionarySyncer {
})
}

private func fetchDictionaryFromiCloud(#onComplete: (CKRecord?, NSMutableDictionary?) -> ()) {
private func fetchDictionaryFromiCloud(onComplete: (CKRecord?, NSMutableDictionary?) -> ()) {
let recordId = CKRecordID(recordName: self.dictname)
self.privateDB!.fetchRecordWithID(recordId, completionHandler: {
(record:CKRecord!, error:NSError!) -> () in
(record:CKRecord?, error:NSError?) -> () in
if error != nil {
self.debug("CDS: Status fetching cloudkit record \(error)")
switch error.code {
switch error!.code {
case CKErrorCode.UnknownItem.rawValue:
self.debug("CDS: Record did not exist, CK throws error for this, but is normal for new records, ignore and move on")
onComplete(nil, nil)
Expand All @@ -220,19 +223,24 @@ class CloudKitDictionarySyncer {
onComplete(nil, nil)

}




} else {
if let obj:AnyObject = record.objectForKey("plistxml") {
if let obj:AnyObject = record!.objectForKey("plistxml") {
var dict:NSMutableDictionary?
if let str = obj as? String {
if let data:NSData = str.dataUsingEncoding(NSUTF8StringEncoding) {
var plisterror:NSError?
dict = NSPropertyListSerialization.propertyListWithData(data,
options:Int(NSPropertyListMutabilityOptions.MutableContainersAndLeaves.rawValue),
format: nil, error: &plisterror) as? NSMutableDictionary
if plisterror != nil {
self.debug("CDS: Error serializing cloudkit xml into dict. Error: \(plisterror)")
}
do{
dict = try NSPropertyListSerialization.propertyListWithData(data, options:NSPropertyListMutabilityOptions.MutableContainersAndLeaves,
format: nil) as? NSMutableDictionary
}catch{
if plisterror != nil {
self.debug("CDS: Error serializing cloudkit xml into dict. Error: \(plisterror)")
}
}

}
}
if dict != nil {
Expand Down
2 changes: 1 addition & 1 deletion CloudKitDictionarySyncer/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>se.baresi.$(PRODUCT_NAME:rfc1034identifier)</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
Expand Down
18 changes: 9 additions & 9 deletions CloudKitDictionarySyncer/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ class ViewController: UIViewController, UITableViewDataSource, UITableViewDelega
override func viewDidLoad() {
super.viewDidLoad()

self.syncer.loadDictionary(onComplete: {
self.syncer.loadDictionary({
loadResult in
switch loadResult {
case .Dict(let loadeddict):
self.dict = loadeddict
println("EXAMPLE: Dict loaded dict = \(loadeddict)")
print("EXAMPLE: Dict loaded dict = \(loadeddict)")
if let rowlabels = self.dict["rowlabels"] as? [String] {
// Yes, we already got the rowlabel key, do nothing
} else {
Expand All @@ -31,13 +31,13 @@ class ViewController: UIViewController, UITableViewDataSource, UITableViewDelega
}
case .Conflict(let localdict, let clouddict, let latest):
// Handle conflict. In this example, we are merging all unique rowlabels from both dicts.
println("EXAMPLE: Conflict detected")
print("EXAMPLE: Conflict detected")
var localrows = localdict["rowlabels"] as? [String]
var cloudrows = clouddict["rowlabels"] as? [String]
if localrows != nil && cloudrows != nil {
println("Both dicts have rowlabels array, will merge cloud array into local array")
print("Both dicts have rowlabels array, will merge cloud array into local array")
for label in cloudrows! {
if !contains(localrows!, label) {
if localrows!.contains(label) {
localrows!.append(label)
}
}
Expand All @@ -46,7 +46,7 @@ class ViewController: UIViewController, UITableViewDataSource, UITableViewDelega
// The dict has changed, thanks to the merge, so we need to resave it
self.syncer.saveDictionary(self.dict, onComplete: {
status in
println("Resaved merged dict. Save status = \(status)")
print("Resaved merged dict. Save status = \(status)")
})
} else if let rows = localrows {
// We only have rows in localdict
Expand Down Expand Up @@ -87,7 +87,7 @@ class ViewController: UIViewController, UITableViewDataSource, UITableViewDelega
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
println("tapped row \(indexPath.row)")
print("tapped row \(indexPath.row)")
let numrows = self.tableView(tableView, numberOfRowsInSection: 1)
if indexPath.row == numrows - 1 {
if var tablerows = self.dict["rowlabels"] as? [String] {
Expand All @@ -101,7 +101,7 @@ class ViewController: UIViewController, UITableViewDataSource, UITableViewDelega
})
self.syncer.saveDictionary(self.dict, onComplete: {
status in
println("Save status = \(status)")
print("Save status = \(status)")
})

}
Expand All @@ -119,7 +119,7 @@ class ViewController: UIViewController, UITableViewDataSource, UITableViewDelega
cell?.textLabel?.text = "Tap here to add row"
} else {
if let tablerows = self.dict["rowlabels"] as? [String] {
println("\(tablerows[indexPath.row])")
print("\(tablerows[indexPath.row])")
cell?.textLabel?.text = tablerows[indexPath.row]
}
}
Expand Down
2 changes: 1 addition & 1 deletion CloudKitDictionarySyncerTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>se.baresi.$(PRODUCT_NAME:rfc1034identifier)</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
Expand Down