CloneableDataType Protocol
Inner representation of data types which are supported by the Cloneable platform and wrapped with the type erased AnyCloneableData
Overview
The CloneableDataType protocol is designed to define a standardized interface for data types that can be cloned, serialized, and deserialized. It includes a variety of methods for handling the data, checking equality, and working with external representations such as JSON and files.
Protocol Definition
swiftCopy codepublic protocol CloneableDataType {
var bindingValue: Any { get set }
func valueType() -> Any.Type
func getRawValue() -> Any
func getTypeAsString() -> String
func getStringDescription() -> String
func getJXValue(context: JXContext) -> JXValue?
func isEqual(to other: CloneableDataType) -> Bool
init(fileURL: URL, displayName: String) throws
init(json: String) throws // throws CloneableDataError.invalidValue
func getJSONValue() -> String
func saveToFile(fileURL: URL) throws
func getData() -> Data?
}Initialization
Each supported data type can implement it's own initialization based on the implementation requirements.
For example a CloneableString is initialized as:
let cloneableString = CloneableString("Hello world")Whereas CloneableLocation is a bit more complex
let cloneableLocation = CloneableLocation(
latitude: 37.7749, // Required, sample latitude
longitude: -122.4194, // Required, sample longitude
altitude: 30.0, // Optional, providing a sample altitude
)Methods
valueType(): Returns the type of the underlying value.getRawValue(): Retrieves the raw value.getTypeAsString(): Provides the type of the value as aString.getStringDescription(): Returns a string description of the value.getJXValue(context:): Returns aJXValuerepresentation of the value, based on the provided context.isEqual(to:): Determines if the current instance is equal to another instance ofCloneableDataType.Initializers:
init(fileURL:displayName:): Initializes an instance from a file.init(json:): Initializes an instance from a JSON string.
getJSONValue(): Serializes the value to a JSON string.saveToFile(fileURL:): Saves the value to a file.getData(): Returns aDatarepresentation of the value, if supported.
Default Implementations with Extensions
The CloneableDataType protocol provides default implementations for some of its methods. This allows you to implement them, only when needed. Below are default implementations for three methods: init(fileURL:displayName:), saveToFile(fileURL:), and getData().
Extension for Default Implementations
swiftCopy codeextension CloneableDataType {
/// Initializes an instance with a file URL and display name.
/// By default, this initializer throws an error, indicating that the method needs an explicit implementation if required.
public init(fileURL: URL, displayName: String) throws {
throw CloneableDataError.implementationMissing
}
/// Saves the instance to a file at the specified URL.
/// By default, this method throws an error, signifying an issue with saving to file.
/// Implement this method in conforming types where file saving functionality is needed.
public func saveToFile(fileURL: URL) throws {
throw CloneableDataError.errorSavingToFile
}
/// Returns a Data representation of the instance.
/// By default, this method returns nil, indicating no default Data representation is available.
/// Override this method in conforming types that can be represented as Data.
public func getData() -> Data? {
return nil
}
}Description of Default Implementations
Initialization from File (
init(fileURL:displayName:)):This initializer is a common requirement for types that need to be created from a file.
The default implementation throws
CloneableDataError.implementationMissing, indicating that the conforming type must provide a specific implementation if this functionality is required.
Save to File (
saveToFile(fileURL:)):This method is essential for persisting data to files.
The default implementation throws
CloneableDataError.errorSavingToFile, signaling that an explicit implementation is necessary for types where file saving is needed.
Data Representation (
getData()):Provides a way to get a
Datarepresentation of the conforming type.The default implementation returns
nil, suitable for types that do not have a straightforwardDatarepresentation. Types that can be represented asDatashould override this method.
By using these default implementations, types conforming to CloneableDataType can avoid boilerplate code for common or optional functionality, focusing only on the specific implementations they require.
Example Implementation for String
Here's an example of how the CloneableDataType protocol could be implemented for a String:
CloneableString: CloneableDataType, Codable {
private var value: String
// MARK: - Initializers
/// Initializes the CloneableString with a JSON string.
public init(json: String) {
self.value = json
}
/// Initializes the CloneableString with a string value.
public init(_ value: String) {
self.value = value
}
// MARK: - CloneableDataType Conformance
/// Returns the string value as JSON.
public func getJSONValue() -> String {
return value
}
/// Converts the string to a JXValue based on the given context.
public func getJXValue(context: JXContext) -> JXValue? {
let stringValue = getRawValue() as! String
return stringValue.toJX(in: context)
}
/// Dynamic binding value getter and setter.
public var bindingValue: Any {
get { return value }
set { value = newValue as! String }
}
/// Returns the type of the underlying value, which is String.
public func valueType() -> Any.Type {
return String.self
}
/// Gets the raw value of the string.
public func getRawValue() -> Any {
return value
}
/// Returns a string representing the type.
public func getTypeAsString() -> String {
return "string"
}
/// Returns a description of the string.
public func getStringDescription() -> String {
return value
}
/// Compares two CloneableDataType objects for equality.
public func isEqual(to other: CloneableDataType) -> Bool {
if let otherString = other as? CloneableString {
return self.value == otherString.value
}
return false
}
}Last updated

