Skip to content
This repository has been archived by the owner on Nov 12, 2024. It is now read-only.

seivan-archives/SHKeyValueObserverBlocks

Repository files navigation

#SHKeyValueObserverBlocks

CI Status Version Platform License

This pod is used by SHFoundationAdditions as part of several components improving Foundation, UIKit, CoreLocation, GameKit, MapKit and other aspects of an iOS application's architecture

There is also for UIKit for extending UIKit with block alternatives to most components

##Overview

Data-Bindings & Key Value Observing with blocks on top of NSObject. Blocks are hold with a weak reference so you don't have to cleanup when your object is gone. There is an automatic Swizzling config that you can toggle on a per class basis.

##Installation

pod 'SHKeyValueObserverBlocks'

##Setup

Put this either in specific files or your project prefix file

#import "NSObject+SHKeyValueObserverBlocks.h"

or

#import "SHKeyValueObserverBlocks.h"

##Usage

Adding Observer on an NSArray to keep track of your data source
  NSString * path = @"languagesArray";
  NSString * identifier = [self SH_addObserverForKeyPath:path 
                                                  block:^(
                                                  NSKeyValueChange changeType, 
                                                  id oldValue, 
                                                  id newValue, 
                                                  NSIndexPath *indexPath) {
    switch (changeType) {
      case NSKeyValueChangeSetting:
        NSLog(@"Setting %@", newValue);
        break;
      case NSKeyValueChangeInsertion:
        NSLog(@"Inserting %@", newValue);
        break;
      case NSKeyValueChangeRemoval:
        NSLog(@"Removal %@", oldValue);
        break;
      case NSKeyValueChangeReplacement:
        NSLog(@"ChangeReplacement %@ with %@", oldValue, newValue);
        break;
      default:
        break;
    }
  }];
  
  NSLog(@"Starting with NSArray");

  self.languagesArray = @[@"Python"];
  [[self mutableArrayValueForKey:path] addObject:@"C++"];
  [[self mutableArrayValueForKey:path] addObject:@"Objective-c"];
  [[self mutableArrayValueForKey:path] replaceObjectAtIndex:0 withObject:@"Ruby"];
  [[self mutableArrayValueForKey:path] removeObject:@"C++"];
  NSLog(@"%@", self.languagesArray);
Set a uni directional binding with a transform block
NSString * identifier =  [self SH_setBindingUniObserverKeyPath:@"playersDictionary" 
                                                      toObject:self
                                                   withKeyPath:@"othersDictionary"
                                           transformValueBlock:^id(
                                           id object, 
                                           NSString *keyPath, 
                                           id newValue, 
                                           BOOL *shouldAbort) {
    return ((NSObject *)newValue).mutableCopy ;
  }];
Set a bi-directional binding
NSArray * identifiers = [self.model SH_setBindingObserverKeyPath:@"errors" 
                                                        toObject:self 
                                                     withKeyPath:@"errors"];
Can use the macro SHKey() for using selectors as a keyPath for autocomplete goodness.
NSArray * identifiers = [self.model SH_setBindingObserverKeyPath:@"errors" 
                                                        toObject:self 
                                                     withKeyPath:SHKey(errors)"];

##API

#pragma mark - Block Definitions

typedef void (^SHKeyValueObserverSplatBlock)(NSKeyValueChange changeType,
                                             id oldValue, id newValue,
                                             NSIndexPath * indexPath);

typedef void (^SHKeyValueObserverDefaultBlock)(NSString * keyPath,
                                               NSDictionary * change);

typedef id(^SHKeyValueObserverBindingTransformBlock)(id object,
                                                     NSString * keyPath,
                                                     id newValue,
                                                     BOOL *shouldAbort);

@interface NSObject (SHKeyValueObserverBlocks)

#pragma mark - Config
+(BOOL)SH_isAutoRemovingObservers;
+(void)SH_setAutoRemovingObservers:(BOOL)isAutoRemovingObservers;

#pragma mark - Properties
@property(nonatomic,readonly) NSDictionary * SH_observedKeyPaths;

#pragma mark - Add Observers

-(NSString *)SH_addObserverForKeyPath:(NSString *)theKeyPath
                                 block:(SHKeyValueObserverSplatBlock)theBlock;


-(NSString *)SH_addObserverForKeyPaths:(NSArray *)theKeyPaths
                           withOptions:(NSKeyValueObservingOptions)theOptions
                                 block:(SHKeyValueObserverDefaultBlock)theBlock;


#pragma mark - Set Bindings


-(NSArray *)SH_setBindingObserverKeyPath:(NSString *)theKeyPath
                                toObject:(NSObject *)theObject
                             withKeyPath:(NSString *)theOtherKeyPath;

-(NSString *)SH_setBindingUniObserverKeyPath:(NSString *)theKeyPath
                                    toObject:(NSObject *)theObject
                                 withKeyPath:(NSString *)theOtherKeyPath;

-(NSString *)SH_setBindingUniObserverKeyPath:(NSString *)theKeyPath
                                    toObject:(NSObject *)theObject
                                 withKeyPath:(NSString *)theOtherKeyPath
                             transformValueBlock:(SHKeyValueObserverBindingTransformBlock)theBlock;



#pragma mark - Remove Observers
-(void)SH_removeAllObserversWithIdentifiers:(NSArray *)theIdentifiers;
-(void)SH_removeAllObserversForKeyPaths:(NSArray *)theKeyPaths;
-(void)SH_removeAllObservers;


@end

##Credit

Thanks to Yan Rabovik for RSSwizzle

##Contact

If you end up using SHKeyValueObserverBlocks in a project, I'd love to hear about it.

email: [email protected]
twitter: @seivanheidari

License

SHKeyValueObserverBlocks is © 2013 Seivan and may be freely distributed under the MIT license. See the LICENSE.md file.

About

Prefixed self removing Key Value Observers with Blocks.

Resources

License

Stars

Watchers

Forks

Packages

No packages published