Skip to content

Latest commit

 

History

History
42 lines (27 loc) · 3.64 KB

STORAGE.md

File metadata and controls

42 lines (27 loc) · 3.64 KB

Storage

This module encapsulates the local persistence layer, and provides an implementation of that persistence layer based on CoreData.

High level class diagram

Storage high level class diagram

Public interface

The Storage module exposes its functionality via the StorageManagerType protocol.

This protocol declares getters to StorageType and methods to save or perform an operation on a StorageType

The CoreData stack

The default implementation of the StorageManagerType and StorageType protocols is based on CoreData.

StorageManagerType is implemented by the CoreDataManager class. As the name implies, this class manages a CoreData stack, aggregating a NSPersistentContainer.

When clients of this class request a StorageType, CoreDataManager will return an NSManagedObjectContext.

When CoreDataManager is requested a viewContext, it will provide the persistent container’s viewContext. viewContext should only be used for reading and not writing.

CoreDataManager manages a single background context for write operations, which cannot be accessed directly. Instead, there are two versions of performAndSave methods to use for writing - depending on whether you need to send a result back to the completion closure or not.

Notes:

  • For thread safety, do not send any NSManagedObject instance to the completion closure of performAndSave. There's an assertion to ensure at debug runtime this does not happen.
  • For performance reasons, please be mindful with fetch requests. Avoid making multiple fetch requests in for loops. This can be replaced by a single fetch request for a list of objects instead.
  • For attributes of type Transformable, if the transformer is NSSecureUnarchiveFromData, make sure to input a class type in the Custom Class field in the Core Data model. Using a Swift type (e.g. [Int64] or [String]) would cause an error logged in Xcode 16.
  • We have a launch argument -enforce-core-data-write-in-background enabled by default in the WooCommerce scheme. This will intentionally crash the app in the debug mode when one attempts to perform write operations in the main thread with the view context.
  • We also enable -com.apple.CoreData.ConcurrencyDebug launch argument by default to get notified when there's a concurrency issue with our Core Data stack. Please keep an eye out for errors from Core Data in the console log and report any problems when you see them.
  • When setting an attribute of type Date/UUID/URI as non-optional, a default value should be set or the property should be kept optional in Swift. More details here.

File storage

The Storage module also exposes a protocol, called FileStorage to abstract saving and reading data to and from local storage.

The default implementation of this protocol, PListFileStorage provides support for .plist files.

File storage is used mostly for local app settings.

Model objects

This module also provides extensions to make the model objects declared in the Networking module coredata-compliant.

That is achieved by extending the model objects declared in Networking to make them extend NSManagedObject and provide @NSManaged properties and CoreData compliant accessors to some of those properties. Those extensions can be generated directly inside Xcode.