Skip to content

Commit c17b9b2

Browse files
committed
Merge pull request #82 from apptentive/Next
Release v1.2.9
2 parents b67207c + a97530f commit c17b9b2

File tree

100 files changed

+142
-41
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+142
-41
lines changed
-3.62 KB

ApptentiveConnect/art/camera icon.png

-3.42 KB
-1.08 KB
-14.5 KB
-1.26 KB
-869 Bytes
-953 Bytes
-6.38 KB
-958 Bytes

ApptentiveConnect/source/ATConnect.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#import <Cocoa/Cocoa.h>
1414
#endif
1515

16-
#define kATConnectVersionString @"1.2.8"
16+
#define kATConnectVersionString @"1.2.9"
1717

1818
#if TARGET_OS_IPHONE
1919
# define kATConnectPlatformString @"iOS"

ApptentiveConnect/source/Controllers/ATInfoViewController.m

+3
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,9 @@ - (void)setup {
277277
self.apptentivePrivacyTextView.text = ATLocalizedString(@"Your feedback is hosted by Apptentive and is subject to Apptentive's privacy policy and the privacy policy of the developer of this app.", @"Description of Apptentive privacy policy.");
278278
[self.gotoPrivacyPolicyButton setTitle:ATLocalizedString(@"Go to Apptentive's Privacy Policy", @"Title for button to open Apptentive's privacy policy") forState:UIControlStateNormal];
279279

280+
if ([tableView respondsToSelector:@selector(setAccessibilityIdentifier:)]) {
281+
[tableView setAccessibilityIdentifier:@"ATInfoViewTable"];
282+
}
280283
tableView.delegate = self;
281284
tableView.dataSource = self;
282285
tableView.tableHeaderView = self.headerView;

ApptentiveConnect/source/Message Center/ATBaseMessageCellV7.m

+3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ - (void)didScroll:(NSNotification *)notification {
1717
NSDictionary *userInfo = [notification userInfo];
1818
NSNumber *offset = userInfo[ATMessageCollectionTopOffsetKey];
1919
if (offset) {
20+
#pragma clang diagnostic push
21+
#pragma clang diagnostic ignored "-Wunreachable-code"
2022
CGFloat topOffset = CGFLOAT_IS_DOUBLE ? [offset doubleValue] : [offset floatValue];
23+
#pragma clang diagnostic pop
2124
UIView *collectionView = self;
2225
while ((collectionView = [collectionView superview])) {
2326
if ([collectionView isKindOfClass:[UICollectionView class]]) {

ApptentiveConnect/source/Message Center/ATMessageCenterBaseViewController.m

+1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ - (void)viewDidLoad {
9191
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(donePressed:)] autorelease];
9292
if ([self.navigationItem.leftBarButtonItem respondsToSelector:@selector(initWithImage:landscapeImagePhone:style:target:action:)]) {
9393
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithImage:[ATBackend imageNamed:@"at_user_button_image"] landscapeImagePhone:[ATBackend imageNamed:@"at_user_button_image_landscape"] style:UIBarButtonItemStylePlain target:self action:@selector(settingsPressed:)]autorelease];
94+
self.navigationItem.rightBarButtonItem.accessibilityLabel = ATLocalizedString(@"Contact Settings", @"Title of contact information edit screen");
9495
} else {
9596
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithImage:[ATBackend imageNamed:@"at_user_button_image"] style:UIBarButtonItemStylePlain target:self action:@selector(settingsPressed:)]autorelease];
9697
}

ApptentiveConnect/source/Message Center/ATPersonDetailsViewController.m

+15-2
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ - (void)viewDidUnload {
7777

7878
- (void)viewDidLoad {
7979
[super viewDidLoad];
80+
if ([self.tableView respondsToSelector:@selector(setAccessibilityIdentifier:)]) {
81+
[self.tableView setAccessibilityIdentifier:@"ATContactInfoTable"];
82+
}
8083
if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) {
8184
self.edgesForExtendedLayout = UIRectEdgeNone;
8285
}
@@ -166,9 +169,19 @@ - (BOOL)savePersonData {
166169
NSString *emailAddress = self.emailTextField.text;
167170
NSString *name = self.nameTextField.text;
168171
if (emailAddress && ![emailAddress isEqualToString:person.emailAddress]) {
169-
person.emailAddress = emailAddress;
170-
person.needsUpdate = YES;
172+
// Do not save empty string as person's email address
173+
if (emailAddress.length > 0) {
174+
person.emailAddress = emailAddress;
175+
person.needsUpdate = YES;
176+
}
177+
178+
// Deleted email address from form, then submitted.
179+
if ([emailAddress isEqualToString:@""] && person.emailAddress) {
180+
person.emailAddress = @"";
181+
person.needsUpdate = YES;
182+
}
171183
}
184+
172185
if (name && ![name isEqualToString:person.name]) {
173186
person.name = name;
174187
person.needsUpdate = YES;

ApptentiveConnect/source/Message Center/ATTextMessageCellV7.m

+36-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#import "ATTextMessageCellV7.h"
1111
#import "ATBackend.h"
12+
#import "ATConnect_Private.h"
1213
#import "ATMessageSender.h"
1314

1415
#define kMinimumIconConstraint 4
@@ -22,7 +23,41 @@ - (void)setup {
2223
self.messageLabel.enabledTextCheckingTypes = types;
2324
self.messageLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
2425
self.messageLabel.textColor = [UIColor blackColor];
25-
self.messageLabel.text = self.message.body;
26+
27+
NSString *messageBody = self.message.body;
28+
if ([[self.message pendingState] intValue] == ATPendingMessageStateSending) {
29+
NSString *sendingText = ATLocalizedString(@"Sending:", @"Sending prefix on messages that are sending");
30+
NSString *fullText = [NSString stringWithFormat:@"%@ %@", sendingText, messageBody];
31+
[self.messageLabel setText:fullText afterInheritingLabelAttributesAndConfiguringWithBlock:^ NSMutableAttributedString *(NSMutableAttributedString *mutableAttributedString) {
32+
NSRange boldRange = NSMakeRange(0, [sendingText length]);
33+
34+
UIFont *boldFont = [UIFont boldSystemFontOfSize:15];
35+
CTFontRef font = CTFontCreateWithName((CFStringRef)[boldFont fontName], [boldFont pointSize], NULL);
36+
if (font) {
37+
[mutableAttributedString addAttribute:(NSString *)kCTFontAttributeName value:(id)font range:boldRange];
38+
CFRelease(font), font = NULL;
39+
}
40+
return mutableAttributedString;
41+
}];
42+
} else if ([[self.message pendingState] intValue] == ATPendingMessageStateError) {
43+
NSString *sendingText = NSLocalizedString(@"Error:", @"Error prefix on messages that failed to send");
44+
NSString *fullText = [NSString stringWithFormat:@"%@ %@", sendingText, messageBody];
45+
[self.messageLabel setText:fullText afterInheritingLabelAttributesAndConfiguringWithBlock:^ NSMutableAttributedString *(NSMutableAttributedString *mutableAttributedString) {
46+
NSRange boldRange = NSMakeRange(0, [sendingText length]);
47+
48+
UIFont *boldFont = [UIFont boldSystemFontOfSize:15];
49+
UIColor *redColor = [UIColor redColor];
50+
CTFontRef font = CTFontCreateWithName((CFStringRef)[boldFont fontName], [boldFont pointSize], NULL);
51+
if (font) {
52+
[mutableAttributedString addAttribute:(NSString *)kCTFontAttributeName value:(id)font range:boldRange];
53+
CFRelease(font), font = NULL;
54+
}
55+
[mutableAttributedString addAttribute:(NSString *)kCTForegroundColorAttributeName value:(id)redColor.CGColor range:boldRange];
56+
return mutableAttributedString;
57+
}];
58+
} else {
59+
self.messageLabel.text = messageBody;
60+
}
2661

2762
self.textContainerView.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:1];
2863
self.textContainerView.layer.cornerRadius = 10;

ApptentiveConnect/source/Misc/ATUtilities.m

+1-10
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,7 @@ + (UIImage *)imageByTakingScreenshotExcludingWindow:(UIWindow *)excludedWindow {
4646
// On iOS prior to 4, fall back to use UIGraphicsBeginImageContext
4747
CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame];
4848
CGSize imageSize = applicationFrame.size;
49-
if (NULL != UIGraphicsBeginImageContextWithOptions) {
50-
UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0);
51-
} else {
52-
UIGraphicsBeginImageContext(imageSize);
53-
}
49+
UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0);
5450

5551
CGContextRef context = UIGraphicsGetCurrentContext();
5652

@@ -115,9 +111,6 @@ + (UIImage *)imageByTakingScreenshotIncludingBlankStatusBarArea:(BOOL)includeSta
115111
case UIInterfaceOrientationLandscapeRight:
116112
origin = CGPointMake(0, 0);
117113
break;
118-
default:
119-
origin = CGPointMake(0, 0);
120-
break;
121114
}
122115
[screenshot drawAtPoint:origin];
123116
UIImage *screenshotPlusStatusBar = UIGraphicsGetImageFromCurrentImageContext();
@@ -144,8 +137,6 @@ + (UIImage *)imageByRotatingImage:(UIImage *)image toInterfaceOrientation:(UIInt
144137
case UIInterfaceOrientationLandscapeRight:
145138
imageOrientation = UIImageOrientationLeft;
146139
break;
147-
default:
148-
break;
149140
}
150141
UIImage *rotated = [[[UIImage alloc] initWithCGImage:[image CGImage] scale:1 orientation:imageOrientation] autorelease];
151142

ApptentiveConnect/source/Model/ATEvent.m

+7-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ - (void)updateWithJSON:(NSDictionary *)json {
3232

3333
- (NSDictionary *)apiJSON {
3434
NSDictionary *parentJSON = [super apiJSON];
35-
NSMutableDictionary *result = [NSMutableDictionary dictionary];
35+
NSMutableDictionary *result = [[[NSMutableDictionary alloc] init] autorelease];
36+
3637
if (parentJSON) {
3738
[result addEntriesFromDictionary:parentJSON];
3839
}
@@ -49,7 +50,10 @@ - (NSDictionary *)apiJSON {
4950
}
5051

5152
// Monitor that the Event payload has not been dropped on retry
52-
if (!result || result.count == 0) {
53+
if (!result) {
54+
ATLogError(@"Event json should not be nil.");
55+
}
56+
if (result.count == 0) {
5357
ATLogError(@"Event json should return a result.");
5458
}
5559
if (!result[@"label"]) {
@@ -59,7 +63,7 @@ - (NSDictionary *)apiJSON {
5963
ATLogError(@"Event json should include a `nonce`.");
6064
}
6165

62-
return @{@"event":result};
66+
return @{@"event": result};
6367
}
6468

6569
- (void)setup {

ApptentiveConnect/source/Model/ATPersonInfo.m

+5
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,14 @@ - (NSDictionary *)apiJSON {
125125
if (self.facebookID) {
126126
[person setObject:self.facebookID forKey:@"facebook_id"];
127127
}
128+
128129
if (self.emailAddress && [self.emailAddress length] > 0 && [ATUtilities emailAddressIsValid:self.emailAddress]) {
129130
[person setObject:self.emailAddress forKey:@"email"];
131+
} else if ([[self.emailAddress stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:@""]) {
132+
// Delete a previously entered email
133+
[person setObject:[NSNull null] forKey:@"email"];
130134
}
135+
131136
if (self.secret) {
132137
[person setObject:self.secret forKey:@"secret"];
133138
}

ApptentiveConnect/source/Persistence/ATBackend.m

+17-6
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ - (BOOL)sendImageMessageWithImage:(UIImage *)image fromSource:(ATFeedbackImageSo
349349
- (BOOL)sendImageMessageWithImage:(UIImage *)image hiddenOnClient:(BOOL)hidden fromSource:(ATFeedbackImageSource)imageSource {
350350
NSData *imageData = UIImageJPEGRepresentation(image, 1.0);
351351
NSString *mimeType = @"image/jpeg";
352-
ATFIleAttachmentSource source;
352+
ATFIleAttachmentSource source = ATFileAttachmentSourceUnknown;
353353
switch (imageSource) {
354354
case ATFeedbackImageSourceCamera:
355355
case ATFeedbackImageSourcePhotoLibrary:
@@ -365,9 +365,6 @@ - (BOOL)sendImageMessageWithImage:(UIImage *)image hiddenOnClient:(BOOL)hidden f
365365
case ATFeedbackImageSourceProgrammatic:
366366
source = ATFIleAttachmentSourceProgrammatic;
367367
break;
368-
default:
369-
source = ATFileAttachmentSourceUnknown;
370-
break;
371368
}
372369

373370
return [self sendFileMessageWithFileData:imageData andMimeType:mimeType hiddenOnClient:hidden fromSource:source];
@@ -564,6 +561,10 @@ - (void)presentMessageCenterFromViewController:(UIViewController *)viewControlle
564561
- (void)presentMessageCenterFromViewController:(UIViewController *)viewController withCustomData:(NSDictionary *)customData {
565562
self.currentCustomData = customData;
566563

564+
if (!viewController) {
565+
ATLogError(@"Attempting to present Apptentive Message Center from a nil View Controller.");
566+
}
567+
567568
NSPredicate *notHidden = [NSPredicate predicateWithFormat:@"hidden != %@", @YES];
568569
NSUInteger messageCount = [ATData countEntityNamed:@"ATAbstractMessage" withPredicate:notHidden];
569570
if (messageCount == 0 || ![[ATConnect sharedConnection] messageCenterEnabled]) {
@@ -692,9 +693,19 @@ - (void)messagePanel:(ATMessagePanelViewController *)messagePanel didSendMessage
692693
person = [[[ATPersonInfo alloc] init] autorelease];
693694
}
694695
if (emailAddress && ![emailAddress isEqualToString:person.emailAddress]) {
695-
person.emailAddress = emailAddress;
696-
person.needsUpdate = YES;
696+
// Do not save empty string as person's email address
697+
if (emailAddress.length > 0) {
698+
person.emailAddress = emailAddress;
699+
person.needsUpdate = YES;
700+
}
701+
702+
// Deleted email address from form, then submitted.
703+
if ([emailAddress isEqualToString:@""] && person.emailAddress) {
704+
person.emailAddress = @"";
705+
person.needsUpdate = YES;
706+
}
697707
}
708+
698709
[person saveAsCurrentPerson];
699710

700711
[self sendTextMessageWithBody:message completion:^(NSString *pendingMessageID) {

ApptentiveConnect/source/Persistence/ATFeedback.m

+1
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ - (NSString *)stringForSource:(ATFeedbackSource)aSource {
268268
case ATFeedbackSourceEnjoymentDialog:
269269
result = @"enjoyment_dialog";
270270
break;
271+
case ATFeedbackSourceUnknown:
271272
default:
272273
break;
273274
}

ApptentiveConnect/source/Rating Flow/ATAppRatingFlow.m

+4
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,10 @@ - (void)dealloc {
152152

153153
#if TARGET_OS_IPHONE
154154
- (BOOL)showRatingFlowFromViewControllerIfConditionsAreMet:(UIViewController *)vc {
155+
if (!viewController) {
156+
ATLogError(@"Attempting to show Apptentive Rating Flow from a nil View Controller.");
157+
}
158+
155159
self.viewController = vc;
156160
# if TARGET_IPHONE_SIMULATOR
157161
[self logDefaults];

ApptentiveConnect/source/Surveys/Persistence/ATSurveysBackend.m

+23-14
Original file line numberDiff line numberDiff line change
@@ -135,21 +135,27 @@ - (void)presentSurveyControllerWithNoTagsFromViewController:(UIViewController *)
135135
[self resetSurvey];
136136
}
137137
currentSurvey = [[self surveyWithNoTags] retain];
138-
if (currentSurvey == nil) {
139-
return;
138+
if (currentSurvey) {
139+
[self presentSurveyControllerFromViewControllerWithCurrentSurvey:viewController];
140+
} else {
141+
ATLogInfo(@"No surveys without tags found!");
142+
ATLogInfo(@"Apptentive surveys have a 24 hour caching period. If you've recently created a survey, please reset your device/simulator and try again.");
140143
}
141-
[self presentSurveyControllerFromViewControllerWithCurrentSurvey:viewController];
142144
}
143145

144146
- (void)presentSurveyControllerWithTags:(NSSet *)tags fromViewController:(UIViewController *)viewController {
145147
if (currentSurvey != nil) {
146148
[self resetSurvey];
147149
}
148150
currentSurvey = [[self surveyWithTags:tags] retain];
149-
if (currentSurvey == nil) {
150-
return;
151+
152+
if (currentSurvey) {
153+
[self presentSurveyControllerFromViewControllerWithCurrentSurvey:viewController];
154+
} else {
155+
NSString *tagsString = [[[tags allObjects] valueForKey:@"description"] componentsJoinedByString:@", "];
156+
ATLogInfo(@"No surveys with tags [%@] found!", tagsString);
157+
ATLogInfo(@"Apptentive surveys have a 24 hour caching period. If you've recently created a survey, please reset your device/simulator and try again.");
151158
}
152-
[self presentSurveyControllerFromViewControllerWithCurrentSurvey:viewController];
153159
}
154160

155161
- (void)setDidSendSurvey:(ATSurvey *)survey {
@@ -194,20 +200,23 @@ - (ATSurvey *)surveyWithTags:(NSSet *)tags {
194200

195201
- (BOOL)hasSurveyAvailableWithNoTags {
196202
ATSurvey *survey = [self surveyWithNoTags];
197-
if (survey) {
198-
return YES;
199-
} else {
200-
return NO;
203+
if (!survey) {
204+
ATLogInfo(@"No surveys without tags found!");
205+
ATLogInfo(@"Apptentive surveys have a 24 hour caching period. If you've recently created a survey, please reset your device/simulator and try again.");
201206
}
207+
208+
return (survey != nil);
202209
}
203210

204211
- (BOOL)hasSurveyAvailableWithTags:(NSSet *)tags {
205212
ATSurvey *survey = [self surveyWithTags:tags];
206-
if (survey) {
207-
return YES;
208-
} else {
209-
return NO;
213+
if (!survey) {
214+
NSString *tagsString = [[[tags allObjects] valueForKey:@"description"] componentsJoinedByString:@", "];
215+
ATLogInfo(@"No surveys with tags [%@] found!", tagsString);
216+
ATLogInfo(@"Apptentive surveys have a 24 hour caching period. If you've recently created a survey, please reset your device/simulator and try again.");
210217
}
218+
219+
return (survey != nil);
211220
}
212221
@end
213222

ApptentiveConnect/source/Surveys/Tasks/ATSurveyGetSurveysTask.m

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#import "ATSurveyGetSurveysTask.h"
1010
#import "ATBackend.h"
11+
#import "ATDeviceUpdater.h"
1112
#import "ATSurveyParser.h"
1213
#import "ATSurveysBackend.h"
1314
#import "ATWebClient.h"
@@ -40,6 +41,10 @@ - (BOOL)canStart {
4041
if (![ATConversationUpdater conversationExists]) {
4142
return NO;
4243
}
44+
if ([ATDeviceUpdater shouldUpdate]) {
45+
// Surveys may depend upon device attributes.
46+
return NO;
47+
}
4348
return YES;
4449
}
4550

ApptentiveConnect/source/Tasks/ATRecordRequestTask.m

-2
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,6 @@ - (void)at_APIRequestDidFinish:(ATAPIRequest *)sender result:(id)result {
120120
case ATRecordRequestTaskFinishedResult:
121121
self.finished = YES;
122122
break;
123-
default:
124-
break;
125123
}
126124
[self stop];
127125
[self release];

CHANGELOG.md

+15-1

apptentive-ios.podspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'apptentive-ios'
3-
s.version = '1.2.8'
3+
s.version = '1.2.9'
44
s.license = 'BSD'
55
s.summary = 'Apptentive Customer Communications SDK.'
66
s.homepage = 'https://www.apptentive.com/'

0 commit comments

Comments
 (0)