【问题标题】:Generic validation on input输入的通用验证
【发布时间】:2013-05-11 07:00:22
【问题描述】:

我想编写一个通用方法来验证所有 UIControls,如 NSTextField、NSTextView 等。如果任何必填字段为空,则应显示一个合并的警报,其中第一个控件作为焦点/第一响应者。

我已经实现了这样的东西:

-(NSInteger)lengthAfterTrimmingSpaces:(NSString *)string{
    return [[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length];
}


-(NSDictionary *)createWarningMessageForMandatoryFields:(NSArray *)uiObjects{

    NSMutableString *warningString=[NSMutableString stringWithString:@"Enter "];
    id firstInvalidatedControl=nil;

    for (NSDictionary *object in uiObjects) {
        NSString *key=[object allKeys][0];
        id control=object[key];
        if ([control isKindOfClass:[NSTextField class]]) {
            if ([self lengthAfterTrimmingSpaces:[control stringValue]]==0){
                [warningString appendString:key];
                [warningString appendString:@", "];

                if (firstInvalidatedControl==nil) {
                    firstInvalidatedControl=control;
                }
            }
        }
        else if ([control isKindOfClass:[NSTextView class]]) {
            if ([self lengthAfterTrimmingSpaces:[control string]]==0){
                [warningString appendString:key];
                [warningString appendString:@", "];
                if (firstInvalidatedControl==nil) {
                    firstInvalidatedControl=control;
                }
            }
        }
    }

    if (firstInvalidatedControl==nil) {
        return @{@"warningString":@"Success"};
    }
    else{

        warningString =[[warningString substringToIndex:[warningString length] - 2]mutableCopy];
        return @{@"warningString":warningString, @"control":firstInvalidatedControl};
    }
}


-(BOOL)validateMandatoryFields{
    NSMutableArray *uiObjects=[NSMutableArray array];

    [uiObjects addObject:@{@"Segment Name":self.segmentName}];
    [uiObjects addObject:@{@"Code":self.code}];
    [uiObjects addObject:@{@"Desciption":self.description}];

    NSDictionary *warningAndControl=[self createWarningMessageForMandatoryFields:uiObjects];
    if ([warningAndControl[@"warningString"] isEqualToString:@"Success"]) {
        return YES;
    }
    else{
        [[self window] makeFirstResponder:warningAndControl[@"control"]];
        NSRunAlertPanel(@"Warning", warningAndControl[@"warningString"], @"OK", nil, nil);
        return NO;
    }
}

- (IBAction)save:(id)sender {
    NSLog(@"%d",[self validateMandatoryFields]);
}

现在我想让它更加通用,因为我正在对每种类型进行类内省,然后检索值(stringValue/string 等)。

对此还有任何其他建议表示赞赏。

【问题讨论】:

  • 您要求的是普通程序员的任务。至少将appendString etc 块移动到单独的函数/方法。或者通过传递控制、所需类、字符串检索块/选择器、警告字符串、键和firstInvalidatedControl 作为参数来分隔整个isKindOfClass 级别。
  • 采用更多参数的单一方法,而不是更多方法。 [self processControl:control requiredClass:[NSTextField class] warningString:warningString key:key firstInvalidatedControl:& firstInvalidatedControl stringValueSelector:@selector(stringValue)]。或者,如果您不反对绑定,更好的方法可能是将控件绑定到 viewController 的属性并测试它们的属性(完全忘记控件)。

标签: objective-c macos cocoa


【解决方案1】:

将控件绑定到查看控制器的属性可能会有所帮助。

@interface MyViewController

@property(nonatomic,copy) NSString *string;
@property(nonatomic,copy) NSDate *date;
@property(nonatomic,copy) NSNumber *number;

@end

现在您将控件值绑定到文件所有者的 string / date / number 属性。

@implementation MyViewController

- (void)testForm
{
    for (NSString *key in @[@"string", @"date", @"number"]) {
        id value = [self valueForKey:key];
        if (value == nil || [value isEqual:@""] || [value isEqual:@(0.0)] || ...) {
            // empty field
        }
    }
}

请注意,您在此处使用真实数据,即如果您有日期/数字字段,则不会检查其 stringValue(即格式化程序的工作)的完整性,而是已转换/格式化的值。

【讨论】:

    【解决方案2】:

    您基于将呈现给用户的字符串内容的逻辑(判断是否存在错误)。你不应该。相反,将逻辑基于键 (control),因为它们是不可变的。与此一起,您应该使用NSLocalizedString 来验证代码以供将来重用。

    为了自省,我会考虑将这些方法放入一个实用程序类中,并将一些类别也添加到该类中。这些类别将向每个NSControl 子类添加一个方法,目的是让您通过始终调用具有相同名称的方法来获取它们的stringValue。对于NSTextField,您不需要类别。对于NSTextView,类别为:

    @implementation NSTextView (MyStringValue)
    
    - (NSString *)stringValue
    {
        return [self string];
    }
    
    @end
    

    您的代码仍应验证该类是否响应 stringValue 选择器,如果没有,则无法验证。

    【讨论】:

      猜你喜欢
      • 2018-11-22
      • 1970-01-01
      • 1970-01-01
      • 2014-03-25
      • 1970-01-01
      • 2019-10-17
      • 2017-09-11
      相关资源
      最近更新 更多