• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Bindings validation for NSMutableArray of NSMutableDictionary
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bindings validation for NSMutableArray of NSMutableDictionary


  • Subject: Re: Bindings validation for NSMutableArray of NSMutableDictionary
  • From: Mike Abdullah <email@hidden>
  • Date: Fri, 14 Dec 2012 11:13:25 +0000

I'd strongly advise the OP it's better for them to create a custom class for their model objects, rather than go down this route of globally modifying NSMutableDictionary's API.

On 13 Dec 2012, at 22:18, email@hidden wrote:

> On 13 Dec 2012, at 11:54, email@hidden wrote:
>
>> I bind an NSArray of NSMutableDictionary instances to an NSTableView and enable NSTableColumn editing..
>>
>> How can I best implement KVO based validation when editing the view?
>>
>> Subclassing NSArray controller is a no go as validateValue:forKeyPath:error is never called.
>> Subclassing the NSMutableDictionary model obviously isn't desirable.
>>
>> I can refactor the NSMutableDictionary instances into custom objects and use model based validation if needed.
>>
>> However, binding dictionaries into table views is often convenient so a working validation strategy would be useful.
>>
>> Jonathan
>
> The following category enables NSMutableDictionary KVC validation routing to a delegate.
>
> NSMutableDictionary *connection = [self selectedConnection];
> connection.validationDelegate = self;
>
> The delegate then performs validation in:
>
> - (BOOL)validateValue:(id *)ioValue forKey:(NSString *)key error:(NSError **)outError sender:(NSMutableDictionary *)sender
>
> See https://github.com/mugginsoft/NSMutableDictionary-KVCValidation
>
> Simple refactoring would enable routing of KVC validation for any class.
>
> Jonathan
>
>
> #import "NSMutableDictionary+KVCValidation.h"
> #import <objc/runtime.h>
>
> const char validationDelegateKey;
>
> /*
>
> MethodSwizzle()
>
> ref: http://www.mikeash.com/pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html
>
> */
> void MethodSwizzle(Class klass, SEL origSEL, SEL overrideSEL)
> {
>    Method origMethod = class_getInstanceMethod(klass, origSEL);
>    Method overrideMethod = class_getInstanceMethod(klass, overrideSEL);
>
>    // try and add instance method with original selector that points to new implementation
>    if (class_addMethod(klass, origSEL, method_getImplementation(overrideMethod), method_getTypeEncoding(overrideMethod))) {
>
>        // add or replace method so that new selector points to original method
>        class_replaceMethod(klass, overrideSEL, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
>    } else {
>
>        // class already has an override method so just swap the implementations.
>        method_exchangeImplementations(origMethod, overrideMethod);
>    }
> }
>
> @implementation NSMutableDictionary (KVCValidation)
>
> /*
>
> + load
>
> */
> + (void)load
> {
>    MethodSwizzle(self, @selector(validateValue:forKey:error:), @selector(swizzle_validateValue:forKey:error:));
> }
>
> /*
>
> - setValidationDelegate:
>
> */
> - (void)setValidationDelegate:(id)validationDelegate
> {
>    objc_setAssociatedObject(self, &validationDelegateKey, validationDelegate, OBJC_ASSOCIATION_RETAIN);
> }
>
> /*
>
> - validationDelegate
>
> */
> - (id)validationDelegate
> {
>    return objc_getAssociatedObject(self, &validationDelegateKey);
> }
>
> /*
>
> - swizzle_validateValue:forKey:error:
>
> */
> - (BOOL)swizzle_validateValue:(id *)ioValue forKey:(NSString *)key error:(NSError **)outError
> {
>    id validationDelegate = self.validationDelegate;
>    SEL validationSelector = @selector(validateValue:forKey:error:sender:);
>    BOOL isValid = NO;
>
>    if ([validationDelegate respondsToSelector:validationSelector]) {
>        isValid = [validationDelegate validateValue:ioValue forKey:key error:outError sender:self];
>    } else {
>        // remember, we swap IMPS at run time
>        isValid = [self swizzle_validateValue:ioValue forKey:key error:outError];
>    }
>
>    return isValid;
> }
> @end
>
> Jonathan
>
>
> _______________________________________________
>
> Cocoa-dev mailing list (email@hidden)
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden


_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Follow-Ups:
    • Re: Bindings validation for NSMutableArray of NSMutableDictionary
      • From: "email@hidden" <email@hidden>
References: 
 >Bindings validation for NSMutableArray of NSMutableDictionary (From: "email@hidden" <email@hidden>)
 >Re: Bindings validation for NSMutableArray of NSMutableDictionary (From: "email@hidden" <email@hidden>)

  • Prev by Date: Re: What rect does NSTextFieldCell use to draw its contents?
  • Next by Date: Re: NSMutableData and Pinned Memory buffers..
  • Previous by thread: Re: Bindings validation for NSMutableArray of NSMutableDictionary
  • Next by thread: Re: Bindings validation for NSMutableArray of NSMutableDictionary
  • Index(es):
    • Date
    • Thread