Convert Figma logo to code with AI

facebookarchive logoKVOController

Simple, modern, thread-safe key-value observing for iOS and OS X.

7,342
925
7,342
15

Top Related Projects

Cocoa framework and Obj-C dynamism bindings for ReactiveSwift.

24,358

Reactive Programming in Swift

Performant animated GIF engine for iOS

A delightful networking framework for iOS, macOS, watchOS, and tvOS.

11,320

Model framework for Cocoa and Cocoa Touch

MBProgressHUD + Customizations

Quick Overview

KVOController is a Key-Value Observing (KVO) library for iOS and macOS, developed by Facebook. It simplifies the implementation of KVO by providing a block-based API and automatic observer removal, reducing boilerplate code and potential memory leaks.

Pros

  • Simplifies KVO implementation with a clean, block-based API
  • Automatically removes observers, preventing common memory management issues
  • Supports both Objective-C and Swift
  • Provides thread-safe observation

Cons

  • No longer actively maintained (archived repository)
  • May not incorporate latest iOS/macOS KVO improvements
  • Requires adding an external dependency to projects
  • Limited documentation and examples

Code Examples

  1. Observing a single keypath:
[FBKVOController observe:object keyPath:@"username" options:NSKeyValueObservingOptionNew block:^(id observer, id object, NSDictionary *change) {
    NSLog(@"Username changed to: %@", change[NSKeyValueChangeNewKey]);
}];
  1. Observing multiple keypaths:
[FBKVOController observe:object keyPaths:@[@"firstName", @"lastName"] options:NSKeyValueObservingOptionNew block:^(id observer, id object, NSDictionary *change) {
    NSLog(@"Name changed: %@ %@", object.firstName, object.lastName);
}];
  1. Using Swift with KVOController:
KVOController(observer: self).observe(object, keyPath: "progress", options: [.new]) { [weak self] _, _, change in
    if let newValue = change[NSKeyValueChangeKey.newKey] as? Float {
        self?.progressView.progress = newValue
    }
}

Getting Started

  1. Add KVOController to your project using CocoaPods:
pod 'KVOController'
  1. Import the library in your Objective-C or Swift file:
#import <KVOController/KVOController.h>

or for Swift:

import KVOController
  1. Create a KVOController instance and start observing:
@property (nonatomic, strong) FBKVOController *kvoController;

self.kvoController = [FBKVOController controllerWithObserver:self];
[self.kvoController observe:object keyPath:@"property" options:NSKeyValueObservingOptionNew block:^(id observer, id object, NSDictionary *change) {
    // Handle changes
}];

Competitor Comparisons

Cocoa framework and Obj-C dynamism bindings for ReactiveSwift.

Pros of ReactiveCocoa

  • Provides a comprehensive reactive programming framework
  • Supports functional reactive programming (FRP) paradigm
  • Offers a wide range of operators for composing and transforming streams

Cons of ReactiveCocoa

  • Steeper learning curve due to its complexity
  • Can lead to increased memory usage if not managed properly
  • May introduce unnecessary complexity for simple use cases

Code Comparison

KVOController:

[self.KVOController observe:object keyPath:@"property" options:NSKeyValueObservingOptionNew block:^(id observer, id object, NSDictionary *change) {
    NSLog(@"Property changed: %@", change[NSKeyValueChangeNewKey]);
}];

ReactiveCocoa:

[RACAble(object.property) subscribeNext:^(id x) {
    NSLog(@"Property changed: %@", x);
}];

ReactiveCocoa offers a more concise syntax for observing property changes and provides additional functionality for composing and transforming signals. However, KVOController is simpler and more focused on KVO specifically, making it easier to use for basic observation tasks.

24,358

Reactive Programming in Swift

Pros of RxSwift

  • Comprehensive reactive programming framework with a rich set of operators
  • Supports composing asynchronous and event-based programs
  • Large community and ecosystem with many extensions and libraries

Cons of RxSwift

  • Steeper learning curve due to its extensive API and concepts
  • Can lead to increased complexity for simple use cases
  • Potential performance overhead for heavy observing scenarios

Code Comparison

KVOController:

FBKVOController *observer = [FBKVOController controllerWithObserver:self];
[observer observe:object keyPath:@"property" options:NSKeyValueObservingOptionNew block:^(id observer, id object, NSDictionary *change) {
    NSLog(@"property changed: %@", change[NSKeyValueChangeNewKey]);
}];

RxSwift:

object.rx.observe(String.self, "property")
    .subscribe(onNext: { newValue in
        print("property changed: \(newValue)")
    })
    .disposed(by: disposeBag)

Summary

KVOController provides a simpler, more focused approach to Key-Value Observing, while RxSwift offers a comprehensive reactive programming framework. KVOController is easier to adopt for basic KVO use cases, whereas RxSwift provides powerful tools for complex asynchronous and event-driven programming but requires more investment to learn and implement effectively.

Performant animated GIF engine for iOS

Pros of FLAnimatedImage

  • Specialized for animated GIF rendering and performance optimization
  • Provides fine-grained control over GIF playback and memory usage
  • Offers a drop-in replacement for UIImageView with GIF support

Cons of FLAnimatedImage

  • Limited to GIF handling, while KVOController is a general-purpose tool
  • May have a steeper learning curve for basic GIF display tasks
  • Requires more setup for simple use cases compared to KVOController

Code Comparison

FLAnimatedImage:

FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:gifData];
FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];
imageView.animatedImage = image;

KVOController:

[self.KVOController observe:object keyPath:@"someProperty" options:NSKeyValueObservingOptionNew block:^(id observer, id object, NSDictionary *change) {
    NSLog(@"The value changed: %@", change[NSKeyValueChangeNewKey]);
}];

Summary

FLAnimatedImage is a specialized library for handling animated GIFs, offering optimized performance and fine-grained control. KVOController, on the other hand, is a general-purpose tool for Key-Value Observing. While FLAnimatedImage excels in GIF-related tasks, it's limited to that specific use case. KVOController provides a simpler API for observing property changes across various objects, making it more versatile but less specialized for specific tasks like GIF handling.

A delightful networking framework for iOS, macOS, watchOS, and tvOS.

Pros of AFNetworking

  • Comprehensive networking library with features for HTTP requests, security, and more
  • Well-maintained and widely adopted in the iOS development community
  • Extensive documentation and examples available

Cons of AFNetworking

  • Larger codebase and potential overhead for simpler networking tasks
  • May require more setup and configuration compared to KVOController
  • Not specifically designed for Key-Value Observing (KVO) functionality

Code Comparison

KVOController:

[self.KVOController observe:self.object keyPath:@"someProperty" options:NSKeyValueObservingOptionNew block:^(id observer, id object, NSDictionary *change) {
    NSLog(@"The value changed: %@", change[NSKeyValueChangeNewKey]);
}];

AFNetworking:

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager GET:@"https://api.example.com/data" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"Response: %@", responseObject);
} failure:nil];

Summary

While KVOController focuses on simplifying Key-Value Observing in iOS applications, AFNetworking is a more comprehensive networking library. KVOController offers a streamlined approach to KVO, while AFNetworking provides a wide range of networking capabilities. The choice between the two depends on the specific needs of your project, with KVOController being more suitable for KVO-specific tasks and AFNetworking for broader networking requirements.

11,320

Model framework for Cocoa and Cocoa Touch

Pros of Mantle

  • Provides a comprehensive model layer for Objective-C, including JSON serialization and deserialization
  • Offers powerful data transformation and validation capabilities
  • Supports complex object graphs and nested relationships

Cons of Mantle

  • Steeper learning curve due to its more extensive feature set
  • May introduce overhead for simpler use cases
  • Requires more setup and configuration compared to KVOController

Code Comparison

Mantle example:

@interface Person : MTLModel <MTLJSONSerializing>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end

@implementation Person
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
    return @{@"name": @"full_name", @"age": @"years_old"};
}
@end

KVOController example:

[self.KVOController observe:self.person
                    keyPath:@"name"
                    options:NSKeyValueObservingOptionNew
                      block:^(id observer, id object, NSDictionary *change) {
    NSLog(@"Name changed to: %@", change[NSKeyValueChangeNewKey]);
}];

While KVOController focuses on simplifying Key-Value Observing, Mantle provides a more comprehensive solution for model management and data transformation. KVOController is lighter and easier to implement for basic observation needs, while Mantle offers more powerful features at the cost of increased complexity.

MBProgressHUD + Customizations

Pros of MBProgressHUD

  • Focused on UI progress indicators, providing a ready-to-use solution for displaying loading states
  • Offers a variety of customizable HUD styles and animations
  • Lightweight and easy to integrate into iOS projects

Cons of MBProgressHUD

  • Limited to progress and loading indicators, not a general-purpose observation tool
  • May require additional setup for complex progress tracking scenarios
  • iOS-specific, not suitable for cross-platform development

Code Comparison

MBProgressHUD:

MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.mode = MBProgressHUDModeIndeterminate;
hud.label.text = @"Loading...";
[hud showAnimated:YES];

KVOController:

FBKVOController *kvoController = [FBKVOController controllerWithObserver:self];
[kvoController observe:object keyPath:@"someProperty" options:NSKeyValueObservingOptionNew block:^(id observer, id object, NSDictionary *change) {
    NSLog(@"Property changed: %@", change[NSKeyValueChangeNewKey]);
}];

Summary

MBProgressHUD is a specialized library for creating progress indicators in iOS apps, while KVOController is a more general-purpose tool for observing property changes. MBProgressHUD offers ready-made UI components but is limited to iOS, whereas KVOController provides a flexible observation mechanism that can be used in various scenarios across Apple platforms.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

KVOController

Build Status Coverage Status Version Platform

Key-value observing is a particularly useful technique for communicating between layers in a Model-View-Controller application. KVOController builds on Cocoa's time-tested key-value observing implementation. It offers a simple, modern API, that is also thread safe. Benefits include:

  • Notification using blocks, custom actions, or NSKeyValueObserving callback.
  • No exceptions on observer removal.
  • Implicit observer removal on controller dealloc.
  • Thread-safety with special guards against observer resurrection – rdar://15985376.

For more information on KVO, see Apple's Introduction to Key-Value Observing.

Usage

Example apps for iOS and OS X are included with the project. Here is one simple usage pattern:

// create KVO controller with observer
FBKVOController *KVOController = [FBKVOController controllerWithObserver:self];
self.KVOController = KVOController;

// observe clock date property
[self.KVOController observe:clock keyPath:@"date" options:NSKeyValueObservingOptionInitial|NSKeyValueObservingOptionNew block:^(ClockView *clockView, Clock *clock, NSDictionary *change) {

  // update clock view with new value
  clockView.date = change[NSKeyValueChangeNewKey];
}];

While simple, the above example is complete. A clock view creates a KVO controller to observe the clock date property. A block callback is used to handle initial and change notification. Unobservation happens implicitly on controller deallocation, since a strong reference to the KVOController is kept.

Note: the observer specified must support weak references. The zeroing weak reference guards against notification of a deallocated observer instance.

NSObject Category

For an even easier usage, just #import <KVOController/NSObject+FBKVOController.h> for an automatic KVOController property on all objects.

[self.KVOController observe:clock keyPath:@"date" options:NSKeyValueObservingOptionInitial|NSKeyValueObservingOptionNew action:@selector(updateClockWithDateChange:)];

Swift

KVOController works great in Swift but there are few requirements:

  • Your observer should subclass NSObject.
  • Properties that you observe must be marked as dynamic.

Check the following example:

class TasksListViewModel: NSObject {

  dynamic var tasksList: [TaskList] = []
}

/// In ViewController.swift

import KVOController

kvoController.observe(viewModel,
                      keyPath: "listsDidChange",
                      options: [.new, .initial]) { (viewController, viewModel, change) in
    
  self.taskListsTableView.reloadData()
}

Prerequisites

KVOController takes advantage of recent Objective-C runtime advances, including ARC and weak collections. It requires:

  • iOS 6 or later.
  • OS X 10.7 or later.

Installation

To install using CocoaPods, add the following to your project Podfile:

pod 'KVOController'

To install using Carthage, add the following to your project Cartfile:

github "facebook/KVOController"

Alternatively, drag and drop FBKVOController.h and FBKVOController.m into your Xcode project, agreeing to copy files if needed. For iOS applications, you can choose to link against the static library target of the KVOController project.

Having installed using CocoaPods or Carthage, add the following to import in Objective-C:

#import <KVOController/KVOController.h>

Testing

The unit tests included use CocoaPods for managing dependencies. Install CocoaPods if you haven't already done so. Then, at the command line, navigate to the root KVOController directory and type:

pod install

This will install and add test dependencies on OCHamcrest and OCMockito. Re-open the Xcode KVOController workspace and Test, ⌘U.

License

KVOController is released under a BSD License. See LICENSE file for details.