From a17088cc1e0e2f666914f59fe6252f25119f2b9b Mon Sep 17 00:00:00 2001 From: Frank Schmitt Date: Thu, 16 May 2019 16:48:26 -0700 Subject: [PATCH] Apptentive IOS SDK 5.2.4 --- .travis.yml | 6 -- .../Apptentive.xcodeproj/project.pbxproj | 8 +-- Apptentive/Apptentive/Apptentive.h | 2 +- Apptentive/Apptentive/Apptentive.m | 5 +- Apptentive/Apptentive/Apptentive.storyboard | 65 +++++++----------- .../Engagement/Model/ApptentiveAppRelease.h | 6 ++ .../Engagement/Model/ApptentiveAppRelease.m | 5 ++ Apptentive/Apptentive/Info.plist | 2 +- .../ApptentiveMessageCenterViewModel.h | 1 - .../ApptentiveMessageCenterViewModel.m | 8 +-- .../ApptentiveMessageCenterViewController.m | 10 +-- .../Model/ApptentiveAttachment.m | 9 ++- .../Message Center/Model/ApptentiveMessage.h | 4 +- .../Message Center/Model/ApptentiveMessage.m | 15 ++-- .../ApptentiveMessageCenterProfileView.h | 7 -- .../ApptentiveMessageCenterProfileView.m | 68 +------------------ .../Model/ApptentiveLegacyMessage.m | 2 +- .../ApptentiveMessagePayload.m | 2 +- .../ApptentiveSurveyViewController.m | 17 +++++ .../Views/ApptentiveSurveyAnswerCell.h | 3 + .../Views/ApptentiveSurveyAnswerCell.m | 5 ++ .../ApptentiveConversationTests.m | 2 + Apptentive/ApptentiveTests/Info.plist | 2 +- CHANGELOG.md | 12 ++++ Example/Podfile.lock | 6 +- LICENSE.txt | 2 +- apptentive-ios.podspec | 2 +- 27 files changed, 121 insertions(+), 155 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 00b226d13..000000000 --- a/.travis.yml +++ /dev/null @@ -1,6 +0,0 @@ -language: objective-c -osx_image: xcode9 -xcode_project: Apptentive/Apptentive.xcodeproj -xcode_scheme: Apptentive -script: - - xcodebuild clean test -sdk iphonesimulator -project Apptentive/Apptentive.xcodeproj -scheme Apptentive -destination platform="iOS Simulator,name=iPhone SE,OS=10.3.1" CODE_SIGNING_REQUIRED=NO diff --git a/Apptentive/Apptentive.xcodeproj/project.pbxproj b/Apptentive/Apptentive.xcodeproj/project.pbxproj index ae20d2a50..8682d9ec8 100644 --- a/Apptentive/Apptentive.xcodeproj/project.pbxproj +++ b/Apptentive/Apptentive.xcodeproj/project.pbxproj @@ -2394,7 +2394,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 23; + CURRENT_PROJECT_VERSION = 24; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -2452,7 +2452,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 23; + CURRENT_PROJECT_VERSION = 24; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -2484,7 +2484,7 @@ DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 86WML2UN43; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 23; + DYLIB_CURRENT_VERSION = 24; DYLIB_INSTALL_NAME_BASE = "@rpath"; GCC_PREFIX_HEADER = "Apptentive/Misc/ApptentiveConnect-Prefix.pch"; GCC_PREPROCESSOR_DEFINITIONS = "APPTENTIVE_DEBUG=1"; @@ -2506,7 +2506,7 @@ DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 86WML2UN43; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 23; + DYLIB_CURRENT_VERSION = 24; DYLIB_INSTALL_NAME_BASE = "@rpath"; GCC_PREFIX_HEADER = "Apptentive/Misc/ApptentiveConnect-Prefix.pch"; GCC_TREAT_WARNINGS_AS_ERRORS = YES; diff --git a/Apptentive/Apptentive/Apptentive.h b/Apptentive/Apptentive/Apptentive.h index fe382c3ea..f54668f42 100644 --- a/Apptentive/Apptentive/Apptentive.h +++ b/Apptentive/Apptentive/Apptentive.h @@ -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.3" +#define kApptentiveVersionString @"5.2.4" /** The version number of the Apptentive API platform. */ #define kApptentiveAPIVersionString @"9" diff --git a/Apptentive/Apptentive/Apptentive.m b/Apptentive/Apptentive/Apptentive.m index 297b9b4b3..f709bb0a5 100644 --- a/Apptentive/Apptentive/Apptentive.m +++ b/Apptentive/Apptentive/Apptentive.m @@ -229,6 +229,7 @@ - (void)sendAttachmentText:(NSString *)text { } ApptentiveMessage *message = [[ApptentiveMessage alloc] initWithBody:text attachments:nil automated:NO customData:nil creationDate:[NSDate date]]; + message.hidden = YES; ApptentiveAssertNotNil(message, @"Message is nil"); if (message != nil) { @@ -268,6 +269,7 @@ - (void)sendAttachmentImage:(UIImage *)image { ApptentiveAssertNotNil(attachment, @"Attachment is nil"); if (attachment != nil) { ApptentiveMessage *message = [[ApptentiveMessage alloc] initWithBody:nil attachments:@[attachment] automated:NO customData:nil creationDate:[NSDate date]]; + message.hidden = YES; ApptentiveAssertNotNil(message, @"Message is nil"); if (message != nil) { @@ -308,8 +310,9 @@ - (void)sendAttachmentFile:(NSData *)fileData withMimeType:(NSString *)mimeType if (attachment != nil) { ApptentiveMessage *message = [[ApptentiveMessage alloc] initWithBody:nil attachments:@[attachment] automated:NO customData:nil creationDate:[NSDate date]]; - + message.hidden = YES; ApptentiveAssertNotNil(message, @"Message is nil"); + if (message != nil) { if (self.messageManager) { [self.messageManager enqueueMessageForSending:message]; diff --git a/Apptentive/Apptentive/Apptentive.storyboard b/Apptentive/Apptentive/Apptentive.storyboard index d438e88a8..a59b981c4 100644 --- a/Apptentive/Apptentive/Apptentive.storyboard +++ b/Apptentive/Apptentive/Apptentive.storyboard @@ -1,15 +1,11 @@ - + - - - - - + @@ -23,7 +19,7 @@ - + @@ -38,7 +34,7 @@ - + @@ -59,16 +55,16 @@ - + @@ -345,7 +335,6 @@ - @@ -353,7 +342,6 @@ - @@ -383,7 +371,6 @@ - @@ -580,14 +567,14 @@ - + - + @@ -1277,7 +1264,7 @@ Your feedback is hosted by Apptentive and is subject to both Apptentive’s priv - + @@ -1294,7 +1281,7 @@ Your feedback is hosted by Apptentive and is subject to both Apptentive’s priv - + @@ -1860,7 +1847,7 @@ Lines - + diff --git a/Apptentive/Apptentive/Engagement/Model/ApptentiveAppRelease.h b/Apptentive/Apptentive/Engagement/Model/ApptentiveAppRelease.h index 54e327909..39f07a7cb 100644 --- a/Apptentive/Apptentive/Engagement/Model/ApptentiveAppRelease.h +++ b/Apptentive/Apptentive/Engagement/Model/ApptentiveAppRelease.h @@ -24,6 +24,12 @@ NS_ASSUME_NONNULL_BEGIN */ @property (readonly, strong, nonatomic) NSString *type; + +/** + The bundle identifier of the app, e.g. com.example.MyApp + */ +@property (readonly, strong, nonatomic) NSString *bundleIdentifier; + /** The version object corresponding to the value of the `CFBundleShortVersionString` key in the application's `Info.plist` file. diff --git a/Apptentive/Apptentive/Engagement/Model/ApptentiveAppRelease.m b/Apptentive/Apptentive/Engagement/Model/ApptentiveAppRelease.m index 727613a90..e41304006 100644 --- a/Apptentive/Apptentive/Engagement/Model/ApptentiveAppRelease.m +++ b/Apptentive/Apptentive/Engagement/Model/ApptentiveAppRelease.m @@ -12,6 +12,7 @@ NS_ASSUME_NONNULL_BEGIN static NSString *const TypeKey = @"type"; +static NSString *const BundleIdentifierKey = @"bundleIdentifier"; static NSString *const VersionKey = @"version"; static NSString *const BuildKey = @"build"; static NSString *const HasAppStoreReceiptKey = @"hasAppStoreReceipt"; @@ -62,6 +63,7 @@ - (instancetype)initWithCurrentAppRelease { if (self) { _type = @"ios"; + _bundleIdentifier = NSBundle.mainBundle.infoDictionary[@"CFBundleIdentifier"]; _version = [[ApptentiveVersion alloc] initWithString:[NSBundle mainBundle].infoDictionary[@"CFBundleShortVersionString"]]; _build = [[ApptentiveVersion alloc] initWithString:[NSBundle mainBundle].infoDictionary[(NSString *)kCFBundleVersionKey]]; _hasAppStoreReceipt = [NSData dataWithContentsOfURL:[NSBundle mainBundle].appStoreReceiptURL] != nil; @@ -89,6 +91,7 @@ - (nullable instancetype)initWithCoder:(NSCoder *)coder { if (self) { _type = [coder decodeObjectOfClass:[NSString class] forKey:TypeKey]; + _bundleIdentifier = [coder decodeObjectOfClass:[NSString class] forKey:BundleIdentifierKey]; _version = [coder decodeObjectOfClass:[ApptentiveVersion class] forKey:VersionKey]; _build = [coder decodeObjectOfClass:[ApptentiveVersion class] forKey:BuildKey]; _hasAppStoreReceipt = [coder decodeBoolForKey:HasAppStoreReceiptKey]; @@ -119,6 +122,7 @@ - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; [coder encodeObject:self.type forKey:TypeKey]; + [coder encodeObject:self.bundleIdentifier forKey:BundleIdentifierKey]; [coder encodeObject:self.version forKey:VersionKey]; [coder encodeObject:self.build forKey:BuildKey]; [coder encodeBool:self.hasAppStoreReceipt forKey:HasAppStoreReceiptKey]; @@ -235,6 +239,7 @@ - (NSNumber *)boxedOverridingStyles { + (NSDictionary *)JSONKeyPathMapping { return @{ @"type": NSStringFromSelector(@selector(type)), + @"cf_bundle_identifier": NSStringFromSelector(@selector(bundleIdentifier)), @"cf_bundle_short_version_string": NSStringFromSelector(@selector(versionString)), @"cf_bundle_version": NSStringFromSelector(@selector(buildString)), @"app_store_receipt": NSStringFromSelector(@selector(appStoreReceiptDictionary)), diff --git a/Apptentive/Apptentive/Info.plist b/Apptentive/Apptentive/Info.plist index b9a3d061c..625805c8e 100644 --- a/Apptentive/Apptentive/Info.plist +++ b/Apptentive/Apptentive/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 5.2.3 + 5.2.4 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/Apptentive/Apptentive/Message Center/ApptentiveMessageCenterViewModel.h b/Apptentive/Apptentive/Message Center/ApptentiveMessageCenterViewModel.h index 7665a89cc..48047b721 100644 --- a/Apptentive/Apptentive/Message Center/ApptentiveMessageCenterViewModel.h +++ b/Apptentive/Apptentive/Message Center/ApptentiveMessageCenterViewModel.h @@ -76,7 +76,6 @@ typedef NS_ENUM(NSInteger, ATMessageCenterMessageStatus) { @property (readonly, nonatomic) NSString *profileInitialEmailPlaceholder; @property (readonly, nonatomic) NSString *profileInitialSkipButtonTitle; @property (readonly, nonatomic) NSString *profileInitialSaveButtonTitle; -@property (readonly, nonatomic) NSString *profileInitialEmailExplanation; @property (readonly, nonatomic) NSString *profileEditTitle; @property (readonly, nonatomic) NSString *profileEditNamePlaceholder; diff --git a/Apptentive/Apptentive/Message Center/ApptentiveMessageCenterViewModel.m b/Apptentive/Apptentive/Message Center/ApptentiveMessageCenterViewModel.m index b3b882f1e..f540c0cf5 100644 --- a/Apptentive/Apptentive/Message Center/ApptentiveMessageCenterViewModel.m +++ b/Apptentive/Apptentive/Message Center/ApptentiveMessageCenterViewModel.m @@ -213,10 +213,6 @@ - (NSString *)profileInitialSaveButtonTitle { return self.interaction.configuration[@"profile"][@"initial"][@"save_button"]; } -- (NSString *)profileInitialEmailExplanation { - return self.interaction.configuration[@"profile"][@"initial"][@"email_explanation"]; -} - #pragma mark - Profile (Edit) - (NSString *)profileEditTitle { @@ -300,6 +296,10 @@ - (nullable NSDate *)dateOfMessageGroupAtIndex:(NSInteger)index { - (ATMessageCenterMessageStatus)statusOfMessageAtIndexPath:(NSIndexPath *)indexPath { ApptentiveMessage *message = [self messageAtIndexPath:indexPath]; + if (message.hidden) { + return ATMessageCenterMessageStatusHidden; + } + switch (message.state) { case ApptentiveMessageStateFailedToSend: return ATMessageCenterMessageStatusFailed; diff --git a/Apptentive/Apptentive/Message Center/Controllers/ApptentiveMessageCenterViewController.m b/Apptentive/Apptentive/Message Center/Controllers/ApptentiveMessageCenterViewController.m index 22cb7fb01..1fd71c84d 100644 --- a/Apptentive/Apptentive/Message Center/Controllers/ApptentiveMessageCenterViewController.m +++ b/Apptentive/Apptentive/Message Center/Controllers/ApptentiveMessageCenterViewController.m @@ -289,8 +289,6 @@ - (void)configureView { self.profileView.containerView.backgroundColor = [self.viewModel.styleSheet colorForStyle:ApptentiveColorBackground]; self.profileView.titleLabel.text = self.viewModel.profileInitialTitle; self.profileView.titleLabel.textColor = [self.viewModel.styleSheet colorForStyle:ApptentiveTextStyleButton]; - self.profileView.requiredLabel.text = self.viewModel.profileInitialEmailExplanation; - self.profileView.requiredLabel.textColor = [self.viewModel.styleSheet colorForStyle:ApptentiveTextStyleSurveyInstructions]; [self.profileView.saveButton setTitle:self.viewModel.profileInitialSaveButtonTitle forState:UIControlStateNormal]; [self.profileView.skipButton setTitle:self.viewModel.profileInitialSkipButtonTitle forState:UIControlStateNormal]; self.profileView.skipButton.hidden = self.viewModel.profileRequired; @@ -306,14 +304,11 @@ - (void)configureView { if (self.viewModel.profileRequired && [self shouldShowProfileViewBeforeComposing:YES]) { self.profileView.skipButton.hidden = YES; - self.profileView.mode = ATMessageCenterProfileModeCompact; self.composeButtonItem.enabled = NO; self.neuMessageButtonItem.enabled = NO; - } else { - self.profileView.mode = ATMessageCenterProfileModeFull; } - } else { + } else { self.navigationItem.leftBarButtonItem = nil; } } @@ -743,8 +738,6 @@ - (IBAction)clear:(UIButton *)sender { } - (IBAction)showWho:(id)sender { - self.profileView.mode = ATMessageCenterProfileModeFull; - self.profileView.skipButton.hidden = NO; self.profileView.titleLabel.text = self.viewModel.profileEditTitle; @@ -1254,7 +1247,6 @@ - (void)updateHeaderFooterTextSize:(nullable NSNotification *)notification { self.profileView.titleLabel.font = [self.viewModel.styleSheet fontForStyle:ApptentiveTextStyleButton]; self.profileView.saveButton.titleLabel.font = [self.viewModel.styleSheet fontForStyle:ApptentiveTextStyleDoneButton]; self.profileView.skipButton.titleLabel.font = [self.viewModel.styleSheet fontForStyle:ApptentiveTextStyleButton]; - self.profileView.requiredLabel.font = [self.viewModel.styleSheet fontForStyle:ApptentiveTextStyleSurveyInstructions]; self.profileView.nameField.font = [self.viewModel.styleSheet fontForStyle:ApptentiveTextStyleTextInput]; self.profileView.emailField.font = [self.viewModel.styleSheet fontForStyle:ApptentiveTextStyleTextInput]; } diff --git a/Apptentive/Apptentive/Message Center/Model/ApptentiveAttachment.m b/Apptentive/Apptentive/Message Center/Model/ApptentiveAttachment.m index 1cb13faa2..272f47fce 100644 --- a/Apptentive/Apptentive/Message Center/Model/ApptentiveAttachment.m +++ b/Apptentive/Apptentive/Message Center/Model/ApptentiveAttachment.m @@ -98,7 +98,14 @@ - (nullable instancetype)initWithData:(NSData *)data contentType:(NSString *)con _attachmentDirectoryPath = attachmentDirectoryPath; NSURL *URL = [self permanentLocation]; - [data writeToURL:URL atomically:YES]; + NSError *error = nil; + BOOL success = [data writeToURL:URL options:NSDataWritingAtomic | NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication error:&error]; + + if (!success) { + ApptentiveLogError(ApptentiveLogTagMessages, @"Failed to write attachment to path"); + return nil; + } + _filename = URL.lastPathComponent; _size = [data length]; } diff --git a/Apptentive/Apptentive/Message Center/Model/ApptentiveMessage.h b/Apptentive/Apptentive/Message Center/Model/ApptentiveMessage.h index a5eaba1f9..424efa2a1 100644 --- a/Apptentive/Apptentive/Message Center/Model/ApptentiveMessage.h +++ b/Apptentive/Apptentive/Message Center/Model/ApptentiveMessage.h @@ -21,8 +21,7 @@ typedef NS_ENUM(NSInteger, ApptentiveMessageState) { ApptentiveMessageStateSent, ApptentiveMessageStateFailedToSend, ApptentiveMessageStateUnread, - ApptentiveMessageStateRead, - ApptentiveMessageStateHidden + ApptentiveMessageStateRead }; @@ -38,6 +37,7 @@ typedef NS_ENUM(NSInteger, ApptentiveMessageState) { @property (readonly, nonatomic) BOOL automated; @property (readonly, nullable, nonatomic) NSDictionary *customData; @property (readonly, nonatomic) BOOL inbound; +@property (assign, nonatomic) BOOL hidden; - (nullable instancetype)initWithJSON:(NSDictionary *)JSON; - (nullable instancetype)initWithBody:(nullable NSString *)body attachments:(nullable NSArray *)attachments automated:(BOOL)automated customData:(NSDictionary *_Nullable)customData creationDate:(NSDate *)creationDate; diff --git a/Apptentive/Apptentive/Message Center/Model/ApptentiveMessage.m b/Apptentive/Apptentive/Message Center/Model/ApptentiveMessage.m index 19149a091..a9864a861 100644 --- a/Apptentive/Apptentive/Message Center/Model/ApptentiveMessage.m +++ b/Apptentive/Apptentive/Message Center/Model/ApptentiveMessage.m @@ -82,14 +82,17 @@ - (nullable instancetype)initWithJSON:(NSDictionary *)JSON { _inbound = YES; } + if ([JSON[@"hidden"] isKindOfClass:[NSNumber class]] && [JSON[@"hidden"] boolValue]) { - _state = ApptentiveMessageStateHidden; + _hidden = YES; } else { - if (_inbound) { - _state = ApptentiveMessageStateSent; - } else { - _state = ApptentiveMessageStateUnread; - } + _hidden = NO; + } + + if (_inbound) { + _state = ApptentiveMessageStateSent; + } else { + _state = ApptentiveMessageStateUnread; } _identifier = ApptentiveDictionaryGetString(JSON, @"id"); diff --git a/Apptentive/Apptentive/Message Center/Views/ApptentiveMessageCenterProfileView.h b/Apptentive/Apptentive/Message Center/Views/ApptentiveMessageCenterProfileView.h index 5c4be3faa..27ba55d6b 100644 --- a/Apptentive/Apptentive/Message Center/Views/ApptentiveMessageCenterProfileView.h +++ b/Apptentive/Apptentive/Message Center/Views/ApptentiveMessageCenterProfileView.h @@ -10,22 +10,15 @@ NS_ASSUME_NONNULL_BEGIN -typedef NS_ENUM(NSInteger, ATMessageCenterProfileMode) { - ATMessageCenterProfileModeCompact = 1, - ATMessageCenterProfileModeFull -}; - @interface ApptentiveMessageCenterProfileView : UIView -@property (assign, nonatomic) ATMessageCenterProfileMode mode; @property (weak, nonatomic) IBOutlet UIView *containerView; @property (weak, nonatomic) IBOutlet UILabel *titleLabel; @property (weak, nonatomic) IBOutlet UITextField *nameField; @property (weak, nonatomic) IBOutlet UITextField *emailField; @property (weak, nonatomic) IBOutlet UIButton *skipButton; @property (weak, nonatomic) IBOutlet UIButton *saveButton; -@property (weak, nonatomic) IBOutlet UILabel *requiredLabel; @property (strong, nonatomic) UIColor *borderColor; @end diff --git a/Apptentive/Apptentive/Message Center/Views/ApptentiveMessageCenterProfileView.m b/Apptentive/Apptentive/Message Center/Views/ApptentiveMessageCenterProfileView.m index 662e6a57d..279e32232 100644 --- a/Apptentive/Apptentive/Message Center/Views/ApptentiveMessageCenterProfileView.m +++ b/Apptentive/Apptentive/Message Center/Views/ApptentiveMessageCenterProfileView.m @@ -25,9 +25,6 @@ @interface ApptentiveMessageCenterProfileView () @property (strong, nonatomic) NSArray *portraitFullConstraints; @property (strong, nonatomic) NSArray *landscapeFullConstraints; -@property (strong, nonatomic) NSArray *portraitCompactConstraints; -@property (strong, nonatomic) NSArray *landscapeCompactConstraints; - @property (strong, nonatomic) NSArray *baseConstraints; @end @@ -42,14 +39,12 @@ - (void)awakeFromNib { self.buttonBar.layer.borderWidth = borderWidth; self.portraitFullConstraints = @[self.nameTrailingConstraint, self.emailLeadingConstraint, self.nameVerticalSpaceToEmail]; - self.portraitCompactConstraints = @[self.nameTrailingConstraint, self.emailLeadingConstraint]; self.nameHorizontalSpaceToEmail = [NSLayoutConstraint constraintWithItem:self.nameField attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.emailField attribute:NSLayoutAttributeLeading multiplier:1.0 constant:-8.0]; NSLayoutConstraint *nameEmailTopAlignment = [NSLayoutConstraint constraintWithItem:self.nameField attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.emailField attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0]; NSLayoutConstraint *nameEmailBottomAlignment = [NSLayoutConstraint constraintWithItem:self.nameField attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.emailField attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0]; self.landscapeFullConstraints = @[self.nameHorizontalSpaceToEmail, nameEmailTopAlignment, nameEmailBottomAlignment]; - self.landscapeCompactConstraints = @[self.emailLeadingConstraint, nameEmailTopAlignment, nameEmailBottomAlignment]; // Find constraints common to both modes/orientations NSMutableSet *baseConstraintSet = [NSMutableSet setWithArray:self.containerView.constraints]; @@ -60,11 +55,7 @@ - (void)awakeFromNib { } - (BOOL)becomeFirstResponder { - if (self.mode == ATMessageCenterProfileModeFull) { - return [self.nameField becomeFirstResponder]; - } else { - return [self.emailField becomeFirstResponder]; - } + return [self.nameField becomeFirstResponder]; } - (void)setBorderColor:(UIColor *)borderColor { @@ -79,65 +70,12 @@ - (void)traitCollectionDidChange:(nullable UITraitCollection *)previousTraitColl // Deactivate all, then selectively re-activate [NSLayoutConstraint deactivateConstraints:self.portraitFullConstraints]; - [NSLayoutConstraint deactivateConstraints:self.portraitCompactConstraints]; [NSLayoutConstraint deactivateConstraints:self.landscapeFullConstraints]; - [NSLayoutConstraint deactivateConstraints:self.landscapeCompactConstraints]; if (self.traitCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact) { - switch (self.mode) { - case ATMessageCenterProfileModeFull: - [NSLayoutConstraint activateConstraints:self.landscapeFullConstraints]; - break; - - case ATMessageCenterProfileModeCompact: - [NSLayoutConstraint activateConstraints:self.landscapeCompactConstraints]; - break; - } + [NSLayoutConstraint activateConstraints:self.landscapeFullConstraints]; } else { - switch (self.mode) { - case ATMessageCenterProfileModeFull: - [NSLayoutConstraint activateConstraints:self.portraitFullConstraints]; - break; - - case ATMessageCenterProfileModeCompact: - [NSLayoutConstraint activateConstraints:self.portraitCompactConstraints]; - break; - } - } -} - -- (void)setMode:(ATMessageCenterProfileMode)mode { - if (_mode != mode) { - _mode = mode; - - CGFloat nameFieldAlpha; - - if (mode == ATMessageCenterProfileModeCompact) { - self.requiredLabel.hidden = NO; - nameFieldAlpha = 0; - self.emailVerticalSpaceToButtonBar.constant = 37.0; - } else { - self.nameField.hidden = NO; - nameFieldAlpha = 1; - self.emailVerticalSpaceToButtonBar.constant = 16.0; - } - - [self traitCollectionDidChange:self.traitCollection]; - - [UIView animateWithDuration:0.25 - animations:^{ - self.nameField.alpha = nameFieldAlpha; - self.requiredLabel.alpha = 1.0 - nameFieldAlpha; - - [self layoutIfNeeded]; - } - completion:^(BOOL finished) { - if (nameFieldAlpha == 0) { - self.nameField.hidden = YES; - } else { - self.requiredLabel.hidden = YES; - } - }]; + [NSLayoutConstraint activateConstraints:self.portraitFullConstraints]; } } diff --git a/Apptentive/Apptentive/Model/ApptentiveLegacyMessage.m b/Apptentive/Apptentive/Model/ApptentiveLegacyMessage.m index ca920fc7d..71e14da7a 100644 --- a/Apptentive/Apptentive/Model/ApptentiveLegacyMessage.m +++ b/Apptentive/Apptentive/Model/ApptentiveLegacyMessage.m @@ -91,7 +91,7 @@ + (BOOL)enqueueUnsentMessagesInContext:(NSManagedObjectContext *)context forConv ApptentiveMessage *message = [[ApptentiveMessage alloc] initWithBody:legacyMessage.body attachments:attachments automated:legacyMessage.automated.boolValue customData:customData creationDate:[NSDate dateWithTimeIntervalSince1970:legacyMessage.clientCreationTime.doubleValue]]; if (legacyMessage.hidden.boolValue) { - message.state = ApptentiveMessageStateHidden; + message.hidden = YES; } ApptentiveMessagePayload *payload = [[ApptentiveMessagePayload alloc] initWithMessage:message sessionIdentifier:nil]; diff --git a/Apptentive/Apptentive/Networking/Requests & Payloads/ApptentiveMessagePayload.m b/Apptentive/Apptentive/Networking/Requests & Payloads/ApptentiveMessagePayload.m index b34438a5d..b5ae0e514 100644 --- a/Apptentive/Apptentive/Networking/Requests & Payloads/ApptentiveMessagePayload.m +++ b/Apptentive/Apptentive/Networking/Requests & Payloads/ApptentiveMessagePayload.m @@ -62,7 +62,7 @@ - (NSDictionary *)JSONDictionary { } JSON[@"automated"] = @(self.message.automated); - JSON[@"hidden"] = @(self.message.state == ApptentiveMessageStateHidden); + JSON[@"hidden"] = @(self.message.hidden); if (self.message.customData) { NSDictionary *customDataDictionary = self.message.customData; diff --git a/Apptentive/Apptentive/Surveys/View Controllers/ApptentiveSurveyViewController.m b/Apptentive/Apptentive/Surveys/View Controllers/ApptentiveSurveyViewController.m index 70ec0d4b2..7a27b7ce4 100644 --- a/Apptentive/Apptentive/Surveys/View Controllers/ApptentiveSurveyViewController.m +++ b/Apptentive/Apptentive/Surveys/View Controllers/ApptentiveSurveyViewController.m @@ -416,6 +416,23 @@ - (BOOL)collectionView:(UICollectionView *)collectionView shouldDeselectItemAtIn } } +- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath { + // We need to work around a bug where cells that are/contain the first responder sometimes disappear. + // An internal property (_isHiddenForReuse) gets incorrectly stuck set to true, which hides the cell + // in one of two ways depending on OS version (see https://openradar.appspot.com/39604024) + + // In iOS 12.2, it sets the cell's layer to hidden, so we can undo that easily: + cell.layer.hidden = NO; + + // In iOS 10..<12.2 we need to force the hidden property to be false, so we use a custom getter in the + // cell that looks at our `forceUnhide` property. + if ([cell isKindOfClass:ApptentiveSurveyAnswerCell.class]) { + // If a cell is about to be displayed and is hidden, override it. + // If the cell is behaving correctly, clear the flag. + ((ApptentiveSurveyAnswerCell *)cell).forceUnhide = !cell.hidden; + } +} + #pragma mark Collection View Flow Layout Delegate - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { diff --git a/Apptentive/Apptentive/Surveys/Views/ApptentiveSurveyAnswerCell.h b/Apptentive/Apptentive/Surveys/Views/ApptentiveSurveyAnswerCell.h index f2174d75e..40ca0edba 100644 --- a/Apptentive/Apptentive/Surveys/Views/ApptentiveSurveyAnswerCell.h +++ b/Apptentive/Apptentive/Surveys/Views/ApptentiveSurveyAnswerCell.h @@ -12,6 +12,9 @@ NS_ASSUME_NONNULL_BEGIN @interface ApptentiveSurveyAnswerCell : UICollectionViewCell + +@property (nonatomic, assign) BOOL forceUnhide; + @end NS_ASSUME_NONNULL_END diff --git a/Apptentive/Apptentive/Surveys/Views/ApptentiveSurveyAnswerCell.m b/Apptentive/Apptentive/Surveys/Views/ApptentiveSurveyAnswerCell.m index dd0c96c81..567767b8a 100644 --- a/Apptentive/Apptentive/Surveys/Views/ApptentiveSurveyAnswerCell.m +++ b/Apptentive/Apptentive/Surveys/Views/ApptentiveSurveyAnswerCell.m @@ -12,6 +12,11 @@ @implementation ApptentiveSurveyAnswerCell + +- (BOOL)isHidden { + return super.hidden && !self.forceUnhide; +} + @end NS_ASSUME_NONNULL_END diff --git a/Apptentive/ApptentiveTests/ApptentiveConversationTests.m b/Apptentive/ApptentiveTests/ApptentiveConversationTests.m index 6781ff76f..79a3797a8 100644 --- a/Apptentive/ApptentiveTests/ApptentiveConversationTests.m +++ b/Apptentive/ApptentiveTests/ApptentiveConversationTests.m @@ -81,6 +81,8 @@ - (void)testAppRelease { XCTAssertFalse(self.conversation.appRelease.debugBuild); #endif + XCTAssertEqualObjects(self.conversation.appRelease.bundleIdentifier, @"com.apple.dt.xctest.tool"); + XCTAssertFalse(self.conversation.appRelease.isUpdateBuild); XCTAssertFalse(self.conversation.appRelease.isUpdateVersion); XCTAssertFalse(self.conversation.appRelease.isOverridingStyles); diff --git a/Apptentive/ApptentiveTests/Info.plist b/Apptentive/ApptentiveTests/Info.plist index 3a0895f8c..536fe677e 100644 --- a/Apptentive/ApptentiveTests/Info.plist +++ b/Apptentive/ApptentiveTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 5.2.3 + 5.2.4 CFBundleVersion 1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bfab9a41..a4ead56e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +# 2019-05-17 - v5.2.4 + +#### Bugs Fixed + +* Work around an iOS bug where survey text fields could disappear. +* Fix an issue where hidden messages (send with `sendAttachment()`) were visible in Message Center + +#### Improvements + +* Explicitly set the protection level on Message Center attachments. +* Also ask for name when Message Center requires an email address. + # 2018-11-27 - v5.2.3 #### Bugs Fixed diff --git a/Example/Podfile.lock b/Example/Podfile.lock index c43b09860..e8f6c79f8 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - apptentive-ios (5.2.3) + - apptentive-ios (5.2.4) DEPENDENCIES: - apptentive-ios (from `..`) @@ -9,8 +9,8 @@ EXTERNAL SOURCES: :path: ".." SPEC CHECKSUMS: - apptentive-ios: cfe3763ac1ef62af21791e57da0c30cbf28022f8 + apptentive-ios: bf18bf840887f0df730cd1e698e1570bf04ebf28 PODFILE CHECKSUM: 89d2b5f4683b04482e89df6d46b268cc9ed1ef79 -COCOAPODS: 1.5.3 +COCOAPODS: 1.6.0 diff --git a/LICENSE.txt b/LICENSE.txt index 4af3ee3c0..9103a634a 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2011-2014, Apptentive, Inc. +Copyright (c) 2011-2019, Apptentive, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/apptentive-ios.podspec b/apptentive-ios.podspec index 8b42ecebc..fa2f52def 100644 --- a/apptentive-ios.podspec +++ b/apptentive-ios.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = 'apptentive-ios' s.module_name = 'Apptentive' - s.version = '5.2.3' + s.version = '5.2.4' s.license = 'BSD' s.summary = 'Apptentive Customer Communications SDK.' s.homepage = 'https://www.apptentive.com/'