Today we thought we’d show you how to add Simperium data sync to an existing iOS app. We’ve selected Listr, a lightweight, open source app that helps you keep track of things on your wish list. Listr works great for having a list on one device, but what if you wanted to access your wish list on another device, such as your iPad? Simperium can help sync the data as soon as it is saved across devices:
Before we continue with the tutorial, you may want to check out the source code to follow along. You can do so via git in the command line git clone -b update/add-simperium https://github.com/Simperium/Listr.git
. Now let’s tweak the code to integrate Simperium!
Note: This tutorial uses Swift, but Simperium still supports Objective-C as well.
1. Configure Project for CocoaPods
Listr wasn’t set up for CocoaPods, so we set up the project to use it so that we can easily include the Simperium iOS library.
- Run
pod init
from the main project directory. - Edit the created
Podfile
, and add the Simperium pod:# Uncomment the next line to define a global platform for your project # platform :ios, '9.0' target 'Listr' do # Comment the next line if you're not using Swift and don't want to use dynamic frameworks use_frameworks! # Pods for Listr pod 'Simperium', '0.8.19' end
- Run
pod install
, and then openListr.xcworkspace
in Xcode.
2. Configure CoreData for Simperium
Listr already uses CoreData, which makes it really simple for us to connect Simperium and start syncing the data.
First up, we will add some CoreData overrides so that Simperium can integrate with the existing data model, and sync data when it is saved automatically. First we go into each data model class, such as Item+CoreDataClass.swift
, and change its parent class from NSManagedObject
to Simperium’s SPManagedObject
:
import Foundation import CoreData import Simperium.SPManagedObject public class Item: SPManagedObject { public override func awakeFromInsert() { super.awakeFromInsert() self.created = NSDate() //Assigning current date to 'created' attribute. } }
Next, we need to tweak how the app manages CoreData storage with a custom NSManagedObjectContext
, NSManagedObjectModel
, and NSPersistentStoreCoordinator
in the main AppDelegate. We can then configure Simperium and authenticate:
@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { ... func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Configure Simperium managedObjectContext = NSManagedObjectContext.init(concurrencyType: NSManagedObjectContextConcurrencyType.mainQueueConcurrencyType) managedObjectContext?.undoManager = nil simperium = Simperium.init(model: managedObjectModel, context: managedObjectContext, coordinator: getPersistentStoreCoordinator()) // Set the login view's icon let spConfig = SPAuthenticationConfiguration.sharedInstance() spConfig?.logoImageName = "AppIcon" // Authenticate will show the login view if no user is signed in simperium?.authenticate(withAppID: "your-app-id", apiKey: "12345", rootViewController: self.window?.rootViewController) return true } // MARK: - Core Data stack func getPersistentStoreCoordinator() -> NSPersistentStoreCoordinator { if (persistentStoreCoordinator != nil) { return persistentStoreCoordinator! } let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask .userDomainMask, true) let documentsDirectory = paths[0] let path = documentsDirectory.appending("/Listr.sqlite") let storeUrl = NSURL.fileURL(withPath: path, isDirectory:false) persistentStoreCoordinator = NSPersistentStoreCoordinator.init(managedObjectModel: self.managedObjectModel) do { try persistentStoreCoordinator?.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeUrl, options: nil) } catch { NSLog("Could not create custom store") } return persistentStoreCoordinator! } var managedObjectModel: NSManagedObjectModel = { let path = Bundle.main.path(forResource: "Listr", ofType: "momd") let model = NSManagedObjectModel.init(contentsOf: NSURL.fileURL(withPath: path!)) return model! }() ... }
You may have noticed the placeholder Simperium app id and key. You can get one by creating an app here and replacing the id and key with your Simperium app’s values.
That’s all! You can run the app, create an account, and start syncing Listr data to all of your devices. We hope you’ve found this tutorial useful and are inspired to add Simperium to your apps. If you have any feedback, please let us know in the comments!
Happy Syncing!
– The Simperium Team
🔄