7

Una cosa con la que siempre he tenido problemas en Cocoa Bindings ha sido la presentación de errores, por ejemplo, cuando el usuario escribe el valor incorrecto en un campo de texto con un formateador adjunto. Normalmente anularía willPresentError: en algún lugar de la cadena de respuesta, pero mi problema es que los objetos NSError creados por el sistema de enlaces no contienen suficiente información para decirme qué falló, o si incluso es un error que me interesa personalizar. Podría eliminar por completo los enlaces de la ecuación y crear mis propios errores cuando se produzcan problemas de validación, pero creo que estaría tirando algunas cosas útiles de esa manera.¿Cómo puedo anular la presentación de NSError cuando se trata de enlaces?

He podido evitar esto implementando los métodos de delegado NSControl y almacenando el control que falló en una variable de instancia en mi controlador de vista. Si no es nulo en el momento en que willPresentError: rueda, sé lo que no pudo validar.

- (BOOL)control:(NSControl *)control didFailToFormatString:(NSString *)string errorDescription:(NSString *)error; 
{ 
    _errorSender = [control retain]; 
    return NO; 
} 

- (NSError *)willPresentError:(NSError *)error; 
{ 
    if (_errorSender != nil) 
    { 
     NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithDictionary:[error userInfo]]; 
     NSString *help = NSLocalizedString(@"Why are you always messing up? You are a terrible person.", @""); 

     [_errorSender release]; 
     _errorSender = nil; 
     [userInfo setObject:help forKey:NSLocalizedRecoverySuggestionErrorKey]; 

     return [NSError errorWithDomain:[error domain] code:[error code] userInfo:userInfo]; 
    } 

    return [super willPresentError:error]; 
} 

Esto funciona cuando los primeros cambios de respuesta, pero no cuando llamo commitEditing en el controlador de la vista, así que es sólo parcialmente útil para mí.

La única otra opción que puedo ver es sacar NSFormatter de la ecuación y usar validateValue:forKey:error: en mis objetos administrados Core Data para manejar la validación. Esto no tiene tanto sentido para mí como el uso de un formateador, pero al menos tendría el control total sobre el objeto NSError.

Siento que me falta algo para que haya este tipo de desconexión con el manejo de errores. ¿Alguna sugerencia?

Respuesta

4

I could completely remove bindings from the equation and create my own errors when validation problems occur, but I feel like I would be throwing out some useful stuff that way.

Puede utilizar NSUnderlyingErrorKey para envolver un error (el objeto de esa tecla) en otro error (el que tiene userInfo contiene esa tecla).

The only other option I can see is taking NSFormatter out of the equation, and using validateValue:forKey:error: in my Core Data managed objects to handle validation. This doesn't make as much sense to me as using a formatter, but at least I'd have full control over the NSError object.

Estos son dos niveles separados, y no son mutuamente excluyentes. La validación del formateador está en la capa de visualización; La validación del valor clave (en este caso, en sus objetos administrados) está en la capa del modelo.

Si la validación en cuestión debe realizarse en la capa de vista, subclase su clase NSFormatter (si no lo ha hecho) e implemente getObjectValue:forString:errorDescription: para devolver una descripción de error más específica. (No tengo ni idea de si Vinculaciones realmente utiliza esta descripción de error, sin embargo. Usted debe verificar.)

Si la validación debe suceder en la capa del modelo, aplicar validate<Key>:error: (la versión de una sola propiedad de validateValue:forKey:error:) en la subclase NSManagedObject.

Si algunas de las restricciones están en la capa del modelo y otras están en la capa de vista, haga ambas cosas. Puede implementar algunos controles en el formateador y otras comprobaciones en el modelo, si eso tiene sentido para su aplicación y sus cheques.

+1

Estoy subclases NSFormatter, y mientras que los enlaces utiliza el mensaje de error NSString, proporciono el NSAlert final es aún bastante básico (me gustaría añadir una sugerencia de recuperación al error, como mínimo). La validación que estoy haciendo parece ser más adecuada para mis subclases NSFormatter, por lo que dudo en implementar la validación de clave-valor en mi modelo. Terminaría haciendo todo tipo de análisis sintáctico de cadenas que no tiene nada que ver con el modelo de datos, solo para poder personalizar el mensaje de error de la interfaz de usuario cuando algo sale mal. –

Cuestiones relacionadas