Commit cd2b7c7f by Brent Gulanowski

Add new custom value transformers.

parent 949f3d13
//
// NSEntityDescription+BUYAdditions.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import <CoreData/CoreData.h>
@protocol BUYObject;
@interface NSEntityDescription (BUYAdditions)
/**
* A dictionary of @{ NSString : NSPropertyDescription } where the keys are property names.
* By default, returns all attributes (instances of NSAttributeDescription) and relationships (NSRelationshipDescription).
*/
@property (nonatomic, readonly, getter=buy_JSONEncodedProperties) NSDictionary *JSONEncodedProperties;
/**
* Returns the custom subclass used for instances of this entity.
*/
@property (nonatomic, readonly, getter=buy_managedObjectClass) Class managedObjectClass;
/**
* Signifies whether this entity is private to the app (not used by the endpoint).
*/
- (BOOL)buy_isPrivate;
/**
* Generate JSON, recursively, from the provided model object.
*/
- (NSDictionary *)buy_JSONForObject:(id<BUYObject>)object;
/**
* Generate JSON, recursively, for each model in the provided array.
*/
- (NSArray *)buy_JSONForArray:(NSArray<NSObject<BUYObject> *> *)array;
/**
* Update the properties of the given model object, and child objects, using the given JSON dictionary.
*/
- (void)buy_updateObject:(id<BUYObject>)object withJSON:(NSDictionary *)JSON;
@end
//
// NSEntityDescription+BUYAdditions.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "NSEntityDescription+BUYAdditions.h"
#import "BUYModelManagerProtocol.h"
#import "BUYObjectProtocol.h"
#import "NSDictionary+BUYAdditions.h"
#import "NSPropertyDescription+BUYAdditions.h"
#import "NSString+BUYAdditions.h"
@interface NSEntityDescription ()
/**
* Returns a block that maps JSON keys into a property name.
* Used when updating model objects from JSON.
*/
@property (nonatomic, readonly, getter=buy_JSONKeyEncodingMap) BUYStringMap JSONKeyEncodingMap;
/**
* Returns a block that maps property names into JSON keys.
* Used when generating JSON data from model objects.
*/
@property (nonatomic, readonly, getter=buy_JSONKeyDecodingMap) BUYStringMap JSONKeyDecodingMap;
@end
@implementation NSEntityDescription (BUYAdditions)
#pragma mark - Derived Properties
- (Class)buy_managedObjectClass
{
return NSClassFromString(self.managedObjectClassName);
}
- (BOOL)buy_isPrivate
{
return [self.userInfo[@"private"] boolValue];
}
#pragma mark - Property Lookup Conveniences
- (NSDictionary *)buy_JSONEncodedProperties
{
NSMutableDictionary *properties = [NSMutableDictionary dictionaryWithDictionary:[self attributesByName]];
[properties addEntriesFromDictionary:[self relationshipsByName]];
return properties;
}
- (NSPropertyDescription *)buy_propertyWithName:(NSString *)name
{
return self.propertiesByName[name];
}
#pragma mark - JSON <-> Property key mapping
// TODO: profile and optimize if necessary
- (BUYStringMap)buy_JSONKeyEncodingMap
{
NSDictionary *mapping = [self buy_PropertyNameMapping];
return ^(NSString *name) {
return mapping[name] ?: [name buy_snakeCaseString];
};
}
- (BUYStringMap)buy_JSONKeyDecodingMap
{
NSDictionary *mapping = [self buy_JSONKeyMapping];
return ^(NSString *key) {
return mapping[key] ?: [key buy_camelCaseString];
};
}
#pragma mark - Property lookup
+ (NSDictionary *)buy_defaultPropertyNameMapping
{
return @{ @"identifier" : @"id" };
}
// json key -> property name
- (NSDictionary *)buy_JSONKeyMapping
{
return [[self buy_PropertyNameMapping] buy_reverseDictionary];
}
// property name -> json key
- (NSDictionary *)buy_PropertyNameMapping
{
return [self.propertiesByName buy_dictionaryByMappingValuesWithBlock:^(NSPropertyDescription *property) {
return [self buy_JSONKeyForPropertyName:property.name];
}];
}
- (NSString *)buy_JSONKeyForPropertyName:(NSString *)name
{
return [self buy_propertyWithName:name].JSONPropertyKey ?: [NSEntityDescription buy_defaultPropertyNameMapping][name];
}
#pragma mark - Object-Plist transformation
- (NSDictionary *)buy_JSONForObject:(NSObject<BUYObject> *)object
{
NSAssert([self isEqual:[object entity]], @"%@ entity cannot decode %@ objects", self.name, [object entity].name);
// The encoding map is a block which converts property names into JSON keys.
BUYStringMap encodingMap = self.JSONKeyEncodingMap;
NSMutableDictionary *results = [NSMutableDictionary dictionary];
[object.JSONEncodedProperties enumerateKeysAndObjectsUsingBlock:^(NSString *propertyName, NSPropertyDescription *property, BOOL *stop) {
id value = [object valueForKey:propertyName];
if (value) {
// Each property is responsible for knowing how to generate JSON for its value
// Some properties do not encode themselves in JSON, so we mut check for nil
id JSONValue = [property buy_JSONForValue:value];
if (JSONValue) {
NSString *JSONKey = encodingMap(propertyName) ?: propertyName;
results[JSONKey] = JSONValue;
}
}
}];
return results;
}
- (NSArray *)buy_JSONForArray:(NSArray<NSObject<BUYObject> *> *)array
{
return [array buy_map:^(NSObject<BUYObject> *object) {
return [self buy_JSONForObject:object];
}];
}
- (void)buy_updateObject:(NSObject<BUYObject> *)object withJSON:(NSDictionary *)JSON
{
NSAssert([self isEqual:[object entity]], @"%@ entity cannot decode %@ objects", self.name, [object entity].name);
NSDictionary *properties = self.propertiesByName;
// The decoding map is a block which converts the key in the JSON into a property name.
BUYStringMap decodingMap = self.JSONKeyDecodingMap;
// Iterate through the JSON, and generate the native value using the property object.
NSMutableDictionary *results = [NSMutableDictionary dictionary];
[JSON enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, BOOL * stop) {
NSString *propertyName = decodingMap(key) ?: key;
NSPropertyDescription *property = properties[propertyName];
// Each property is responsible for knowing how to parse JSON for its value
results[propertyName] = [property buy_valueForJSON:value object:object];
}];
[object setValuesForKeysWithDictionary:results];
}
@end
//
// NSPropertyDescription+BUYAdditions.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import <CoreData/CoreData.h>
@class BUYModelManager;
@protocol BUYObject;
// property user info keys
extern NSString * const BUYJSONValueTransformerUserInfoKey; // = @"JSONValueTransformer";
extern NSString * const BUYJSONPropertyKeyUserInfoKey; // = @"JSONPropertyKey";
@interface NSPropertyDescription (BUYAdditions)
/**
* The name of a value transformer used to convert to JSON values and back.
* Uses the value specified in the property's user info dictionary under the "JSONValueTransformer" key.
*
* Currently only two transformers are supported: "BUYPublicationsDate" and "BUYShippingRateDate".
* Currently, only attributes (instances of NSAttributeDescription) use value transformers.
*/
@property (nonatomic, readonly, getter=buy_JSONValueTransformerName) NSString *JSONValueTransformerName;
/**
* The value transformer corresponding to the JSONValueTransformerName. If no name is specified,
* the value is not changed.
*/
@property (nonatomic, readonly, getter=buy_JSONValueTransformer) NSValueTransformer *JSONValueTransformer;
/**
* The name of the key to use for the property, instead of its name, when generating JSON. Requires
* adding an entry in the Property userInfo, in the Core Data model file, with the key "JSONPropertyKey".
*/
@property (nonatomic, readonly, getter=buy_JSONPropertyKey) NSString *JSONPropertyKey;
/**
* Convert the provided JSON into the appropriate data type, either simple values or model objects.
* For relationships, uses the destinationEntity to recursively fetch or create related objects as needed.
*/
- (id)buy_valueForJSON:(id)JSON object:(id<BUYObject>)object;
/**
* Convert the provided object, a value corresponding to the property on the parent object.
*
* For relationships, related object data is generated according to the following rules:
* - if the "JSONPropertyKey" is set in the user info dictionary, and it ends in "_id" (or "_ids")
* then encode the related object(s) using only their identifier(s)
* - if the inverse relationship delete rule is "Cascade", or its entity is marked private,
* or the relationship is many-to-many, do not encode the object for this relationship
* (it is inferred that the related object owns this object; this avoids a loop in the encoding)
* - otherwise, encode the full JSON representation of the related object(s)
*/
- (id)buy_JSONForValue:(id)value;
@end
@interface NSRelationshipDescription (BUYAdditions)
/**
* Used during JSON transformation. If the value is YES, parsed JSON is expected to be a number
* representing an object identifier, which will be resolved by fetching from the persistent store.
* Likewise, generated JSON will include identifiers in place of full objects.
*/
@property (nonatomic, readonly, getter=buy_encodesIdInJSON) BOOL encodesIdInJSON;
/**
* YES if the delete rule is not Cascading and the entity is not private.
*/
@property (nonatomic, readonly, getter=buy_allowsInverseEncoding) BOOL allowsInverseEncoding;
/**
* YES if this relationship and its inverse are both toMany
*/
@property (nonatomic, readonly, getter=buy_isManyToMany) BOOL manyToMany;
@end
//
// NSPropertyDescription+BUYAdditions.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "NSPropertyDescription+BUYAdditions.h"
#import "BUYModelManagerProtocol.h"
#import "BUYObjectProtocol.h"
#import "NSDecimalNumber+BUYAdditions.h"
#import "NSArray+BUYAdditions.h"
#import "NSException+BUYAdditions.h"
#import "NSEntityDescription+BUYAdditions.h"
#import "BUYDateTransformer.h"
#import "BUYDecimalNumberTransformer.h"
#import "BUYIdentityTransformer.h"
#import "BUYURLTransformer.h"
// User Info Keys
NSString * const BUYJSONValueTransformerUserInfoKey = @"JSONValueTransformer";
NSString * const BUYJSONPropertyKeyUserInfoKey = @"JSONPropertyKey";
// This is defined by mogenerator
static NSString * const BUYAttributeValueClassNameKey = @"attributeValueClassName";
#pragma mark -
@interface NSObject (BUYValueTransforming)
- (BOOL)buy_isValidObject;
+ (NSString *)buy_JSONValueTransformerName;
@end
#pragma mark -
@implementation NSPropertyDescription (BUYAdditions)
- (NSString *)buy_JSONValueTransformerName
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// default transformer
[NSValueTransformer setValueTransformer:[[BUYIdentityTransformer alloc] init] forName:BUYIdentityTransformerName];
// attribute type transformers
[NSValueTransformer setValueTransformer:[[BUYDecimalNumberTransformer alloc] init] forName:BUYDecimalNumberTransformerName];
// value type transformers
[NSValueTransformer setValueTransformer:[[BUYURLTransformer alloc] init] forName:BUYURLTransformerName];
});
return self.userInfo[BUYJSONValueTransformerUserInfoKey];
}
- (NSString *)buy_JSONPropertyKey
{
return self.userInfo[BUYJSONPropertyKeyUserInfoKey];
}
- (NSValueTransformer *)buy_JSONValueTransformer
{
return [NSValueTransformer valueTransformerForName:self.JSONValueTransformerName];
}
- (id)buy_valueForJSON:(id)JSON object:(id<BUYObject>)object
{
@throw BUYAbstractMethod();
}
- (id)buy_JSONForValue:(id)object
{
@throw BUYAbstractMethod();
}
@end
#pragma mark -
static NSString *JSONValueTransformerNameForAttributeType(NSAttributeType type)
{
NSString *name = nil;
switch (type) {
case NSDateAttributeType:
name = BUYDateTransformerName;
break;
case NSDecimalAttributeType:
name = BUYDecimalNumberTransformerName;
break;
default:
break;
}
return name;
}
@implementation NSAttributeDescription (BUYAdditions)
- (NSString *)buy_attributeValueClassName
{
return self.userInfo[BUYAttributeValueClassNameKey];
}
- (Class)buy_attributeValueClass
{
return NSClassFromString([self buy_attributeValueClassName]);
}
- (NSString *)buy_JSONValueTransformerName
{
NSString *name = [super buy_JSONValueTransformerName];
if (name == nil) {
name = JSONValueTransformerNameForAttributeType(self.attributeType);
}
if (name == nil) {
name = [[self buy_attributeValueClass] buy_JSONValueTransformerName];
}
if (name == nil) {
name = BUYIdentityTransformerName;
}
return name;
}
- (id)buy_valueForJSON:(id)JSON object:(id<BUYObject>)object
{
// An attribute's value is determined by the specified transformer.
// An Identity transform returns the same value. `nil` is converted into `NSNull`.
id transformedValue = [JSON buy_isValidObject] ? [self.JSONValueTransformer reverseTransformedValue:JSON] : [NSNull null];
return transformedValue ?: [NSNull null];
}
- (id)buy_JSONForValue:(id)object
{
// An attribute's JSON is determined by the specified transformer.
// An identify transform returns the same value.
return [self.JSONValueTransformer transformedValue:object];
}
@end
#pragma mark -
@implementation NSRelationshipDescription (BUYAdditions)
- (NSString *)encodesIdSuffix
{
return (self.isToMany ? @"_ids" : @"_id");
}
- (BOOL)buy_encodesIdInJSON
{
return [self.JSONPropertyKey hasSuffix:[self encodesIdSuffix]];
}
- (id)buy_transformArray:(NSArray<id<BUYObject>> *)array
{
return self.isOrdered ? [NSOrderedSet orderedSetWithArray:array] : [NSSet setWithArray:array];
}
- (id)buy_objectForJSON:(id)JSON modelManager:(id<BUYModelManager>)modelManager
{
NSString *entityName = self.destinationEntity.name;
// If we are expecting an object `id` the object should already exist.
// Otherwise let the object context decide how to resolve the object and update it.
if (self.encodesIdInJSON) {
return [modelManager buy_objectWithEntityName:entityName identifier:JSON];
}
else {
return [modelManager buy_objectWithEntityName:entityName JSONDictionary:JSON];
}
}
- (id)buy_collectionForJSON:(NSArray *)JSON object:(id<BUYObject>)object
{
NSString *entityName = self.destinationEntity.name;
NSArray<id<BUYObject>> *array;
// If we are expecting an array of object `ids`, the objects should already exist.
// Otherwise, let the object context decide how to resolve the objects and update them.
// If device caching is not provided, this will return nothing.
if (self.encodesIdInJSON) {
array = [object.modelManager buy_objectsWithEntityName:entityName identifiers:JSON];
}
else {
array = [object.modelManager buy_objectsWithEntityName:entityName JSONArray:JSON];
}
// Transform the array to the correct container type (`NSSet` or `NSOrderedSet`).
return [self buy_transformArray:array];
}
- (id)buy_valueForJSON:(id)JSON object:(id<BUYObject>)object
{
// A relationship's value is provided by the object context.
// The logic for decoding JSON is slightly different for to-one and to-many relationships.
// NOTE: by default, without a caching system, inverse relationships are not supported.
if (JSON && ![JSON isEqual:[NSNull null]]) {
if (self.isToMany) {
return [self buy_collectionForJSON:JSON object:object];
}
else {
return [self buy_objectForJSON:JSON modelManager:object.modelManager];
}
}
else {
return nil;
}
}
- (id)buy_JSONForValue:(id)value
{
return self.toMany ? [self buy_JSONForCollection:value] : [self buy_JSONForObject:value];
}
- (NSArray *)buy_JSONForCollection:(id)collection
{
if (self.manyToMany) {
return nil;
}
NSArray *array = [self buy_arrayForCollection:collection];
return self.encodesIdInJSON ? [array valueForKey:@"identifier"] : [self.destinationEntity buy_JSONForArray:array];
}
- (NSArray *)buy_arrayForCollection:(id)collection
{
return self.ordered ? [collection array] : [collection allObjects];
}
- (id)buy_JSONForObject:(NSObject<BUYObject> *)object
{
// JSON generation for a relationship depends on the rules defined in the model.
// The model can explicitly specify using an `id` encoding.
// Alternately, if the relationship is compatible, encode the entire object.
// We do not encode related objects unless three conditions are satisfied:
// 1. the relationship is not many-to-many
// 2. the inverse relationship is not an ownership relationship
// (this is inferred from the `NSCascadeDeleteRule` used by owning objects)
// 3. the relationship is to a "private" entity (not known to the API)
if (self.encodesIdInJSON) {
return [[object valueForKey:self.name] identifier];
}
else if (!self.inverseRelationship || self.inverseRelationship.allowsInverseEncoding) {
return [self.destinationEntity buy_JSONForObject:object];
}
else {
return nil;
}
}
- (BOOL)buy_isManyToMany
{
return self.toMany && self.inverseRelationship.toMany;
}
- (BOOL)buy_allowsInverseEncoding
{
return self.deleteRule != NSCascadeDeleteRule && ![self.entity buy_isPrivate];
}
@end
#pragma mark -
@implementation NSFetchedPropertyDescription (BUYAdditions)
- (id)buy_valueForJSON:(id)JSON object:(id<BUYObject>)object
{
return nil;
}
- (id)buy_reverseTransformedJSONValue:(id)value
{
return nil;
}
@end
#pragma mark -
// We could be really clever here and use an algorithm for string transformation
// but it's not worth it right now.
@implementation NSObject (BUYValueTransforming)
+ (NSString *)buy_JSONValueTransformerName
{
return BUYIdentityTransformerName;
}
- (BOOL)buy_isValidObject
{
return YES;
}
@end
@implementation NSNull (BUYValueTransforming)
- (BOOL)buy_isValidObject
{
return NO;
}
@end
@implementation NSURL (BUYValueTransforming)
+ (NSString *)buy_JSONValueTransformerName
{
return BUYURLTransformerName;
}
@end
//
// BUYModelManagerProtocol.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import <CoreData/CoreData.h>
/**
* A protocol for defining an object that can store and retrieve model objects from a data store or other cache.
*/
@protocol BUYModelManager <NSObject>
/**
* Returns an entity given its name.
*
* @param entityName Name of the entity from the Core Data managed object model.
*
* @return The entity description matching the name.
*/
- (NSEntityDescription *)buy_entityWithName:(NSString *)entityName;
/**
* If the JSON contains a key representing the unique identifier, and there is an existing cached object that matches that identifier,
* then that object will be updated with the remaining entries in the JSON. If no such object exists, a new object is created, and
* sent -updateWithJSON:.
*
* @param entityName Name of the entity from the Core Data managed object model.
* @param JSON The JSON representing the object.
*
* @return A new or existing model object.
*/
- (id<BUYObject>)buy_objectWithEntityName:(NSString *)entityName JSONDictionary:(NSDictionary *)JSON;
- (NSArray<id<BUYObject>> *)buy_objectsWithEntityName:(NSString *)entityName JSONArray:(NSArray *)JSON;
/**
* Cache-based model managers may resolve objects based on their identifier. The alternative is to return nil.
* Only supported by models whose entity declares an "identifier" attribute.
*
* @param entityName Name of the entity from the Core Data managed object model.
* @param identifier A shopify object identifier of an existing object in the local data cache.
*
* @return An object from the cache matching the provided identifier, or nil if no matching object is found.
*/
- (id<BUYObject>)buy_objectWithEntityName:(NSString *)entityName identifier:(NSNumber *)identifier;
/**
* Find all the objects in the cache matching the provided identifiers.
*
* @param entityName Name of the entity from the Core Data managed object model.
* @param identifiers An array of Shopify object identifiers.
*
* @return An array of objects from the cache matching the provided identifiers, if any.
*/
- (NSArray<id<BUYObject>> *)buy_objectsWithEntityName:(NSString *)entityName identifiers:(NSArray *)identifiers;
/**
* If there is a local cache available, and the object is cached, it is flushed from the cache. Depending on the type of
* caching in use (if any), the provided object may no longer be valid, and references should be reset. If the cache
* supports stand-alone objects, and the object is modified or passed into the SDK, it could be re-inserted into the cache.
*
* If Core Data is used for local caching, purging is equivalent to deletion. (see -deleteObject[WithIdentifier]:error:)
*
* If the object is not in the cache (or there is no cache), does nothing.
*
* @param object An existing model object.
* @param error A pointer to an error. May be NULL.
*
* @return YES if the object was successfully removed from the cache. NO if there was an error.
*/
- (BOOL)buy_purgeObject:(id<BUYObject>)object error:(NSError **)error;
/**
* Update the cached version of the object given the current state of the object.
*
* @param object An existing model object.
*/
- (void)buy_refreshCacheForObject:(id<BUYObject>)object;
/**
*
* @param entityName Name of the entity from the Core Data managed object model.
* @param predicate An NSPredicate that identifies objects that should be deleted from the cache.
*
* @return YES if the purge was successful. NO if there was a problem.
*/
- (BOOL)buy_purgeObjectsWithEntityName:(NSString *)entityName matchingPredicate:(NSPredicate *)predicate;
@end
//
// BUYObjectProtocol.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import <Foundation/Foundation.h>
@protocol BUYModelManager;
/**
* The BUYObject protocol is adopted by the common superclasses of both persistent and transient model classes.
*
*/
@protocol BUYObject <NSObject>
@property (nonatomic, readonly, weak) id<BUYModelManager> modelManager;
/**
* Transient model objects need an entity for introspection.
*/
@property (nonatomic, readonly, weak) NSEntityDescription *entity;
/**
* A dictionary of @{ NSString : NSPropertyDescription } where the keys are property names.
* By default, returns the same value defined on NSEntityDescription (from BUYAdditions).
*/
@property (nonatomic, readonly) NSDictionary *JSONEncodedProperties;
/**
* Convenience static property overridden by auto-generated model files.
*/
+ (NSString *)entityName;
/**
* A derived property used to generate or apply JSON data. Values are calculated, recursively, automatically.
*/
@property (nonatomic, strong) NSDictionary *JSONDictionary;
/**
* A predicate composed of values from the JSON. For objects that do not have an "identifier"/"id" property.
*/
+ (NSPredicate *)fetchPredicateWithJSON:(NSDictionary *)JSONDictionary;
/**
* Persistent classes return YES; transient classes return NO.
*/
+ (BOOL)isPersistentClass;
/**
* Conforming classes should override to specify whether to use dirty tracking to restrict generated JSON to only changed values.
*/
+ (BOOL)tracksDirtyProperties;
/**
* Use the values in the given dictionary to update properties.
*/
- (void)updateWithJSONDictionary:(NSDictionary *)dictionary;
@optional
- (instancetype)initWithModelManager:(id<BUYModelManager>)modelManager JSONDictionary:(NSDictionary *)dictionary;
@end
//
// BUYDateTransformer.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import <Foundation/Foundation.h>
extern NSString * const BUYDateTransformerName; // = @"BUYDate";
/**
* Transforms a date object into a string and back using the provided format string.
*/
@interface BUYDateTransformer : NSValueTransformer
+ (instancetype)dateTransformerWithFormat:(NSString *)format;
@end
//
// BUYDateTransformer.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "BUYDateTransformer.h"
NSString * const BUYDateTransformerName = @"BUYDate";
@interface BUYDateTransformer ()
@property (nonatomic, strong) NSDateFormatter *dateFormatter;
@end
@implementation BUYDateTransformer
- (instancetype)initWithDateFormatter:(NSDateFormatter *)formatter
{
self = [super init];
if (self) {
self.dateFormatter = formatter;
}
return self;
}
- (NSString *)transformedValue:(NSDate *)value
{
return [self.dateFormatter stringFromDate:value];
}
- (NSDate *)reverseTransformedValue:(NSString *)value
{
return [self.dateFormatter dateFromString:value];
}
+ (instancetype)dateTransformerWithFormat:(NSString *)format
{
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:format];
return [[self alloc] initWithDateFormatter:formatter];
}
+ (BOOL)allowsReverseTransformation
{
return YES;
}
+ (Class)transformedValueClass
{
return [NSString class];
}
@end
//
// BUYDecimalNumberTransformer.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import <Foundation/Foundation.h>
extern NSString * const BUYDecimalNumberTransformerName; // = @"BUYDecimalNumber";
/**
* Transforms a decimal number object into a string and back.
*/
@interface BUYDecimalNumberTransformer : NSValueTransformer
@end
//
// BUYDecimalNumberTransformer.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "BUYDecimalNumberTransformer.h"
#import "NSDecimalNumber+BUYAdditions.h"
NSString * const BUYDecimalNumberTransformerName = @"BUYDecimalNumber";
@implementation BUYDecimalNumberTransformer
+ (Class)transformedValueClass
{
return [NSString class];
}
+ (BOOL)allowsReverseTransformation
{
return YES;
}
- (id)transformedValue:(NSDecimalNumber *)value
{
return [value stringValue];
}
- (id)reverseTransformedValue:(id)value
{
return [NSDecimalNumber buy_decimalNumberFromJSON:value];
}
@end
//
// BUYDeliveryRangeTransformer.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import <Foundation/Foundation.h>
extern NSString * const BUYShippingRateDateTransformerName; // = @"BUYShippingRateDate";
extern NSString * const BUYShippingRateDateFormat; // = @"yyyy-MM-dd'T'HH:mm:ss.SSSZ";
@interface BUYDeliveryRangeTransformer : NSValueTransformer
@end
//
// BUYDeliveryRangeTransformer.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "BUYDeliveryRangeTransformer.h"
#import "BUYDateTransformer.h"
#import "NSArray+BUYAdditions.h"
NSString * const BUYShippingRateDateTransformerName = @"BUYShippingRateDate";
NSString * const BUYShippingRateDateFormat = @"yyyy-MM-dd'T'HH:mm:ss.SSSZ";
@implementation BUYDeliveryRangeTransformer
+ (void)initialize
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[NSValueTransformer setValueTransformer:[BUYDateTransformer dateTransformerWithFormat:BUYShippingRateDateFormat] forName:BUYShippingRateDateTransformerName];
});
}
- (NSArray *)transformedValue:(NSArray *)value
{
NSValueTransformer *dateTransformer = [NSValueTransformer valueTransformerForName:BUYShippingRateDateTransformerName];
return [value buy_map:^(NSDate *date) {
return [dateTransformer transformedValue:date];
}];
}
- (NSArray *)reverseTransformedValue:(NSArray *)value
{
NSValueTransformer *dateTransformer = [NSValueTransformer valueTransformerForName:BUYShippingRateDateTransformerName];
return [value buy_map:^(NSString *dateString) {
return [dateTransformer reverseTransformedValue:dateString];
}];
}
+ (BOOL)allowsReverseTransformation
{
return YES;
}
+ (Class)transformedValueClass
{
return [NSString class];
}
@end
//
// BUYFlatCollectionTransformer.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import <Foundation/Foundation.h>
/**
* Transforms an array of objects into a string with given separator.
*/
@interface BUYFlatCollectionTransformer : NSValueTransformer
+ (instancetype)arrayTransformerWithElementTransformer:(NSValueTransformer *)elementTransformer separator:(NSString *)separator;
+ (instancetype)setTransformerWithElementTransformer:(NSValueTransformer *)elementTransformer separator:(NSString *)separator;
+ (instancetype)orderedSetTransformerWithElementTransformer:(NSValueTransformer *)elementTransformer separator:(NSString *)separator;
/**
* Default to using the identity transformer and a space as separator.
*/
+ (instancetype)arrayTransformer;
+ (instancetype)setTransformer;
+ (instancetype)arrayTransformerWithSeparator:(NSString *)separator;
+ (instancetype)setTransformerWithSeparator:(NSString *)separator;
@end
//
// BUYFlatCollectionTransformer.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "BUYFlatCollectionTransformer.h"
#import "BUYIdentityTransformer.h"
#import "NSArray+BUYAdditions.h"
@interface BUYFlatCollectionTransformer ()
@property (nonatomic, weak) Class collectionClass;
@property (nonatomic, strong) NSValueTransformer *elementTransformer;
@property (nonatomic, strong) NSString *separator;
@end
@implementation BUYFlatCollectionTransformer
+ (instancetype)collectionTransformerWithClass:(Class)klass elementTransformer:(NSValueTransformer *)elementTransformer separator:(NSString *)separator
{
BUYFlatCollectionTransformer *transformer = [[BUYFlatCollectionTransformer alloc] init];
transformer.collectionClass = klass;
transformer.separator = separator;
transformer.elementTransformer = elementTransformer;
return transformer;
}
+ (instancetype)arrayTransformerWithElementTransformer:(NSValueTransformer *)elementTransformer separator:(NSString *)separator
{
return [self collectionTransformerWithClass:[NSArray class] elementTransformer:elementTransformer separator:separator];
}
+ (instancetype)arrayTransformer
{
return [self arrayTransformerWithElementTransformer:[[BUYIdentityTransformer alloc] init] separator:@" "];
}
+ (instancetype)arrayTransformerWithSeparator:(NSString *)separator
{
return [self arrayTransformerWithElementTransformer:[[BUYIdentityTransformer alloc] init] separator:separator];
}
+ (instancetype)setTransformerWithElementTransformer:(NSValueTransformer *)elementTransformer separator:(NSString *)separator
{
return [self collectionTransformerWithClass:[NSSet class] elementTransformer:elementTransformer separator:separator];
}
+ (instancetype)setTransformerWithSeparator:(NSString *)separator
{
return [self setTransformerWithElementTransformer:[[BUYIdentityTransformer alloc] init] separator:separator];
}
+ (instancetype)setTransformer
{
return [self setTransformerWithSeparator:@" "];
}
+ (instancetype)orderedSetTransformerWithElementTransformer:(NSValueTransformer *)elementTransformer separator:(NSString *)separator
{
return [self collectionTransformerWithClass:[NSOrderedSet class] elementTransformer:elementTransformer separator:separator];
}
+ (instancetype)orderedSetTransformerWithSeparator:(NSString *)separator
{
return [self orderedSetTransformerWithElementTransformer:[[BUYIdentityTransformer alloc] init] separator:separator];
}
+ (Class)transformedValueClass
{
return [NSString class];
}
+ (BOOL)allowsReverseTransformation
{
return YES;
}
- (NSString *)transformedValue:(id)value
{
return [[[value buy_array] buy_map:^(id element) {
return [_elementTransformer transformedValue:element];
}] componentsJoinedByString:self.separator];
}
- (id)reverseTransformedValue:(NSString *)value
{
NSArray *array = [[value componentsSeparatedByString:self.separator] buy_map:^(NSString *string) {
return [_elementTransformer reverseTransformedValue:string];
}];
return [_collectionClass buy_convertArray:array];
}
@end
//
// BUYIdentityTransformer.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import <Foundation/Foundation.h>
extern NSString * const BUYIdentityTransformerName; // = @"BUYIdentity";
/**
* Transforms a value into itself.
*/
@interface BUYIdentityTransformer : NSValueTransformer
@end
//
// BUYIdentityTransformer.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "BUYIdentityTransformer.h"
NSString * const BUYIdentityTransformerName = @"BUYIdentity";
@implementation BUYIdentityTransformer
- (id)transformedValue:(id)value
{
return value;
}
- (id)reverseTransformedValue:(id)value
{
return value;
}
+ (BOOL)allowsReverseTransformation
{
return YES;
}
+ (Class)transformedValueClass
{
return [NSObject class];
}
@end
//
// BUYURLTransformer.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import <Foundation/Foundation.h>
extern NSString * const BUYURLTransformerName; // = @"BUYURL";
/**
* Transforms a URL object into a string and back.
*/
@interface BUYURLTransformer : NSValueTransformer
@end
//
// BUYURLTransformer.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "BUYURLTransformer.h"
NSString * const BUYURLTransformerName = @"BUYURL";
@implementation BUYURLTransformer
+ (Class)transformedValueClass
{
return [NSString class];
}
+ (BOOL)allowsReverseTransformation
{
return YES;
}
- (id)transformedValue:(NSURL *)value
{
return [value absoluteString];
}
- (id)reverseTransformedValue:(NSString *)value
{
return [NSURL URLWithString:value];
}
@end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment