Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ORKNavigationRule accepting a closure as an alternative to ORKResultPredicate #531

Closed
md0u80c9 opened this issue Oct 15, 2015 · 7 comments
Closed

Comments

@md0u80c9
Copy link
Member

The proposal would be to extend ORKPredicateStepNavigationRule to take a closure as an alternative to ORKResultPredicate.

Example case: your study may contain multiple surveys/forms. Or you may have data from other areas (HealthKit being the obvious example).

Your application could then have significantly better logic from external variables, without having to resort to subclassing.

In my application example, we have some data stored in Core Data (demographics) - if the data is already present (because they have entered data from an earlier survey) we won't want to ask it in any subsequent survey. If it's not present we will ask it and then as part of our result parser put the data into Core Data.

If your application picked up an anomaly on HealthKit that might lead to a change in your survey questions (eg. diabetic has an abnormal blood sugar result from HealthKit you may want to ask extra dietary intake questions).

The closure would either return a boolean state: true ( go to the specified destination), or false. It could alternatively conceivably return a String state (destinationStepIdentifier), allowing effectively a switch-type predicate.

@rsanchezsaez
Copy link
Contributor

This is a good idea, I may look into it at a later date.

@rsanchezsaez
Copy link
Contributor

Hey @YuanZhu-apple, I have been looking into this by drafting an API along the lines:

typedef NSString  * _Nullable  (^ORKBlockStepNavigationRuleHandler)(ORKTaskResult *taskResult);

ORK_CLASS_AVAILABLE
@interface ORKBlockStepNavigationRule : ORKStepNavigationRule

- (instancetype)initWithRuleHandler:(ORKBlockStepNavigationRuleHandler)ruleHandler NS_DESIGNATED_INITIALIZER;
@property (nonatomic, copy, readonly) ORKBlockStepNavigationRuleHandler ruleHandler;

@end

Where ORKBlockStepNavigationRuleHandler returns the destination step identifier you want to jump to. However, I've noticed that this class won't be able to conform to NSSecureCoding since blocks cannot be archived. Similarly, the class would not play nice regarding JSON serialization.

Do you think it's worth implementing anyway? I suspect having a rule class that's not archivable is not a good idea, as this would cause issues when archiving ORKNavigableOrderedTask. Any ideas on how to work around this? Or should we just forget about such a kind of navigation rule?

@YuanZhu-apple
Copy link
Member

@rsanchezsaez The API design is OK with me.
Yes, I can see this rule won't support NSSecureCoding.

How about make a protocol for identifierForDestinationStepWithTaskResult:; let ORKStepNavigationRule adopt it. Then ORKBlockStepNavigationRule just need to implement the new protocol without conforming to NSSecureCoding.

Do you like this approach?

I just realized NavigationRule is expected to be archived with ORKNavigableTask, this may not work.

But I found NSPredicate has predicateWithBlock: but still conforming to NSSecureCoding.
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSPredicate_Class/#//apple_ref/occ/clm/NSPredicate/predicateWithBlock:

Is it possible for ORKPredicateStepNavigationRule to take a block type predicate? Then no change is required.

@rsanchezsaez
Copy link
Contributor

On one hand, ORKPredicateStepNavigationRule and ORKPredicateSkipStepNavigationRule support any kind of NSPredicate object, so an NSPredicate initialized with predicateWithBlock: will work just fine (I just tested them).

However, deceivingly, those NSPredicate cannot be encoded. This is what happens when you try to encode one such predicate:

2016-03-16 18:23:54.453 ORKTest[24301:5379870] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'NSBlockPredicate cannot be encoded or decoded'


So I guess we can just leave it like that, and if somebody (@md0u80c9?) needs to use them, they must be aware that they will lose ORKNavigableOrderedTask encoding capabilities. ;-)

If everybody agrees, this issue can be closed.

@YuanZhu-apple
Copy link
Member

@rsanchezsaez Thanks for trying it!

So the fact is that ORKNavigationRule can accept a closure now, but cannot be serialized(Nothing we can do about it).

@md0u80c9 Can this issue be closed?

@rsanchezsaez
Copy link
Contributor

I think this issue can be closed.

@md0u80c9
Copy link
Member Author

Agree I think it can be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants