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

Location Question Type #478

Merged
merged 111 commits into from Oct 23, 2015
Merged

Conversation

QuintilesRK
Copy link

This pull request adds support for a new location question and answer type. It can be used as a single question step and/or in a form task. You may have multiple entries in the form task and while interacting with each individual form item, the map will hide or show depending on your current selection. The location question handles the permission request for accessing the devices current location, when using the current location button. It will reverse geocode the current location value to an address and fill it in the question answer field.

Eric Rolf added 4 commits September 22, 2015 18:16
Includes:
Location Question
Location Question Answer Format
Location Question Form Cell
Location Survey Answer
* master: (114 commits)
  ResearchKit Project: add explicit 'ORK_LOG_LEVEL_WARNING=1'
  ORKImageSelectionView: resolve merge conflict
  ORKTest: fix column width not being updated after rotation
  ORKImageCaptureStepViewController: restore 'queue_' method prefix
  ORKTappingContentView: slight constraint refactor
  ORKSkin: hide 'ORKGetMetricForScreenType()' function; use 'ORKGetMetricForWindow()' instead
  Misc: remove extra newlines before 'else'
  Misc: remove additional space after '!' unary operator
  Misc: homegenize whitespace between consecutive closing and opening brackets
  ORKTaskViewController: whitespace
  Misc: homogenize for the more common 'cannot' instead of 'can not' in exception messages
  Misc: whitespace between '==' operator
  Misc: some additional constraint homogeneization of recently merged active tasks
  Misc: remove needless empty class extensions
  Misc: use 'has' instead of 'have' when refering to singular noun
  ORKFormItemCell: use VerticalMargin and HorizontalMargin const names
  Misc: remove space between '!' unary operator and operand
  Misc: use property syntax for accessing 'font', 'ascender', 'descender', and 'window'
  Misc: use property syntax for 'allValues' and 'allKeys'
  ORKDataLogger: use previous configuration file key for backwards compatibility
  ...

#pragma mark - ORKLocationAnswerFormat

@implementation ORKLocationAnswerFormat
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a warning that init has not been implemented. To dismiss the warning, go to ORKAnswerFormat_Internal.h and remove line 67 (marked below).

@rsanchezsaez
Copy link
Contributor

Also, although its layout looks ok, the location step logs unsatisfiable constraint warnings when shown. It'd be nice to fix those.

@rsanchezsaez
Copy link
Contributor

In ORKCatalog, sort the Location Question alphabetically within its section.

When doing this, make sure you reorder all the related code in ORKCatalog (represented task type, description text, task-generating code, etc.) accordingly, because we're trying to keep the code in the same order as the items appear in the list, as detailed here.

isValid = false;
} else if (longitude.doubleValue < -180.0 || longitude.doubleValue > 180.0) {
isValid = false;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change all the above isValid = false to isValid = NO.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to translate the coordinates into a string and then validated them here. We can just take the coordinates and validate them in isAnswerValid instead of validating them in isAnswerValidWithString:.

@Marxon13
Copy link
Contributor

@YuanZhu-apple The changes are ready for review.

ENTRY(ORKLocationAnswerFormat,
^id(NSDictionary *dict, ORKESerializationPropertyGetter getter) {
ORKLocationAnswerFormat *format = [[ORKLocationAnswerFormat alloc] init];
format.useCurrentLocation = ((NSNumber *)GETPROP(dict, useCurrentLocation)).boolValue;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is unnecessary, since useCurrentLocation can be written after init.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@YuanZhu-apple Removed unnecessary setting of userCurrentLocation.

_mapViewHeightConstraint = [NSLayoutConstraint constraintWithItem:_mapView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:ORKGetMetricForWindow(ORKScreenMetricLocationQuestionMapHeight, self.window)];
[constraints addObject:_mapViewHeightConstraint];

[NSLayoutConstraint activateConstraints:constraints];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

showMapViewIfNecessary can be called again and again, more and more constraints are added?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once this method is called, the mapView will have a super view, and the method will return on its second line. The map view is not an external property, so there is no way it can be removed from outside of the class, and it is never removed internally. Also once these constraints are set, they are never going to change since the map view is never going to be hidden once open. Do you want me to switch to using a boolean to keep track of wether or not this is called, or hold on to the constraints with an array and check its count?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation! It's good to keep it like this.

@Marxon13
Copy link
Contributor

@YuanZhu-apple Everything is ready for you to take another look at.

@YuanZhu-apple
Copy link
Member

typedef enum {
   kCLErrorLocationUnknown  = 0,
   kCLErrorDenied,
   kCLErrorNetwork,
   kCLErrorHeadingFailure,
   kCLErrorRegionMonitoringDenied,
   kCLErrorRegionMonitoringFailure,
   kCLErrorRegionMonitoringSetupDelayed,
   kCLErrorRegionMonitoringResponseDelayed,
   kCLErrorGeocodeFoundNoResult,
   kCLErrorGeocodeFoundPartialResult,
   kCLErrorGeocodeCanceled,
   kCLErrorDeferredFailed,
   kCLErrorDeferredNotUpdatingLocation,
   kCLErrorDeferredAccuracyTooLow,
   kCLErrorDeferredDistanceFiltered,
   kCLErrorDeferredCanceled,
   kCLErrorRangingUnavailable,
   kCLErrorRangingFailure,
} CLError;

Here is a list of all the possible errors from core location. Now all the error codes were untranslated, for example, when the WiFi is disabled(no internet connection), the error alert shows
screen shot 2015-10-20 at 1 26 02 pm

A more useful message should be displayed, like "Resolving address requires internet connection, please turn on your WiFi to answer this question. Skip this question if skip button is available, or come back to shi survey when you are back on internet".

I'm suggesting categorize the error codes into sub categories, and display different message to the user.

@Marxon13
Copy link
Contributor

@YuanZhu-apple Error handling has been updated. I've categorized the errors that would cause issues with the functionality of the location question. I've grouped other errors (like region monitoring) into an unknown error case. I'm debating whether or not those should even be displayed to the user, as it has nothing to do with the functionality of the question.

/* Alerts for invalid location coordinates */
"LOCATION_QUESTION_PLACEHOLDER" = "Enter an address";
"LOCATION_ERROR_TITLE" = "Failed to Resolve Specified Address";

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newly added strings are not here yet.

@YuanZhu-apple
Copy link
Member

Generally I think there are two kinds of message can be displayed to user:

  • Internet is not available, ask user to "turn on WiFi / try next time / skip"
  • User's input cannot be resolved, ask user to correct their input
    Please correct me if there are more messages can give guidance to user.

And for other types of errors, we need to handle them either internally within the view; or throw it out to taskViewController's delegate and let developer to handle.

@Marxon13
Copy link
Contributor

@YuanZhu-apple I added the localized strings I forgot, as well as internally absorbing the errors from the location manager that do not affect the functionality.

return [[ORKLocationAnswerFormat alloc] init];
},
(@{
PROPERTY(useCurrentLocation, NSNumber, NSObject, NO, nil, nil)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change writeAfterInit from NO to YES, it will fix the unit test failure in ORKTest

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@YuanZhu-apple Fixed issue causing tests to fail.

@YuanZhu-apple
Copy link
Member

Great, good to go.

YuanZhu-apple added a commit that referenced this pull request Oct 23, 2015
@YuanZhu-apple YuanZhu-apple merged commit 160b7c5 into ResearchKit:master Oct 23, 2015
@YuanZhu-apple YuanZhu-apple modified the milestone: Next Release Oct 28, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants