Skip to content

Commit

Permalink
Merge pull request #270 from apptentive/branch_5.2.11
Browse files Browse the repository at this point in the history
Release 5.2.11
  • Loading branch information
frankus authored Apr 27, 2020
2 parents e2ad5c7 + ec80ada commit ac77da9
Show file tree
Hide file tree
Showing 11 changed files with 183 additions and 58 deletions.
8 changes: 4 additions & 4 deletions Apptentive/Apptentive.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2405,7 +2405,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 38;
CURRENT_PROJECT_VERSION = 39;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
Expand Down Expand Up @@ -2463,7 +2463,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 38;
CURRENT_PROJECT_VERSION = 39;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
Expand Down Expand Up @@ -2495,7 +2495,7 @@
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 86WML2UN43;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 38;
DYLIB_CURRENT_VERSION = 39;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_PREFIX_HEADER = "Apptentive/Misc/ApptentiveConnect-Prefix.pch";
GCC_PREPROCESSOR_DEFINITIONS = "APPTENTIVE_DEBUG=1";
Expand All @@ -2515,7 +2515,7 @@
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 86WML2UN43;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 38;
DYLIB_CURRENT_VERSION = 39;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_PREFIX_HEADER = "Apptentive/Misc/ApptentiveConnect-Prefix.pch";
INFOPLIST_FILE = Apptentive/Info.plist;
Expand Down
2 changes: 1 addition & 1 deletion Apptentive/Apptentive/Apptentive.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ FOUNDATION_EXPORT double ApptentiveVersionNumber;
FOUNDATION_EXPORT const unsigned char ApptentiveVersionString[];

/** The version number of the Apptentive SDK. */
#define kApptentiveVersionString @"5.2.10"
#define kApptentiveVersionString @"5.2.11"

/** The version number of the Apptentive API platform. */
#define kApptentiveAPIVersionString @"9"
Expand Down
2 changes: 1 addition & 1 deletion Apptentive/Apptentive/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>5.2.10</string>
<string>5.2.11</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ @interface ApptentiveSurveyViewController ()
@property (assign, nonatomic) CGFloat toolbarInset;
@property (assign, nonatomic) BOOL keyboardVisible;

@property (assign, nonatomic) BOOL shouldPostAccessibiltyNotificationOnScrollViewDidEndScrollingAnimation;

@end


Expand Down Expand Up @@ -177,15 +179,28 @@ - (IBAction)submit:(id)sender {
HUD.imageView.image = [ApptentiveUtilities imageNamed:@"at_thanks"];
}
} else {
NSIndexPath *firstInvalidQuestionIndex = self.viewModel.firstInvalidAnswerIndexPath;
ApptentiveAssertNotNil(firstInvalidQuestionIndex, @"Expected non-nil index");
if (firstInvalidQuestionIndex) {
[self.collectionView scrollToItemAtIndexPath:firstInvalidQuestionIndex atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:YES];
UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, [self.viewModel errorMessageAtIndex:firstInvalidQuestionIndex.section]);
NSIndexPath *firstInvalidQuestionIndexPath = self.viewModel.firstInvalidAnswerIndexPath;
ApptentiveAssertNotNil(firstInvalidQuestionIndexPath, @"Expected non-nil index");
if (firstInvalidQuestionIndexPath) {
// Defer moving VoiceOver focus to first invalid question until after scrolling completes
self.shouldPostAccessibiltyNotificationOnScrollViewDidEndScrollingAnimation = YES;

[self.collectionView scrollToItemAtIndexPath:firstInvalidQuestionIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:YES];
}
}
}

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
if (self.shouldPostAccessibiltyNotificationOnScrollViewDidEndScrollingAnimation) {
NSIndexPath *firstInvalidQuestionIndexPath = self.viewModel.firstInvalidAnswerIndexPath;

UIView *firstInvalidQuestionView = [self.collectionView supplementaryViewForElementKind:UICollectionElementKindSectionHeader atIndexPath:firstInvalidQuestionIndexPath];
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, firstInvalidQuestionView);

self.shouldPostAccessibiltyNotificationOnScrollViewDidEndScrollingAnimation = NO;
}
}

- (IBAction)close:(id)sender {
UIViewController *presentingViewController = self.presentingViewController;
[self dismissViewControllerAnimated:YES
Expand Down Expand Up @@ -238,6 +253,7 @@ - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cell
cell.textView.text = [self.viewModel textOfAnswerAtIndexPath:indexPath];
cell.placeholderLabel.attributedText = [self.viewModel placeholderTextOfAnswerAtIndexPath:indexPath];
cell.placeholderLabel.hidden = cell.textView.text.length > 0;
cell.placeholderLabel.isAccessibilityElement = NO;
cell.textView.delegate = self;
cell.textView.tag = [self.viewModel textFieldTagForIndexPath:indexPath];
cell.textView.accessibilityLabel = cell.placeholderLabel.text;
Expand All @@ -254,7 +270,6 @@ - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cell
cell.textField.delegate = self;
cell.textField.tag = [self.viewModel textFieldTagForIndexPath:indexPath];
cell.textField.font = [self.viewModel.styleSheet fontForStyle:ApptentiveTextStyleTextInput];
cell.textField.accessibilityLabel = cell.textField.placeholder;
cell.textField.textColor = [self.viewModel.styleSheet colorForStyle:ApptentiveTextStyleTextInput];

return cell;
Expand All @@ -263,30 +278,33 @@ - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cell
case ATSurveyQuestionTypeSingleSelect:
case ATSurveyQuestionTypeMultipleSelect: {
NSString *reuseIdentifier, *buttonImageName, *detailText;
NSString *accessibilityHintDetails = nil;
NSString *accessibilityLabel = nil;
NSString *accessibilityHint = nil;

switch ([self.viewModel typeOfQuestionAtIndex:indexPath.section]) {
case ATSurveyQuestionTypeRange:
if (indexPath.item == 0) {
reuseIdentifier = @"RangeMinimum";
detailText = [self.viewModel minimumLabelForQuestionAtIndex:indexPath.section];
accessibilityHintDetails = [self.viewModel minimumLabelForQuestionAtIndex:indexPath.section];
} else if (indexPath.item == [self.viewModel numberOfAnswersForQuestionAtIndex:indexPath.section] - 1) {
reuseIdentifier = @"RangeMaximum";
detailText = [self.viewModel maximumLabelForQuestionAtIndex:indexPath.section];
accessibilityHintDetails = [self.viewModel maximumLabelForQuestionAtIndex:indexPath.section];
} else {
reuseIdentifier = @"Range";
}
buttonImageName = @"at_circle";
accessibilityLabel = [self.viewModel rangeOptionAccessibilityLabelForQuestionAtIndexPath:indexPath];
accessibilityHint = [self.viewModel rangeOptionAccessibilityHintForQuestionAtIndexPath:indexPath];
break;
case ATSurveyQuestionTypeMultipleSelect:
reuseIdentifier = @"Checkbox";
buttonImageName = @"at_checkmark";
accessibilityLabel = [self.viewModel textOfChoiceAtIndexPath:indexPath];
break;
default:
reuseIdentifier = @"Radio";
buttonImageName = @"at_circle";
accessibilityLabel = [self.viewModel textOfChoiceAtIndexPath:indexPath];
break;
}

Expand All @@ -306,17 +324,11 @@ - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cell
cell.detailTextLabel.text = detailText;
cell.detailTextLabel.font = [self.viewModel.styleSheet fontForStyle:ApptentiveTextStyleSurveyInstructions];
cell.detailTextLabel.textColor = [self.viewModel.styleSheet colorForStyle:ApptentiveTextStyleSurveyInstructions];

if (detailText) {
cell.accessibilityHint = detailText;
}

if (accessibilityHintDetails.length > 0) {
cell.accessibilityLabel = [NSString stringWithFormat:@"%@, %@", accessibilityHintDetails, [self.viewModel textOfChoiceAtIndexPath:indexPath]];
} else {
cell.accessibilityLabel = [self.viewModel textOfChoiceAtIndexPath:indexPath];
}

cell.accessibilityLabel = accessibilityLabel;
cell.accessibilityHint = accessibilityHint;
cell.accessibilityTraits |= UIAccessibilityTraitButton;

cell.button.image = buttonImage;
cell.button.highlightedImage = highlightedButtonImage;
[cell.button sizeToFit];
Expand Down Expand Up @@ -352,12 +364,15 @@ - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView
view.textLabel.text = [self.viewModel textOfQuestionAtIndex:indexPath.section];
view.textLabel.font = [self.viewModel.styleSheet fontForStyle:UIFontTextStyleBody];
view.textLabel.textColor = [self.viewModel.styleSheet colorForStyle:UIFontTextStyleBody];
view.textLabel.accessibilityHint = [self.viewModel accessibilityHintForQuestionAtIndexPath:indexPath];
view.instructionsTextLabel.attributedText = [self.viewModel instructionTextOfQuestionAtIndex:indexPath.section];
view.instructionsTextLabel.font = [self.viewModel.styleSheet fontForStyle:ApptentiveTextStyleSurveyInstructions];

view.separatorView.backgroundColor = [self.viewModel.styleSheet colorForStyle:ApptentiveColorSeparator];

view.isAccessibilityElement = YES;
view.accessibilityLabel = [self.viewModel accessibilityLabelForQuestionAtIndexPath:indexPath];
view.accessibilityHint = [self.viewModel accessibilityHintForQuestionAtIndexPath:indexPath];

return view;
} else {
ApptentiveSurveyQuestionFooterView *view = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"Footer" forIndexPath:indexPath];
Expand Down Expand Up @@ -611,7 +626,7 @@ - (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRan
return NO;
}

if([UIApplication.sharedApplication canOpenURL:URL]) {
if ([UIApplication.sharedApplication canOpenURL:URL]) {
[ApptentiveURLOpener openURL:URL completionHandler: NULL];
}

Expand Down Expand Up @@ -652,7 +667,7 @@ - (void)presentationControllerDidDismiss:(UIPresentationController *)presentatio
#pragma mark - View model delegate

- (void)viewModelValidationChanged:(ApptentiveSurveyViewModel *)viewModel isValid:(BOOL)valid {
[self.collectionViewLayout invalidateLayout];
[self.collectionView reloadData];

[self setToolbarHidden:valid];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ NS_ASSUME_NONNULL_BEGIN
- (NSString *)textOfQuestionAtIndex:(NSInteger)index;
- (nullable NSAttributedString *)instructionTextOfQuestionAtIndex:(NSInteger)index;
- (NSAttributedString *)placeholderTextOfAnswerAtIndexPath:(NSIndexPath *)indexPath;
- (nullable NSString *)rangeOptionAccessibilityLabelForQuestionAtIndexPath:(NSIndexPath *)indexPath;
- (nullable NSString *)rangeOptionAccessibilityHintForQuestionAtIndexPath:(NSIndexPath *)indexPath;
- (nullable NSString *)accessibilityLabelForQuestionAtIndexPath:(NSIndexPath *)indexPath;
- (nullable NSString *)accessibilityHintForQuestionAtIndexPath:(NSIndexPath *)indexPath;
- (ATSurveyQuestionType)typeOfQuestionAtIndex:(NSInteger)index;
- (ApptentiveSurveyAnswerType)typeOfAnswerAtIndexPath:(NSIndexPath *)indexPath;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,13 +161,59 @@ - (BOOL)answerIsSelectedAtIndexPath:(NSIndexPath *)indexPath {
return [self.selectedIndexPaths containsObject:indexPath];
}

- (nullable NSString *)accessibilityHintForQuestionAtIndexPath:(NSIndexPath *)indexPath {
- (nullable NSString *)rangeOptionAccessibilityLabelForQuestionAtIndexPath:(NSIndexPath *)indexPath {
NSString *result = [self textOfChoiceAtIndexPath:indexPath];

return result;
}

- (nullable NSString *)rangeOptionAccessibilityHintForQuestionAtIndexPath:(NSIndexPath *)indexPath {
NSInteger questionIndex = indexPath.section;

NSIndexPath *minValueIndexPath = [NSIndexPath indexPathForRow:0 inSection: questionIndex];
NSString *minValueLabel = [self textOfChoiceAtIndexPath:minValueIndexPath];
NSString *minLabel = [self minimumLabelForQuestionAtIndex:questionIndex];

NSInteger numberOfAnswers = [self numberOfAnswersForQuestionAtIndex:questionIndex];
NSIndexPath *maxValueIndexPath = [NSIndexPath indexPathForRow:numberOfAnswers - 1 inSection: questionIndex];
NSString *maxValueLabel = [self textOfChoiceAtIndexPath:maxValueIndexPath];
NSString *maxLabel = [self maximumLabelForQuestionAtIndex:questionIndex];

NSString *result = [NSString stringWithFormat:@"where %@ is %@ and %@ is %@", minValueLabel, minLabel, maxValueLabel, maxLabel];

return result;
}

- (nullable NSString *)accessibilityLabelForQuestionAtIndexPath:(NSIndexPath *)indexPath {
ApptentiveSurveyQuestion *question = [self questionAtIndex:indexPath.section];

NSMutableArray *resultParts = [[NSMutableArray alloc] init];

if ([self.invalidQuestionIndexes containsIndex:indexPath.section] && question.errorMessage != nil) {
[resultParts addObject:question.errorMessage];
}

if (question.value) {
[resultParts addObject:question.value];
}

if (question.required) {
return ApptentiveLocalizedString(@"required", @"Required answer hint");
NSString *requiredHint = self.survey.requiredText ?: ApptentiveLocalizedString(@"required", @"Required answer hint");

if (requiredHint) {
[resultParts addObject:requiredHint];
}
}

return nil;

NSString *result = [resultParts count] > 0 ? [resultParts componentsJoinedByString:@", "] : nil;

return result;
}

- (nullable NSString *)accessibilityHintForQuestionAtIndexPath:(NSIndexPath *)indexPath {
ApptentiveSurveyQuestion *question = [self questionAtIndex:indexPath.section];

return question.instructions;
}

- (ATSurveyQuestionType)typeOfQuestionAtIndex:(NSInteger)index {
Expand All @@ -187,7 +233,9 @@ - (NSString *)maximumLabelForQuestionAtIndex:(NSInteger)index {
}

- (nullable NSString *)errorMessageAtIndex:(NSInteger)index {
return [self questionAtIndex:index].errorMessage;
ApptentiveSurveyQuestion *question = [self questionAtIndex:index];

return question.errorMessage;
}

- (BOOL)answerIsValidForQuestionAtIndex:(NSInteger)index {
Expand All @@ -207,35 +255,35 @@ - (NSInteger)textFieldTagForIndexPath:(NSIndexPath *)indexPath {
}

-(BOOL)isNonEmptyText:(NSString *)text {
NSString *trimmed = [text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
BOOL isValid = [trimmed length] > 0;
return isValid;
NSString *trimmed = [text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
BOOL isValid = [trimmed length] > 0;

return isValid;
}

- (nullable NSAttributedString *)termsAndConditionsAttributedText:(TermsAndConditions *)termsAndConditions {
NSMutableAttributedString *result = [[NSMutableAttributedString alloc] init];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.alignment = NSTextAlignmentCenter;
NSDictionary *attributes = @{
NSParagraphStyleAttributeName: paragraphStyle,
NSFontAttributeName: [self.styleSheet fontForStyle:ApptentiveTextStyleSurveyInstructions],
NSForegroundColorAttributeName: [self.styleSheet colorForStyle:ApptentiveTextStyleBody],
};
NSString *bodyText = termsAndConditions.bodyText;
BOOL hasBodyText = [self isNonEmptyText:bodyText];
if (hasBodyText) {
NSMutableAttributedString *result = [[NSMutableAttributedString alloc] init];

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.alignment = NSTextAlignmentCenter;

NSDictionary *attributes = @{
NSParagraphStyleAttributeName: paragraphStyle,
NSFontAttributeName: [self.styleSheet fontForStyle:ApptentiveTextStyleSurveyInstructions],
NSForegroundColorAttributeName: [self.styleSheet colorForStyle:ApptentiveTextStyleBody],
};

NSString *bodyText = termsAndConditions.bodyText;
BOOL hasBodyText = [self isNonEmptyText:bodyText];

if (hasBodyText) {
[result appendAttributedString:[[NSAttributedString alloc] initWithString:bodyText attributes:attributes]];
}

NSURL *linkURL = termsAndConditions.linkURL;
BOOL hasValidURL = linkURL && [linkURL scheme] && [linkURL host];

if(hasValidURL) {
if (hasValidURL) {
if (hasBodyText) {
[result appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n\n" attributes:attributes]];
}
Expand Down
Loading

0 comments on commit ac77da9

Please sign in to comment.