SHKeyValueObserverBlocks 2.1.1

SHKeyValueObserverBlocks 2.1.1

TestsTested
LangLanguage Obj-CObjective C
License MIT
ReleasedLast Release Jan 2015

Maintained by Seivan Heidari.



  • By
  • Seivan Heidari

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.