Skip to content
Browse files

Added Error/Validation

  • Loading branch information...
1 parent 13077a1 commit 46200b1e42c33325ce9cd4ed1ebd2ebfff3429c4 @cneuwirt committed Feb 23, 2014
View
116 Miruken.xcodeproj/project.pbxproj
@@ -79,6 +79,30 @@
14982D7618B9252F0065EE40 /* UIScrollView+Motion.m in Sources */ = {isa = PBXBuildFile; fileRef = 14982D7418B9252F0065EE40 /* UIScrollView+Motion.m */; };
14982D7918B9257B0065EE40 /* UIWindow+Rotation.h in Headers */ = {isa = PBXBuildFile; fileRef = 14982D7718B9257B0065EE40 /* UIWindow+Rotation.h */; };
14982D7A18B9257B0065EE40 /* UIWindow+Rotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 14982D7818B9257B0065EE40 /* UIWindow+Rotation.m */; };
+ 14982D7D18B92A370065EE40 /* MKMasterDetail.h in Headers */ = {isa = PBXBuildFile; fileRef = 14982D7B18B92A370065EE40 /* MKMasterDetail.h */; };
+ 14982D7E18B92A370065EE40 /* MKViewRegion.h in Headers */ = {isa = PBXBuildFile; fileRef = 14982D7C18B92A370065EE40 /* MKViewRegion.h */; };
+ 14982D8B18B92BE70065EE40 /* MKCallbackHandler+Recoverable.h in Headers */ = {isa = PBXBuildFile; fileRef = 14982D8018B92BE70065EE40 /* MKCallbackHandler+Recoverable.h */; };
+ 14982D8C18B92BE70065EE40 /* MKCallbackHandler+Recoverable.m in Sources */ = {isa = PBXBuildFile; fileRef = 14982D8118B92BE70065EE40 /* MKCallbackHandler+Recoverable.m */; };
+ 14982D8D18B92BE70065EE40 /* MKEndContextOnError.h in Headers */ = {isa = PBXBuildFile; fileRef = 14982D8218B92BE70065EE40 /* MKEndContextOnError.h */; };
+ 14982D8E18B92BE70065EE40 /* MKEndContextOnError.m in Sources */ = {isa = PBXBuildFile; fileRef = 14982D8318B92BE70065EE40 /* MKEndContextOnError.m */; };
+ 14982D8F18B92BE70065EE40 /* MKErrorCallbackHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 14982D8418B92BE70065EE40 /* MKErrorCallbackHandler.h */; };
+ 14982D9018B92BE70065EE40 /* MKErrorCallbackHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 14982D8518B92BE70065EE40 /* MKErrorCallbackHandler.m */; };
+ 14982D9118B92BE70065EE40 /* MKErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = 14982D8618B92BE70065EE40 /* MKErrors.h */; };
+ 14982D9418B92BE70065EE40 /* MKWellKnownErrorResults.h in Headers */ = {isa = PBXBuildFile; fileRef = 14982D8918B92BE70065EE40 /* MKWellKnownErrorResults.h */; };
+ 14982D9518B92BE70065EE40 /* MKWellKnownErrorResults.m in Sources */ = {isa = PBXBuildFile; fileRef = 14982D8A18B92BE70065EE40 /* MKWellKnownErrorResults.m */; };
+ 14982D9818BA2D830065EE40 /* UIAlertView+Block.h in Headers */ = {isa = PBXBuildFile; fileRef = 14982D9618BA2D830065EE40 /* UIAlertView+Block.h */; };
+ 14982D9918BA2D830065EE40 /* UIAlertView+Block.m in Sources */ = {isa = PBXBuildFile; fileRef = 14982D9718BA2D830065EE40 /* UIAlertView+Block.m */; };
+ 14982DA818BA33AC0065EE40 /* NSError+MKValidation.h in Headers */ = {isa = PBXBuildFile; fileRef = 14982D9D18BA33AC0065EE40 /* NSError+MKValidation.h */; };
+ 14982DA918BA33AC0065EE40 /* NSError+MKValidation.m in Sources */ = {isa = PBXBuildFile; fileRef = 14982D9E18BA33AC0065EE40 /* NSError+MKValidation.m */; };
+ 14982DAA18BA33AC0065EE40 /* MKValidationResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 14982D9F18BA33AC0065EE40 /* MKValidationResult.h */; };
+ 14982DAB18BA33AC0065EE40 /* MKValidationResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 14982DA018BA33AC0065EE40 /* MKValidationResult.m */; };
+ 14982DAC18BA33AC0065EE40 /* MKValidateCallbackHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 14982DA118BA33AC0065EE40 /* MKValidateCallbackHandler.h */; };
+ 14982DAD18BA33AC0065EE40 /* MKValidateCallbackHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 14982DA218BA33AC0065EE40 /* MKValidateCallbackHandler.m */; };
+ 14982DAE18BA33AC0065EE40 /* MKValidationErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = 14982DA318BA33AC0065EE40 /* MKValidationErrors.h */; };
+ 14982DAF18BA33AC0065EE40 /* MKValidationErrors.m in Sources */ = {isa = PBXBuildFile; fileRef = 14982DA418BA33AC0065EE40 /* MKValidationErrors.m */; };
+ 14982DB018BA33AC0065EE40 /* MKValidationExtension.h in Headers */ = {isa = PBXBuildFile; fileRef = 14982DA518BA33AC0065EE40 /* MKValidationExtension.h */; };
+ 14982DB118BA33AC0065EE40 /* MKValidationExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 14982DA618BA33AC0065EE40 /* MKValidationExtension.m */; };
+ 14982DB218BA33AC0065EE40 /* MKValidate.h in Headers */ = {isa = PBXBuildFile; fileRef = 14982DA718BA33AC0065EE40 /* MKValidate.h */; };
14FD8A5618A7CB18008077CF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 14FD8A5518A7CB18008077CF /* Foundation.framework */; };
14FD8A5B18A7CB18008077CF /* Miruken.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 14FD8A5A18A7CB18008077CF /* Miruken.h */; };
14FD8A6418A7CB18008077CF /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 14FD8A6318A7CB18008077CF /* XCTest.framework */; };
@@ -271,6 +295,32 @@
14982D7418B9252F0065EE40 /* UIScrollView+Motion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIScrollView+Motion.m"; sourceTree = "<group>"; };
14982D7718B9257B0065EE40 /* UIWindow+Rotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIWindow+Rotation.h"; sourceTree = "<group>"; };
14982D7818B9257B0065EE40 /* UIWindow+Rotation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIWindow+Rotation.m"; sourceTree = "<group>"; };
+ 14982D7B18B92A370065EE40 /* MKMasterDetail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MKMasterDetail.h; sourceTree = "<group>"; };
+ 14982D7C18B92A370065EE40 /* MKViewRegion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MKViewRegion.h; sourceTree = "<group>"; };
+ 14982D8018B92BE70065EE40 /* MKCallbackHandler+Recoverable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MKCallbackHandler+Recoverable.h"; sourceTree = "<group>"; };
+ 14982D8118B92BE70065EE40 /* MKCallbackHandler+Recoverable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MKCallbackHandler+Recoverable.m"; sourceTree = "<group>"; };
+ 14982D8218B92BE70065EE40 /* MKEndContextOnError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MKEndContextOnError.h; sourceTree = "<group>"; };
+ 14982D8318B92BE70065EE40 /* MKEndContextOnError.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MKEndContextOnError.m; sourceTree = "<group>"; };
+ 14982D8418B92BE70065EE40 /* MKErrorCallbackHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MKErrorCallbackHandler.h; sourceTree = "<group>"; };
+ 14982D8518B92BE70065EE40 /* MKErrorCallbackHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MKErrorCallbackHandler.m; sourceTree = "<group>"; };
+ 14982D8618B92BE70065EE40 /* MKErrors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MKErrors.h; sourceTree = "<group>"; };
+ 14982D8918B92BE70065EE40 /* MKWellKnownErrorResults.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MKWellKnownErrorResults.h; sourceTree = "<group>"; };
+ 14982D8A18B92BE70065EE40 /* MKWellKnownErrorResults.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MKWellKnownErrorResults.m; sourceTree = "<group>"; };
+ 14982D9618BA2D830065EE40 /* UIAlertView+Block.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIAlertView+Block.h"; sourceTree = "<group>"; };
+ 14982D9718BA2D830065EE40 /* UIAlertView+Block.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIAlertView+Block.m"; sourceTree = "<group>"; };
+ 14982D9B18BA32C70065EE40 /* MKError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MKError.h; sourceTree = "<group>"; };
+ 14982D9D18BA33AC0065EE40 /* NSError+MKValidation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSError+MKValidation.h"; sourceTree = "<group>"; };
+ 14982D9E18BA33AC0065EE40 /* NSError+MKValidation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSError+MKValidation.m"; sourceTree = "<group>"; };
+ 14982D9F18BA33AC0065EE40 /* MKValidationResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MKValidationResult.h; sourceTree = "<group>"; };
+ 14982DA018BA33AC0065EE40 /* MKValidationResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MKValidationResult.m; sourceTree = "<group>"; };
+ 14982DA118BA33AC0065EE40 /* MKValidateCallbackHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MKValidateCallbackHandler.h; sourceTree = "<group>"; };
+ 14982DA218BA33AC0065EE40 /* MKValidateCallbackHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MKValidateCallbackHandler.m; sourceTree = "<group>"; };
+ 14982DA318BA33AC0065EE40 /* MKValidationErrors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MKValidationErrors.h; sourceTree = "<group>"; };
+ 14982DA418BA33AC0065EE40 /* MKValidationErrors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MKValidationErrors.m; sourceTree = "<group>"; };
+ 14982DA518BA33AC0065EE40 /* MKValidationExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MKValidationExtension.h; sourceTree = "<group>"; };
+ 14982DA618BA33AC0065EE40 /* MKValidationExtension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MKValidationExtension.m; sourceTree = "<group>"; };
+ 14982DA718BA33AC0065EE40 /* MKValidate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MKValidate.h; sourceTree = "<group>"; };
+ 14982DB318BA37B30065EE40 /* MKValidation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MKValidation.h; sourceTree = "<group>"; };
14FD8A5218A7CB18008077CF /* libMiruken.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMiruken.a; sourceTree = BUILT_PRODUCTS_DIR; };
14FD8A5518A7CB18008077CF /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
14FD8A5918A7CB18008077CF /* Miruken-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Miruken-Prefix.pch"; sourceTree = "<group>"; };
@@ -467,6 +517,8 @@
isa = PBXGroup;
children = (
14982D5518B807070065EE40 /* MirukenCocoa.h */,
+ 14982D7C18B92A370065EE40 /* MKViewRegion.h */,
+ 14982D7B18B92A370065EE40 /* MKMasterDetail.h */,
14982D5D18B9245E0065EE40 /* MKPagingMixin.h */,
14982D5E18B9245E0065EE40 /* MKPagingMixin.m */,
14982D5918B9245E0065EE40 /* MKAlertViewMixin.h */,
@@ -485,6 +537,8 @@
14982D6218B9245E0065EE40 /* UIViewController_RotationMixin.m */,
14982D5F18B9245E0065EE40 /* UINavigationController_RotationMixin.h */,
14982D6018B9245E0065EE40 /* UINavigationController_RotationMixin.m */,
+ 14982D9618BA2D830065EE40 /* UIAlertView+Block.h */,
+ 14982D9718BA2D830065EE40 /* UIAlertView+Block.m */,
14982D7318B9252F0065EE40 /* UIScrollView+Motion.h */,
14982D7418B9252F0065EE40 /* UIScrollView+Motion.m */,
14982D7718B9257B0065EE40 /* UIWindow+Rotation.h */,
@@ -505,6 +559,42 @@
path = Context;
sourceTree = "<group>";
};
+ 14982D7F18B92ACD0065EE40 /* Error */ = {
+ isa = PBXGroup;
+ children = (
+ 14982D9B18BA32C70065EE40 /* MKError.h */,
+ 14982D8618B92BE70065EE40 /* MKErrors.h */,
+ 14982D8918B92BE70065EE40 /* MKWellKnownErrorResults.h */,
+ 14982D8A18B92BE70065EE40 /* MKWellKnownErrorResults.m */,
+ 14982D8418B92BE70065EE40 /* MKErrorCallbackHandler.h */,
+ 14982D8518B92BE70065EE40 /* MKErrorCallbackHandler.m */,
+ 14982D8018B92BE70065EE40 /* MKCallbackHandler+Recoverable.h */,
+ 14982D8118B92BE70065EE40 /* MKCallbackHandler+Recoverable.m */,
+ 14982D8218B92BE70065EE40 /* MKEndContextOnError.h */,
+ 14982D8318B92BE70065EE40 /* MKEndContextOnError.m */,
+ );
+ path = Error;
+ sourceTree = "<group>";
+ };
+ 14982D9C18BA336D0065EE40 /* Validation */ = {
+ isa = PBXGroup;
+ children = (
+ 14982DB318BA37B30065EE40 /* MKValidation.h */,
+ 14982DA718BA33AC0065EE40 /* MKValidate.h */,
+ 14982D9F18BA33AC0065EE40 /* MKValidationResult.h */,
+ 14982DA018BA33AC0065EE40 /* MKValidationResult.m */,
+ 14982DA118BA33AC0065EE40 /* MKValidateCallbackHandler.h */,
+ 14982DA218BA33AC0065EE40 /* MKValidateCallbackHandler.m */,
+ 14982DA318BA33AC0065EE40 /* MKValidationErrors.h */,
+ 14982DA418BA33AC0065EE40 /* MKValidationErrors.m */,
+ 14982DA518BA33AC0065EE40 /* MKValidationExtension.h */,
+ 14982DA618BA33AC0065EE40 /* MKValidationExtension.m */,
+ 14982D9D18BA33AC0065EE40 /* NSError+MKValidation.h */,
+ 14982D9E18BA33AC0065EE40 /* NSError+MKValidation.m */,
+ );
+ path = Validation;
+ sourceTree = "<group>";
+ };
14FD8A4918A7CB18008077CF = {
isa = PBXGroup;
children = (
@@ -545,6 +635,8 @@
14982D1818B16C8E0065EE40 /* Context */,
1462993418B02DCD002BCBF6 /* Callbacks */,
14FD8A7B18A7DBF7008077CF /* Concurrency */,
+ 14982D7F18B92ACD0065EE40 /* Error */,
+ 14982D9C18BA336D0065EE40 /* Validation */,
14FD8A5818A7CB18008077CF /* Supporting Files */,
);
path = Miruken;
@@ -672,12 +764,26 @@
14982D6918B9245E0065EE40 /* MKEndContextWhenAppResignsMixin.h in Headers */,
14982D7118B9245E0065EE40 /* MKUserInteractionMixin.h in Headers */,
14982D6718B9245E0065EE40 /* MKAlertViewMixin.h in Headers */,
+ 14982D9418B92BE70065EE40 /* MKWellKnownErrorResults.h in Headers */,
+ 14982D8B18B92BE70065EE40 /* MKCallbackHandler+Recoverable.h in Headers */,
+ 14982DAE18BA33AC0065EE40 /* MKValidationErrors.h in Headers */,
14982D6F18B9245E0065EE40 /* UIViewController_RotationMixin.h in Headers */,
+ 14982D8F18B92BE70065EE40 /* MKErrorCallbackHandler.h in Headers */,
+ 14982D9818BA2D830065EE40 /* UIAlertView+Block.h in Headers */,
14982D7918B9257B0065EE40 /* UIWindow+Rotation.h in Headers */,
+ 14982D7E18B92A370065EE40 /* MKViewRegion.h in Headers */,
+ 14982D9118B92BE70065EE40 /* MKErrors.h in Headers */,
+ 14982D8D18B92BE70065EE40 /* MKEndContextOnError.h in Headers */,
14982D7518B9252F0065EE40 /* UIScrollView+Motion.h in Headers */,
14982D6B18B9245E0065EE40 /* MKPagingMixin.h in Headers */,
14982D6D18B9245E0065EE40 /* UINavigationController_RotationMixin.h in Headers */,
14982D6518B9245E0065EE40 /* MKActionSheetMixin.h in Headers */,
+ 14982DB018BA33AC0065EE40 /* MKValidationExtension.h in Headers */,
+ 14982D7D18B92A370065EE40 /* MKMasterDetail.h in Headers */,
+ 14982DAA18BA33AC0065EE40 /* MKValidationResult.h in Headers */,
+ 14982DA818BA33AC0065EE40 /* NSError+MKValidation.h in Headers */,
+ 14982DAC18BA33AC0065EE40 /* MKValidateCallbackHandler.h in Headers */,
+ 14982DB218BA33AC0065EE40 /* MKValidate.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -798,6 +904,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 14982DA918BA33AC0065EE40 /* NSError+MKValidation.m in Sources */,
14982D1418B11D100065EE40 /* MKTraversal.m in Sources */,
1462997A18B02DCD002BCBF6 /* MKHandleMethod.m in Sources */,
14FD8AA918A7DBF7008077CF /* MKAsyncProxyResult.m in Sources */,
@@ -808,6 +915,8 @@
1462997D18B02DCD002BCBF6 /* NSObject+NotHandled.m in Sources */,
1462997418B02DCD002BCBF6 /* MKCascadeCallbackHandler.m in Sources */,
14982D6618B9245E0065EE40 /* MKActionSheetMixin.m in Sources */,
+ 14982D9518B92BE70065EE40 /* MKWellKnownErrorResults.m in Sources */,
+ 14982DAF18BA33AC0065EE40 /* MKValidationErrors.m in Sources */,
14982D2A18B16C8E0065EE40 /* MKContextualHelper.m in Sources */,
14982D6E18B9245E0065EE40 /* UINavigationController_RotationMixin.m in Sources */,
14982D2818B16C8E0065EE40 /* MKContextObserver.m in Sources */,
@@ -817,17 +926,21 @@
14FD8AAD18A7DBF7008077CF /* MKDeferred.m in Sources */,
14FD8AAA18A7DBF7008077CF /* MKAsyncResult.m in Sources */,
1462996C18B02DCD002BCBF6 /* MKCallbackHandler+Invocation.m in Sources */,
+ 14982D9018B92BE70065EE40 /* MKErrorCallbackHandler.m in Sources */,
14982D2D18B16DF20065EE40 /* MKWeakCell.m in Sources */,
14FD8AA618A7DBF7008077CF /* MKAction.m in Sources */,
14982D2618B16C8E0065EE40 /* MKContext+Traversal.m in Sources */,
14FD8AB218A7DBF7008077CF /* MKOperationProxyResult.m in Sources */,
1462996B18B02DCD002BCBF6 /* MKCallbackHandler+Buffer.m in Sources */,
14982D7018B9245E0065EE40 /* UIViewController_RotationMixin.m in Sources */,
14FD8AB018A7DBF7008077CF /* MKMainThreadDelegate.m in Sources */,
+ 14982D9918BA2D830065EE40 /* UIAlertView+Block.m in Sources */,
1462997B18B02DCD002BCBF6 /* MKInvocationCallbackHandler.m in Sources */,
14982D2918B16C8E0065EE40 /* MKContextual.m in Sources */,
1462997318B02DCD002BCBF6 /* MKCallbackHandlerFilter.m in Sources */,
+ 14982D8E18B92BE70065EE40 /* MKEndContextOnError.m in Sources */,
14982D7618B9252F0065EE40 /* UIScrollView+Motion.m in Sources */,
+ 14982DB118BA33AC0065EE40 /* MKValidationExtension.m in Sources */,
14982D5418B8025C0065EE40 /* MKCallbackHandler+Context.m in Sources */,
1462997918B02DCD002BCBF6 /* MKDynamicCallbackHandlerExtension.m in Sources */,
14FD8AA718A7DBF7008077CF /* MKAsyncDelegate.m in Sources */,
@@ -837,6 +950,7 @@
1462997818B02DCD002BCBF6 /* MKDynamicCallbackHandler+HandleMethod.m in Sources */,
14982D6C18B9245E0065EE40 /* MKPagingMixin.m in Sources */,
14982D3B18B1763C0065EE40 /* UIViewController_ContextualMixin.m in Sources */,
+ 14982DAD18BA33AC0065EE40 /* MKValidateCallbackHandler.m in Sources */,
1462998818B02EEA002BCBF6 /* MKReadWriteLock.m in Sources */,
14982D6818B9245E0065EE40 /* MKAlertViewMixin.m in Sources */,
14982D4A18B181980065EE40 /* MKCallbackHandler+Track.m in Sources */,
@@ -855,12 +969,14 @@
1462996E18B02DCD002BCBF6 /* MKCallbackHandler+Resolvers.m in Sources */,
14982D7A18B9257B0065EE40 /* UIWindow+Rotation.m in Sources */,
14FD8AB318A7DBF7008077CF /* MKOperationQueueDelegate.m in Sources */,
+ 14982D8C18B92BE70065EE40 /* MKCallbackHandler+Recoverable.m in Sources */,
14FD8AB518A7DBF7008077CF /* MKScheduledPromise.m in Sources */,
1462997618B02DCD002BCBF6 /* MKConditionCallbackHandler.m in Sources */,
14FD8AB118A7DBF7008077CF /* MKNewThreadDelegate.m in Sources */,
14982D2718B16C8E0065EE40 /* MKContext.m in Sources */,
14FD8AAB18A7DBF7008077CF /* MKBufferedPromise.m in Sources */,
1462997F18B02DCD002BCBF6 /* MKObjectCallbackReceiver.m in Sources */,
+ 14982DAB18BA33AC0065EE40 /* MKValidationResult.m in Sources */,
14982CF518B10E430065EE40 /* NSObject+ResolvePromise.m in Sources */,
1462997018B02DCD002BCBF6 /* MKCallbackHandler+Subscripting.m in Sources */,
1462998218B02DCD002BCBF6 /* MKProtocolCallbackReceiver.m in Sources */,
View
51 Miruken/Cocoa/MKMasterDetail.h
@@ -0,0 +1,51 @@
+//
+// MasterDetail.h
+// Miruken
+//
+// Created by Venkat Palivela on 3/27/13.
+// Copyright (c) 2013 Craig Neuwirt. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@protocol MKMasterDetail <NSObject>
+
+@optional
+- (id<Promise>)selectedDetail:(Class)detailClass;
+
+- (id<Promise>)selectedDetails:(Class)detailClass;
+
+- (void)selectDetail:(id)selectedDetail;
+
+- (void)deselectDetail:(id)selectedDetail;
+
+- (BOOL)hasPreviousDetail:(Class)detailClass;
+
+- (BOOL)hasNextDetail:(Class)detailClass;
+
+- (id<Promise>)previousDetail:(Class)detailClass;
+
+- (id<Promise>)nextDetail:(Class)detailClass;
+
+- (id<Promise>)addDetail:(id)detail;
+
+- (id<Promise>)removeDetail:(id)detail delete:(BOOL)delete;
+
+@end
+
+#define MKMasterDetail(handler) ((id<MKMasterDetail>)(handler))
+
+@protocol MKMasterDetailAware <NSObject>
+
+@optional
+- (void)masterChanged;
+
+- (void)didSelectDetail:(id)detail;
+
+- (void)didDeselectDetail:(id)detail;
+
+- (void)didRemoveDetail:(id)detail;
+
+@end
+
+#define MKMasterDetailAware(handler) ((id<MKMasterDetailAware>)(handler))
View
26 Miruken/Cocoa/MKViewRegion.h
@@ -0,0 +1,26 @@
+//
+// ViewRegion.h
+// Miruken
+//
+// Created by Craig Neuwirt on 2/27/13.
+// Copyright (c) 2013 Craig Neuwirt. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+/**
+ This protocol represents a region on the screen where a view controller can
+ be rendered. It enables compositional view controllers.
+ */
+
+@protocol MKViewRegion <NSObject>
+
+@optional
+- (void)presentViewController:(UIViewController *)viewControllerToPresent;
+
+- (void)presentNextViewController:(UIViewController *)viewControllerToPresent;
+
+@end
+
+#define MKViewRegion(handler) ((id<MKViewRegion>)(handler))
+#define MKViewRegionHint(region,handler) (region ? region : MKViewRegion(handler))
View
13 Miruken/Cocoa/MirukenCocoa.h
@@ -6,5 +6,16 @@
// Copyright (c) 2014 Craig Neuwirt. All rights reserved.
//
+#import "MKViewRegion.h"
+#import "MKMasterDetail.h"
+#import "MKPagingMixin.h"
+#import "MKAlertViewMixin.h"
+#import "MKActionSheetMixin.h"
+#import "MKUserInteractionMixin.h"
+#import "MKEndContextWhenAppResignsMixin.h"
#import "UIViewController_ContextualMixin.h"
-#import "UINavigationController_ContextualMixin.h"
+#import "UINavigationController_ContextualMixin.h"
+#import "UIViewController_RotationMixin.h"
+#import "UINavigationController_RotationMixin.h"
+#import "UIScrollView+Motion.h"
+#import "UIWindow+Rotation.h"
View
17 Miruken/Cocoa/UIAlertView+Block.h
@@ -0,0 +1,17 @@
+//
+// UIAlertView+Action.h
+// Miruken
+//
+// Created by Craig Neuwirt on 2/11/13.
+// Copyright (c) 2013 Craig Neuwirt. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef void (^MKAlertViewBlock)(NSInteger buttonIndex);
+
+@interface UIAlertView (UIAlertView_Block)
+
+- (void)showUsingBlock:(MKAlertViewBlock)block;
+
+@end
View
55 Miruken/Cocoa/UIAlertView+Block.m
@@ -0,0 +1,55 @@
+//
+// UIAlertView+Block.m
+// Miruken
+//
+// Created by Craig Neuwirt on 2/11/13.
+// Copyright (c) 2013 Craig Neuwirt. All rights reserved.
+//
+
+#import "UIAlertView+Block.h"
+
+@interface MKAlertViewDelegate : NSObject<UIAlertViewDelegate>
+
+@property (strong, atomic) MKAlertViewBlock block;
+
++ (void)show:(UIAlertView *)alertView withBlock:(MKAlertViewBlock)block;
+
+@end
+
+
+@implementation UIAlertView (UIAlertView_Block)
+
+- (void)showUsingBlock:(MKAlertViewBlock)block
+{
+ [MKAlertViewDelegate show:self withBlock:block];
+}
+
+@end
+
+
+@implementation MKAlertViewDelegate
+
++ (void)show:(UIAlertView *)alertView withBlock:(MKAlertViewBlock)block
+{
+ __block MKAlertViewDelegate *delegate = [MKAlertViewDelegate new];
+
+ alertView.delegate = delegate;
+ delegate.block = ^(NSInteger buttonIndex) {
+ alertView.delegate = nil;
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Warc-retain-cycles"
+ delegate = nil;
+#pragma clang diagnostic pop
+ };
+
+ [alertView show];
+}
+
+- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
+{
+ if (_block)
+ _block(buttonIndex);
+}
+
+@end
View
17 Miruken/Error/MKCallbackHandler+Recoverable.h
@@ -0,0 +1,17 @@
+//
+// MKCallbackHandler+Recoverable.h
+// Miruken
+//
+// Created by Craig Neuwirt on 11/30/12.
+// Copyright (c) 2012 Craig Neuwirt. All rights reserved.
+//
+
+#import "MKCallbackHandler.h"
+
+@interface MKCallbackHandler (MKCallbackHandler_Recoverable)
+
+- (instancetype)recoverable;
+
+- (instancetype)recoverableInContext:(void *)context;
+
+@end
View
50 Miruken/Error/MKCallbackHandler+Recoverable.m
@@ -0,0 +1,50 @@
+//
+// MKCallbackHandler+Recoverable.m
+// Miruken
+//
+// Created by Craig Neuwirt on 11/30/12.
+// Copyright (c) 2012 Craig Neuwirt. All rights reserved.
+//
+
+#import "MKCallbackHandler+Recoverable.h"
+#import "MKCallbackHandlerFilter.h"
+#import "NSObject+ResolvePromise.h"
+#import "MKErrors.h"
+
+@implementation MKCallbackHandler (MKCallbackHandler_Recoverable)
+
+- (instancetype)recoverable
+{
+ return [self recoverableInContext:NULL];
+}
+
+- (instancetype)recoverableInContext:(void *)context
+{
+ return [MKCallbackHandlerFilter for:self
+ filter:^(id callback, id<MKCallbackHandler> composer, BOOL(^proceed)()) {
+ id<MKPromise> promise = nil;
+ @try {
+ BOOL handled = proceed();
+ if (handled && (promise = [callback effectivePromise]))
+ {
+ __block id failureReason = nil;
+ __block BOOL *failureHandled = nil;
+ [[promise fail:^(id reason, BOOL *handled) {
+ failureReason = reason;
+ failureHandled = handled;
+ }]
+ always:^{
+ if (failureHandled != nil && *failureHandled == NO)
+ [MKErrors(composer) handleFailure:failureReason context:context];
+ failureReason = nil;
+ }];
+ }
+ return handled;
+ }
+ @catch (id exception) {
+ [MKErrors(composer) handleFailure:exception context:context];
+ }
+ }];
+}
+
+@end
View
19 Miruken/Error/MKEndContextOnError.h
@@ -0,0 +1,19 @@
+//
+// MKEndContextOnError.h
+// Miruken
+//
+// Created by Craig Neuwirt on 9/3/13.
+// Copyright (c) 2013 Craig Neuwirt. All rights reserved.
+//
+
+#import "MKErrors.h"
+#import "MKContextual.h"
+
+@interface MKEndContextOnError : NSObject <MKErrors, MKContextual>
+@end
+
+@interface MKContext (MKContext_EndContextOnError)
+
+- (MKContext *)endContextOnError;
+
+@end
View
53 Miruken/Error/MKEndContextOnError.m
@@ -0,0 +1,53 @@
+//
+// MKEndContextOnError.m
+// Miruken
+//
+// Created by Craig Neuwirt on 9/3/13.
+// Copyright (c) 2013 Craig Neuwirt. All rights reserved.
+//
+
+#import "MKEndContextOnError.h"
+#import "MKContext+Subscribe.h"
+#import "UIAlertView+Block.h"
+#import "MKDeferred.h"
+#import "MKMixin.h"
+
+@implementation MKEndContextOnError
+
++ (void)initialize
+{
+ if (self == MKEndContextOnError.class)
+ [MKEndContextOnError mixinFrom:MKContextualMixin.class];
+}
+
+- (id<MKPromise>)reportError:(NSError *)error message:(NSString *)message
+ title:(NSString *)title context:(void *)context
+{
+ MKDeferred *deferred = [MKDeferred new];
+
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:message
+ delegate:self cancelButtonTitle:@"Continue"
+ otherButtonTitles:nil];
+
+ [alert showUsingBlock:^(NSInteger buttonIndex) {
+ [self endContext];
+ [deferred resolve:nil];
+ }];
+
+ return [deferred promise];
+}
+
+@end
+
+@implementation MKContext (MKCallbackHandler_EndContextOnError)
+
+- (MKContext *)endContextOnError
+{
+ __block MKEndContextOnError *end = [[MKEndContextOnError allocInContext:self] init];
+ [end.context subscribeDidEnd:^(id<MKContext> context) {
+ end = nil; // keeps refresh alive until context ends
+ }];
+ return end.context;
+}
+
+@end
View
12 Miruken/Error/MKError.h
@@ -0,0 +1,12 @@
+//
+// MKError.h
+// Miruken
+//
+// Created by Craig Neuwirt on 2/23/14.
+// Copyright (c) 2014 Craig Neuwirt. All rights reserved.
+//
+
+#import "MKErrors.h"
+#import "MKCallbackHandler+Recoverable.h"
+#import "MKEndContextOnError.h"
+#import "MKWellKnownErrorResults.h"
View
14 Miruken/Error/MKErrorCallbackHandler.h
@@ -0,0 +1,14 @@
+//
+// ErrorCallbackHandler.h
+// Miruken
+//
+// Created by Craig Neuwirt on 11/16/12.
+// Copyright (c) 2012 Craig Neuwirt. All rights reserved.
+//
+
+#import "MKErrors.h"
+#import "MKDynamicCallbackHandler.h"
+
+@interface MKErrorCallbackHandler : MKDynamicCallbackHandler <MKErrors>
+
+@end
View
107 Miruken/Error/MKErrorCallbackHandler.m
@@ -0,0 +1,107 @@
+
+//
+// ErrorCallbackHandler.m
+// Miruken
+//
+// Created by Craig Neuwirt on 11/16/12.
+// Copyright (c) 2012 Craig Neuwirt. All rights reserved.
+//
+
+#import "MKErrorCallbackHandler.h"
+#import "MKContextual.h"
+#import "MKDeferred.h"
+#import "UIAlertView+Block.h"
+#import "MKAlertViewMixin.h"
+
+@interface MKErrorCallbackHandler() <MKAlertViewDelegate>
+@end
+
+@implementation MKErrorCallbackHandler
+{
+ BOOL _alertingError;
+}
+
+@synthesize alertView = _alertView;
+
++ (void)initialize
+{
+ if (self == MKErrorCallbackHandler.class)
+ [MKAlertViewMixin mixInto:self];
+}
+
+- (id<MKPromise>)handleFailure:(id)reason context:(void *)context
+{
+ if (reason != nil)
+ {
+ if ([reason isKindOfClass:NSError.class])
+ return [MKErrors(self.composer) handleError:reason context:context];
+
+ if ([reason isKindOfClass:NSException.class])
+ return [MKErrors(self.composer) handleException:reason context:context];
+ }
+ return [[MKDeferred resolved] promise];
+}
+
+- (id<MKPromise>)handleError:(NSError *)error context:(void *)context
+{
+ NSString *title = @"Error";
+ NSString *message = @"An unspecified error has occurred.";
+
+ return [MKErrors(self.composer) reportError:error message:message
+ title:title context:context];
+}
+
+- (id<MKPromise>)handleException:(NSException *)exception context:(void *)context
+{
+ return [MKErrors(self.composer) reportException:exception context:context];
+}
+
+
+- (id<MKPromise>)reportError:(NSError *)error message:(NSString *)message
+ title:(NSString *)title context:(void *)context
+{
+ MKDeferred *deferred = [MKDeferred new];
+
+ if (_alertingError)
+ return [[deferred resolve:[MKWellKnownErrorResults errorInProgress]] promise];
+
+ _alertView = [[UIAlertView alloc] initWithTitle:title
+ message:message
+ delegate:self
+ cancelButtonTitle:@"Continue"
+ otherButtonTitles:nil];
+
+ [_alertView showUsingBlock:^(NSInteger buttonIndex) {
+ _alertingError = NO;
+ [deferred resolve:[MKWellKnownErrorResults continue]];
+ _alertView = nil;
+ }];
+
+ _alertingError = YES;
+
+ return [deferred promise];
+}
+
+- (id<MKPromise>)reportException:(NSException *)exception context:(void *)context
+{
+ MKDeferred *deferred = [MKDeferred new];
+
+ if (_alertingError)
+ return [[deferred resolve:[MKWellKnownErrorResults errorInProgress]] promise];
+
+ _alertView = [[UIAlertView alloc] initWithTitle:exception.name
+ message:exception.reason delegate:self
+ cancelButtonTitle:@"Continue" otherButtonTitles:nil];
+
+ [_alertView showUsingBlock:^(NSInteger buttonIndex) {
+ _alertingError = NO;
+ [deferred resolve:[MKWellKnownErrorResults continue]];
+ _alertView = nil;
+ }];
+
+ _alertingError = YES;
+
+ return [deferred promise];
+}
+
+@end
View
29 Miruken/Error/MKErrors.h
@@ -0,0 +1,29 @@
+//
+// MKErrors.h
+// Miruken
+//
+// Created by Craig Neuwirt on 11/15/12.
+// Copyright (c) 2012 Craig Neuwirt. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "MKWellKnownErrorResults.h"
+#import "MKPromise.h"
+
+@protocol MKErrors
+
+@optional
+- (id<MKPromise>)handleFailure:(id)reason context:(void *)context;
+
+- (id<MKPromise>)handleError:(NSError *)error context:(void *)context;
+
+- (id<MKPromise>)handleException:(NSException *)exception context:(void *)context;
+
+- (id<MKPromise>)reportError:(NSError *)error message:(NSString *)message
+ title:(NSString *)title context:(void *)context;
+
+- (id<MKPromise>)reportException:(NSException *)exception context:(void *)context;
+
+@end
+
+#define MKErrors(handler) ((id<MKErrors>)(handler))
View
19 Miruken/Error/MKWellKnownErrorResults.h
@@ -0,0 +1,19 @@
+//
+// MKWellKnownErrorResults.h
+// Miruken
+//
+// Created by Craig Neuwirt on 2/11/13.
+// Copyright (c) 2013 Craig Neuwirt. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface MKWellKnownErrorResults : NSObject
+
++ (id)continue;
+
++ (id)retry;
+
++ (id)errorInProgress;
+
+@end
View
40 Miruken/Error/MKWellKnownErrorResults.m
@@ -0,0 +1,40 @@
+//
+// MKWellKnownErrorResults.m
+// Miruken
+//
+// Created by Craig Neuwirt on 2/11/13.
+// Copyright (c) 2013 Craig Neuwirt. All rights reserved.
+//
+
+#import "MKWellKnownErrorResults.h"
+
+static id _continue, _retry, _errorInProgress;
+
+@implementation MKWellKnownErrorResults
+
++ (void)initialize
+{
+ if (self == MKWellKnownErrorResults.class)
+ {
+ _continue = [NSObject alloc];
+ _retry = [NSObject alloc];
+ _errorInProgress = [NSObject alloc];
+ }
+}
+
++ (id)continue
+{
+ return _continue;
+}
+
++ (id)retry
+{
+ return _retry;
+}
+
++ (id)errorInProgress
+{
+ return _errorInProgress;
+}
+
+@end
View
4 Miruken/Miruken.h
@@ -18,4 +18,6 @@
#import "MirukenCallbacks.h"
#import "MirukenConcurrency.h"
#import "MirukenContext.h"
-#import "MirukenCocoa.h"
+#import "MirukenCocoa.h"
+#import "MKError.h"
+#import "MKValidation.h"
View
22 Miruken/Validation/MKValidate.h
@@ -0,0 +1,22 @@
+//
+// MKValidate.h
+// Miruken
+//
+// Created by Craig Neuwirt on 2/4/13.
+// Copyright (c) 2013 ZixCorp. All rights reserved.
+//
+
+#import "MKValidationResult.h"
+#import "MKValidationErrors.h"
+
+@protocol MKValidate
+
+@optional
+- (BOOL)validateObject:(id)object scope:(NSString *)scope;
+
+- (BOOL)validateObject:(id)object scope:(NSString *)scope
+ result:(MKValidationResult * __autoreleasing *)result;
+
+@end
+
+#define MKValidate(handler) ((id<MKValidate>)(handler))
View
14 Miruken/Validation/MKValidateCallbackHandler.h
@@ -0,0 +1,14 @@
+//
+// ValidationCallbackHandler.h
+// Miruken
+//
+// Created by Craig Neuwirt on 2/4/13.
+// Copyright (c) 2013 ZixCorp. All rights reserved.
+//
+
+#import "MKDynamicCallbackHandler.h"
+#import "MKValidate.h"
+
+@interface MKValidateCallbackHandler : MKDynamicCallbackHandler <MKValidate>
+
+@end
View
40 Miruken/Validation/MKValidateCallbackHandler.m
@@ -0,0 +1,40 @@
+//
+// ValidationCallbackHandler.m
+// Miruken
+//
+// Created by Craig Neuwirt on 2/4/13.
+// Copyright (c) 2013 ZixCorp. All rights reserved.
+//
+
+#import "MKValidateCallbackHandler.h"
+#import "MKValidationExtension.h"
+#import "MKContextual.h"
+
+@implementation MKValidateCallbackHandler
+
++ (void)initialize
+{
+ if (self == MKValidateCallbackHandler.class)
+ [MKValidationExtension install];
+}
+
+- (BOOL)validateObject:(id)object scope:(NSString *)scope
+{
+ MKValidationResult *validation;
+ return [self validateObject:object scope:scope result:&validation];
+}
+
+- (BOOL)validateObject:(id)object scope:(NSString *)scope
+ result:(MKValidationResult *__autoreleasing *)result
+{
+ MKValidationResult *validation = [MKValidationResult validateObject:object inScope:scope];
+ if ([self.composer handle:validation])
+ {
+ if (result)
+ *result = validation;
+ return validation.isValid;
+ }
+ return YES;
+}
+
+@end
View
12 Miruken/Validation/MKValidation.h
@@ -0,0 +1,12 @@
+//
+// MKValidation.h
+// Miruken
+//
+// Created by Craig Neuwirt on 2/23/14.
+// Copyright (c) 2014 Craig Neuwirt. All rights reserved.
+//
+
+#import "MKValidate.h"
+#import "MKValidationResult.h"
+#import "MKValidationErrors.h"
+#import "NSError+MKValidation.h"
View
30 Miruken/Validation/MKValidationErrors.h
@@ -0,0 +1,30 @@
+//
+// MKValidationErrors.h
+// Miruken
+//
+// Created by Craig Neuwirt on 2/4/13.
+// Copyright (c) 2013 ZixCorp. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "NSError+MKValidation.h"
+
+/**
+ Error domain used to identify validation errors.
+ */
+extern NSString * const MKValidationErrorDomain;
+
+/**
+ NSError userInfo key containing the keypath of the validation error.
+ */
+extern NSString * const MKValidationErrorKeyPathUserInfoKey;
+
+/**
+ NSError userInfo key containing the source of the validation error.
+ */
+extern NSString * const MKValidationErrorSourceUserInfoKey;
+
+typedef NS_ENUM(NSUInteger, ValidationErrors) {
+ MKValidationErrorEmpty = 3000,
+ MKValidationErrorInvalidEmailAddress
+};
View
15 Miruken/Validation/MKValidationErrors.m
@@ -0,0 +1,15 @@
+//
+// MKValidationErrors.m
+// Miruken
+//
+// Created by Craig Neuwirt on 2/4/13.
+// Copyright (c) 2013 ZixCorp. All rights reserved.
+//
+
+#import "MKValidationErrors.h"
+
+NSString * const MKValidationErrorDomain = @"MKValidation.ErrorDomain";
+
+NSString * const MKValidationErrorKeyPathUserInfoKey = @"MKValidationKeyPath";
+
+NSString * const MKValidationErrorSourceUserInfoKey = @"MKValidationSource";
View
18 Miruken/Validation/MKValidationExtension.h
@@ -0,0 +1,18 @@
+//
+// MKValidationExtension.h
+// Miruken
+//
+// Created by Craig Neuwirt on 4/24/13.
+// Copyright (c) 2013 ZixCorp. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "MKDynamicCallbackhandlerExtension.h"
+
+/**
+ This class extends MKDynamicCallbackHandler with convention-based validation capabilities.
+ */
+
+@interface MKValidationExtension : MKDynamicCallbackHandlerExtension
+
+@end
View
84 Miruken/Validation/MKValidationExtension.m
@@ -0,0 +1,84 @@
+//
+// MKValidationExtension.m
+// Miruken
+//
+// Created by Craig Neuwirt on 4/24/13.
+// Copyright (c) 2013 ZixCorp. All rights reserved.
+//
+
+#import "MKValidationExtension.h"
+#import "MKValidationResult.h"
+
+@implementation MKValidationExtension
+
+#pragma mark - Validation conventions
+
+- (BOOL)handleMKValidationResult:(MKValidationResult *)validation composition:(id<MKCallbackHandler>)composer
+{
+ NSString *specifier = NSStringFromClass([validation.target class]);
+
+ return
+ (self.handler.delegate && [self handleMKValidationResult:specifier validation:validation
+ composition:composer target:self.handler.delegate])
+ || [self handleMKValidationResult:specifier validation:validation composition:composer
+ target:self.handler];
+}
+
+- (BOOL)handleMKValidationResult:(NSString *)specifier validation:(MKValidationResult *)validation
+ composition:(id<MKCallbackHandler>)composer target:(id)target
+{
+ BOOL passObject = YES;
+ BOOL passComposer = NO;
+
+ SEL selector = [self.handler resolveNamedSelector:
+ [NSString stringWithFormat:@"validate%@:validation:", specifier] target:target];
+
+ if (selector == nil)
+ {
+ selector = [self.handler resolveNamedSelector:
+ [NSString stringWithFormat:@"validate%@:validation:composition:", specifier]
+ target:target];
+ if (selector)
+ passComposer = YES;
+ }
+
+ if (selector == nil)
+ {
+ passObject = NO;
+ selector = [self.handler resolveNamedSelector:@"validateUnknown:" target:target];
+
+ if (selector == nil)
+ {
+ selector = [self.handler resolveNamedSelector:@"validateUnknown:composition:" target:target];
+ if (selector)
+ passComposer = YES;
+ else
+ return NO;
+ }
+ }
+
+ NSInteger argIndex = 2;
+ NSMethodSignature *signature = [target methodSignatureForSelector:selector];
+ NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
+
+ [invocation setSelector:selector];
+ if (passObject)
+ {
+ id target = validation.target;
+ [invocation setArgument:&target atIndex:argIndex++];
+ }
+ [invocation setArgument:&validation atIndex:argIndex++];
+
+ if (passComposer)
+ [invocation setArgument:&composer atIndex:argIndex++];
+
+ BOOL handled = YES;
+ [invocation invokeWithTarget:target];
+
+ if (strcmp([signature methodReturnType], @encode(BOOL)) == 0)
+ [invocation getReturnValue:&handled];
+
+ return handled;
+}
+
+@end
View
37 Miruken/Validation/MKValidationResult.h
@@ -0,0 +1,37 @@
+//
+// MKValidationResult.h
+// Miruken
+//
+// Created by Craig Neuwirt on 11/19/12.
+// Copyright (c) 2012 Craig Neuwirt. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+/**
+ MKValidationResult is a container for object validation results.
+ */
+
+@interface MKValidationResult : NSObject
+
++ (instancetype)validateObject:(id)object inScope:(NSString *)scope;
+
+- (id)target;
+
+- (NSString *)scope;
+
+- (BOOL)isValid;
+
+- (BOOL)isNotValid;
+
+- (NSArray *)keyPathCulprits;
+
+- (NSDictionary *)errors;
+
+- (void)addError:(NSError *)error forKeyPath:(NSString *)keyPath;
+
+- (NSArray *)errorsForKeyPath:(NSString *)keyPath;
+
+- (NSError *)errorSummary;
+
+@end
View
96 Miruken/Validation/MKValidationResult.m
@@ -0,0 +1,96 @@
+//
+// MKValidationResult.m
+// Miruken
+//
+// Created by Craig Neuwirt on 11/19/12.
+// Copyright (c) 2012 Craig Neuwirt. All rights reserved.
+//
+
+#import "MKValidationResult.h"
+#import "NSError+MKValidation.h"
+
+@implementation MKValidationResult
+{
+ id _target;
+ NSString *_scope;
+ NSMutableDictionary *_errors;
+}
+
++ (instancetype)validateObject:(id)object inScope:(NSString *)scope
+{
+ return [[MKValidationResult alloc] initWithObject:object andScope:scope];
+}
+
+- (id)initWithObject:(id)object andScope:(NSString *)scope
+{
+ if (object == nil)
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:@"object cannot be nil"
+ userInfo:nil];
+
+ if (self = [super init])
+ {
+ _target = object;
+ _scope = scope;
+ _errors = [NSMutableDictionary new];
+ }
+ return self;
+}
+
+- (id)target
+{
+ return _target;
+}
+
+- (NSString *)scope
+{
+ return _scope;
+}
+
+- (BOOL)isValid
+{
+ return _errors.count == 0;
+}
+
+- (BOOL)isNotValid
+{
+ return _errors.count > 0;
+}
+
+- (NSArray *)keyPathCulprits
+{
+ return [_errors allKeys];
+}
+
+- (NSDictionary *)errors
+{
+ return _errors;
+}
+
+- (id)errorsForKeyPath:(NSString *)keyPath
+{
+ return [_errors objectForKey:keyPath];
+}
+
+- (void)addError:(NSError *)error forKeyPath:(NSString *)keyPath
+{
+ NSMutableArray *keyPathErrors = [_errors objectForKey:keyPath];
+ if (keyPathErrors == nil)
+ [_errors setValue:[NSMutableArray arrayWithObject:error] forKey:keyPath];
+ else
+ [keyPathErrors addObject:error];
+}
+
+- (NSError *)errorSummary
+{
+ if (self.isValid)
+ return nil;
+
+ NSError *summary = nil;
+ for (NSError *validationError in self.errors)
+ summary = summary ? [summary combineErrors:validationError] : validationError;
+
+ return summary;
+}
+
+@end
View
19 Miruken/Validation/NSError+MKValidation.h
@@ -0,0 +1,19 @@
+//
+// NSError+Validation.h
+// Miruken
+//
+// Created by Craig Neuwirt on 11/19/12.
+// Copyright (c) 2012 Craig Neuwirt. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface NSError (NSError_MKValidation)
+
+- (id)validationSourceCulprit;
+
+- (NSString *)validationKeyPathCulprit;
+
+- (NSError *)combineErrors:(NSError *)otherError;
+
+@end
View
47 Miruken/Validation/NSError+MKValidation.m
@@ -0,0 +1,47 @@
+//
+// NSError+Validation.m
+// Miruken
+//
+// Created by Craig Neuwirt on 11/19/12.
+// Copyright (c) 2012 Craig Neuwirt. All rights reserved.
+//
+
+#import "NSError+MKValidation.h"
+#import "MKValidationErrors.h"
+#import <CoreData/CoreData.h>
+
+@implementation NSError (NSError_MKValidation)
+
+- (id)validationSourceCulprit
+{
+ return self.userInfo[MKValidationErrorSourceUserInfoKey];
+}
+
+- (NSString *)validationKeyPathCulprit
+{
+ return self.userInfo[MKValidationErrorKeyPathUserInfoKey];
+}
+
+- (NSError *)combineErrors:(NSError *)otherError
+{
+ NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
+ NSMutableArray *otherErrors = [NSMutableArray arrayWithObject:otherError];
+
+ if (self.code == NSValidationMultipleErrorsError)
+ {
+ [userInfo addEntriesFromDictionary:self.userInfo];
+ [otherErrors addObjectsFromArray:[userInfo objectForKey:NSDetailedErrorsKey]];
+ }
+ else
+ {
+ [otherErrors addObject:self];
+ }
+
+ [userInfo setObject:otherErrors forKey:NSDetailedErrorsKey];
+
+ return [NSError errorWithDomain:NSCocoaErrorDomain
+ code:NSValidationMultipleErrorsError
+ userInfo:userInfo];
+}
+
+@end

0 comments on commit 46200b1

Please sign in to comment.
Something went wrong with that request. Please try again.