Skip to content

Instantly share code, notes, and snippets.

@zaneclaes
Created May 4, 2014 15:32
Show Gist options
  • Save zaneclaes/e4a531805ad28022952c to your computer and use it in GitHub Desktop.
Save zaneclaes/e4a531805ad28022952c to your computer and use it in GitHub Desktop.
//
// SNFirebase.m
// SharedNotes
//
// Created by Zane Claes on 4/12/14.
// Copyright (c) 2014 inZania LLC. All rights reserved.
//
#import "SNFirebase.h"
@implementation NSDictionary (DeepCopy)
- (NSMutableDictionary *)mutableDeepCopy
{
return (NSMutableDictionary *)CFBridgingRelease(CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (CFDictionaryRef)self, kCFPropertyListMutableContainers));
}
@end
@implementation NSArray (DeepCopy)
- (NSMutableArray *)mutableDeepCopy
{
return (NSMutableArray *)CFBridgingRelease(CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (CFArrayRef)self, kCFPropertyListMutableContainers));
}
@end
@interface SNFirebase ()
@property (nonatomic, strong) NSString *firebaseURL;
@end
@implementation SNFirebase
- (Firebase*)observe:(NSString*)path eventType:(FEventType)type expectedClass:(Class)cls withBlock:(void (^)(id copiedValue))block {
__block Firebase *fb = path.length ? [self.firebase childByAppendingPath:path] : self.firebase;
[fb observeEventType:type withBlock:^(FDataSnapshot *snapshot) {
if(![snapshot.value isKindOfClass:cls]) {
//block(nil);
DLog(@"Object changed at %@ is not a %@; it is a %@ (%@)",snapshot.ref.description,cls,[snapshot.value class],snapshot.value);
return;
}
id copied = nil;
if(cls == [NSDictionary class] || [cls isSubclassOfClass:[NSDictionary class]] ||
cls == [NSArray class] || [cls isSubclassOfClass:[NSArray class]]) {
copied = [snapshot.value mutableDeepCopy];
}
else {
copied = [snapshot.value mutableCopy];
}
NSAssert([copied isKindOfClass:cls],@"%@ was not a %@ after copying (%@)",copied,cls,[copied class]);
block(copied);
}];
self.observers = self.observers ?: [NSMutableArray new];
[self.observers addObject:fb];
return fb;
}
- (void)startObservingChanges {
NSAssert(NO,@"startObservingChanges should be overwritten");
}
- (void)stopObservingChanges {
[self.firebase removeAllObservers];
for(Firebase *observer in self.observers) {
[observer removeAllObservers];
}
self.observers = nil;
}
- (void)save:(void (^)(BOOL success))completionHandler {
Firebase *fb = [[Firebase alloc] initWithUrl:self.firebaseURL];
[fb setValue:[self.contents mutableDeepCopy] withCompletionBlock:^(NSError *error, Firebase *ref) {
if(completionHandler) {
completionHandler(error ? NO : YES);
}
}];
}
- (void)save {
[self save:nil];
}
- (void)load:(void (^)(BOOL success))block {
Firebase *fb = [[Firebase alloc] initWithUrl:self.firebaseURL];
[fb observeSingleEventOfType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot) {
_contents = [[snapshot.value isKindOfClass:[NSDictionary class]]?snapshot.value:@{} mutableDeepCopy];
block(_contents.allKeys.count > 0);
}];
}
- (Firebase*)firebase {
return [[Firebase alloc] initWithUrl:self.firebaseURL];
}
- (id)initWithFirebase:(Firebase*)firebase contents:(NSDictionary*)contents {
if((self = [super init])) {
_firebaseURL = firebase.description;
_contents = [contents?:@{} mutableDeepCopy];
}
return self;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment