Skip to content

Commit 0d34c39

Browse files
author
Evan Greer
committed
Merge branch 'master' into embedded
2 parents ecc4ed2 + 46b0038 commit 0d34c39

File tree

19 files changed

+608
-109
lines changed

19 files changed

+608
-109
lines changed

CHANGELOG.md

+155-2
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,164 @@ This project adheres to [Semantic Versioning](http://semver.org/).
1212
#### Changed
1313
- nothing yet
1414

15+
## [3.4.17](https://github.com/Iterable/iterable-android-sdk/releases/tag/3.4.17)
16+
#### Added
17+
- when JWT is invalid, `IterableAuthManager` is updated to fetch and store a new JWT token locally
18+
- `IterableRequestTask` now has a retry mechanism that fetches a new JWT token and retries the request if JWT is invalid
19+
- retries are capped at a max of 5
20+
21+
## [3.4.16](https://github.com/Iterable/iterable-android-sdk/releases/tag/3.4.16)
1522
#### Fixed
16-
- nothing yet
23+
- SDK now handles `null` scenarios preventing crashes when `IterableEncryptedSharedPreference` creation fails.
24+
- Updated crypto library to version [1.1.0-alpha06](https://developer.android.com/jetpack/androidx/releases/security#1.1.0-alpha06). [1.1.0-alpha05](https://developer.android.com/jetpack/androidx/releases/security#1.1.0-alpha05) solves a race condition during creation process.
1725

18-
## [3.4.9](https://github.com/Iterable/iterable-android-sdk/releases/tag/3.4.9)
26+
## [3.4.15](https://github.com/Iterable/iterable-android-sdk/releases/tag/3.4.15)
27+
#### Added
28+
29+
This release allows you to use projects hosted on Iterable's EU data center. If your project is hosted on Iterable's [European data center (EUDC)](https://support.iterable.com/hc/articles/17572750887444), configure the SDK to use Iterable's EU-based API endpoints:
30+
31+
_Java_
32+
33+
```java
34+
IterableConfig config = new IterableConfig.Builder()
35+
// ... other configuration options ...
36+
.setDataRegion(IterableDataRegion.EU)
37+
.build();
38+
IterableApi.initialize(context, "<YOUR_API_KEY>", config);
39+
```
40+
41+
_Kotlin_
42+
43+
```kotlin
44+
val configBuilder = IterableConfig.Builder()
45+
// ... other configuration options ...
46+
.setDataRegion(IterableDataRegion.EU)
47+
.build();
48+
IterableApi.initialize(context, "<YOUR_API_KEY>", config);
49+
```
50+
51+
#### Fixed
52+
- Addressed React Native SDK push notification deep linking issues where the app would restart instead of resuming the last activity upon being backgrounded.
53+
- Resolves an additional push notification problem wherein the customActionHandler and urlHandler were not being invoked in specific scenarios, as documented in issue #470. (Credit to @tnortman-jabra for the report and the fix)
54+
55+
## [3.4.14](https://github.com/Iterable/iterable-android-sdk/releases/tag/3.4.14)
56+
#### Added
57+
- `IterableInAppManager.setRead` now accepts `IterableHelper.FailureHandler failureHandler`
58+
59+
#### Fixed
60+
- Fixes an issue where `IterableInAppManager.removeMessage` caused build failure in React Native SDK pointing to legacy method calls.
61+
- Fixes an issue where custom action handlers were not invoked when tapping on push notification when the app is in background.
62+
63+
## [3.4.13](https://github.com/Iterable/iterable-android-sdk/releases/tag/3.4.13)
64+
#### Added
65+
- `IterableInAppManager.setRead` now accepts `IterableHelper.SuccessHandler successHandler`.
66+
- `IterableApi.inAppConsume` now accepts `IterableHelper.SuccessHandler successHandler` and `IterableHelper.FailureHandler failureHandler`.
67+
68+
## [3.4.12](https://github.com/Iterable/iterable-android-sdk/releases/tag/3.4.12)
69+
#### Added
70+
- `setEmail` and `setUserId` now accepts `IterableHelper.SuccessHandler successHandler` and `IterableHelper.FailureHandler failureHandler`.
71+
72+
#### Changed
73+
- OTT devices (FireTV) will now register as `OTT` device instead of `Android` under user's devices.
74+
75+
## [3.4.11](https://github.com/Iterable/iterable-android-sdk/releases/tag/3.4.11)
76+
77+
#### Added
78+
79+
- Custom push notification sounds! To play a custom sound for a push notification, add a sound file to your app's `res/raw` folder and specify that same filename when setting up a template in Iterable.
80+
81+
Some important notes about custom sounds and notification channels:
82+
83+
- Android API level 26 introduced [notification channels](https://developer.android.com/develop/ui/views/notifications/channels). Every notification must be assigned to a channel.
84+
- Each custom sound you add to an Iterable template creates a new Android notification channel. The notification channel's name matches the filename of the sound (without its extension).
85+
- To ensure sensible notification channel names for end users, give friendly names to your sound files. For example, a custom sound file with name `Paid.mp3` creates a notification channel called `Paid`. The end user can see this notification channel name in their device's notification channel settings.
86+
- Be sure to place the corresponding sound file in your app's `res/raw` directory.
87+
88+
- To help you access a user's `email` address, `userId`, and `authToken`, the SDK now provides convenience methods: `getEmail()`, `getUserId()`, and `getAuthToken()`.
1989

90+
#### Changed
91+
92+
- Updated the [Security library](https://developer.android.com/topic/security/data) and improved `EncryptedSharedPreferences` handling.
93+
94+
To work around a [known Android issue](https://issuetracker.google.com/issues/164901843) that can cause crashes when creating `EncryptedSharedPreferences`, we've upgraded `androidx.security.crypto` from version `1.0.0` to `1.1.0-alpha04`. When `EncryptedSharedPreferences` cannot be created, the SDK now uses `SharedPreferences` (unencrypted).
95+
96+
If your app requires encryption, you can prevent this fallback to `SharedPreferences` by setting the `encryptionEnforced` configuration flag to `true`. However, if you enable this flag and `EncryptedSharedPreferences` cannot be created, an exception will be thrown.
97+
98+
- Improved JWT token management. This change addresses an issue where `null` values could prevent the refresh of a JWT token.
99+
100+
#### Fixed
101+
102+
- Fixed an issue which could prevent in-app messages from respecting the **Position** value selected when setting up the template (top / center / bottom / full).
103+
104+
- Fixed crashes that sometimes happened during in-app message animations.
105+
106+
## [3.4.10](https://github.com/Iterable/iterable-android-sdk/releases/tag/3.4.10)
107+
This release includes support for encrypting some data at rest, and an option to
108+
store in-app messages in memory.
109+
110+
#### Encrypted data
111+
112+
In Android apps with `minSdkVersion` 23 or higher ([Android 6.0](https://developer.android.com/studio/releases/platforms#6.0))
113+
Iterable's Android SDK now encrypts the following fields when storing them at
114+
rest:
115+
116+
- `email` — The user's email address.
117+
- `userId` — The user's ID.
118+
- `authToken` — The JWT used to authenticate the user with Iterable's API.
119+
120+
(Note that Iterable's Android SDK does not store the last push payload at
121+
rest—before or after this update.)
122+
123+
For more information about this encryption in Android, examine the source code
124+
for Iterable's Android SDK: [`IterableKeychain`](https://github.com/Iterable/iterable-android-sdk/blob/master/iterableapi/src/main/java/com/iterable/iterableapi/IterableKeychain.kt).
125+
126+
#### Storing in-app messages in memory
127+
128+
This release also allows you to have your Android apps (regardless of `minSdkVersion`)
129+
store in-app messages in memory, rather than in an unencrypted local file.
130+
However, an unencrypted local file is still the default option.
131+
132+
To store in-app messages in memory, set the `setUseInMemoryStorageForInApps(true)`
133+
SDK configuration option (defaults to `false`):
134+
135+
_Java_
136+
137+
```java
138+
IterableConfig.Builder configBuilder = new IterableConfig.Builder()
139+
// ... other configuration options ...
140+
.setUseInMemoryStorageForInApps(true);
141+
IterableApi.initialize(context, "<YOUR_API_KEY>", config);
142+
```
143+
144+
_Kotlin_
145+
146+
```kotlin
147+
val configBuilder = IterableConfig.Builder()
148+
// ... other configuration options ...
149+
.setUseInMemoryStorageForInApps(true);
150+
IterableApi.initialize(context, "<YOUR_API_KEY>", configBuilder.build());
151+
```
152+
153+
When users upgrade to a version of your Android app that uses this version of
154+
the SDK (or higher), and you've set this configuration option to `true`, the
155+
local file used for in-app message storage (if it already exists) is deleted
156+
However, no data is lost.
157+
158+
#### Android upgrade instructions
159+
160+
If your app targets API level 23 or higher, this is a standard SDK upgrade, with
161+
no special instructions.
162+
163+
If your app targets an API level less than 23, you'll need to make the following
164+
changes to your project (which allow your app to build, even though it won't
165+
encrypt data):
166+
167+
1. In `AndroidManifest.xml`, add `<uses-sdk tools:overrideLibrary="androidx.security" />`
168+
2. In your app's `app/build.gradle`:
169+
- Add `multiDexEnabled true` to the `default` object, under `android`.
170+
- Add `implementation androidx.multidex:multidex:2.0.1` to the `dependencies`.
171+
172+
## [3.4.9](https://github.com/Iterable/iterable-android-sdk/releases/tag/3.4.9)
20173
#### Added
21174
- Added new methods for `setEmail`, `setUserId` and `updateEmail` which accepts `authToken`, providing more ways to pass `authToken` to SDK
22175
- Added two interface methods - `onTokenRegistrationSuccessful` and `onTokenRegistrationFailed`. Override these methods to see if authToken was successfully received by the SDK.

app/build.gradle

+12
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,25 @@ android {
2020
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
2121
multiDexEnabled true
2222
}
23+
2324
buildTypes {
2425
release {
2526
minifyEnabled false
2627
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
2728
}
29+
2830
debug {
2931
testCoverageEnabled true
3032
}
3133
}
3234

3335
testOptions.unitTests.includeAndroidResources = true
36+
3437
compileOptions {
3538
sourceCompatibility = 1.8
3639
targetCompatibility = 1.8
3740
}
41+
3842
kotlinOptions {
3943
jvmTarget = "1.8"
4044
}
@@ -73,9 +77,11 @@ dependencies {
7377
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.2.0'
7478
androidTestImplementation 'br.com.concretesolutions:kappuccino:1.2.1'
7579
}
80+
7681
tasks.withType(Test) {
7782
jacoco.includeNoLocationClasses = true
7883
}
84+
7985
task jacocoDebugTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest']) {
8086
group = "reporting"
8187
description = "Generate unified Jacoco code coverage report"
@@ -103,12 +109,14 @@ task jacocoDebugTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest'])
103109
'**/*$ModuleAdapter.class',
104110
'**/*$ViewInjector*.class',
105111
]
112+
106113
def debugTree = fileTree(dir: "${buildDir}/intermediates/javac/debug/classes", excludes: fileFilter) //we use "debug" build type for test coverage (can be other)
107114
def sdkTree = fileTree(dir: "${buildDir}/../../iterableapi/build/intermediates/javac/debug/classes", excludes: fileFilter)
108115
def sdkUiTree = fileTree(dir: "${buildDir}/../../iterableapi-ui/build/intermediates/javac/debug/classes", excludes: fileFilter)
109116
def mainSrc = "${project.projectDir}/src/main/java"
110117
def sdkSrc = "${project.projectDir}/../iterableapi/src/main/java"
111118
def sdkUiSrc = "${project.projectDir}/../iterableapi-ui/src/main/java"
119+
112120
sourceDirectories.from = files([mainSrc])
113121
classDirectories.from = files([debugTree])
114122
additionalSourceDirs.from = files([sdkSrc, sdkUiSrc])
@@ -121,11 +129,13 @@ task jacocoDebugTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest'])
121129
task jacocoDebugAndroidTestReport(type: JacocoReport, dependsOn: ['connectedCheck']) {
122130
group = "reporting"
123131
description = "Generate Jacoco code coverage report for instumentation tests"
132+
124133
reports {
125134
xml.enabled = true
126135
html.enabled = true
127136
csv.enabled = false
128137
}
138+
129139
def fileFilter = [
130140
'**/*Test*.*',
131141
'**/AutoValue_*.*',
@@ -145,12 +155,14 @@ task jacocoDebugAndroidTestReport(type: JacocoReport, dependsOn: ['connectedChec
145155
'**/*$ModuleAdapter.class',
146156
'**/*$ViewInjector*.class',
147157
]
158+
148159
def debugTree = fileTree(dir: "${buildDir}/intermediates/javac/debug/classes", excludes: fileFilter) //we use "debug" build type for test coverage (can be other)
149160
def sdkTree = fileTree(dir: "${buildDir}/../../iterableapi/build/intermediates/javac/debug/classes", excludes: fileFilter)
150161
def sdkUiTree = fileTree(dir: "${buildDir}/../../iterableapi-ui/build/intermediates/javac/debug/classes", excludes: fileFilter)
151162
def mainSrc = "${project.projectDir}/src/main/java"
152163
def sdkSrc = "${project.projectDir}/../iterableapi/src/main/java"
153164
def sdkUiSrc = "${project.projectDir}/../iterableapi-ui/src/main/java"
165+
154166
sourceDirectories.from = files([mainSrc])
155167
classDirectories.from = files([debugTree])
156168
additionalSourceDirs.from = files([sdkSrc, sdkUiSrc])
+2-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<manifest xmlns:tools="http://schemas.android.com/tools"
3-
package="iterable.com.iterableapi">
4-
<uses-sdk tools:overrideLibrary="br.com.concretesolutions.kappuccino,android_libs.ub_uiautomator"/>
2+
<manifest xmlns:tools="http://schemas.android.com/tools" package="iterable.com.iterableapi">
3+
<uses-sdk tools:overrideLibrary="br.com.concretesolutions.kappuccino,android_libs.ub_uiautomator,androidx.security"/>
54
</manifest>

app/src/main/AndroidManifest.xml

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:tools="http://schemas.android.com/tools"
34
package="com.iterable.iterableapi.testapp">
4-
5+
<uses-sdk tools:overrideLibrary="androidx.security"/>
56
<application
67
android:allowBackup="true"
78
android:icon="@mipmap/ic_launcher"
@@ -14,10 +15,8 @@
1415
android:theme="@style/AppTheme.NoActionBar">
1516
<intent-filter>
1617
<action android:name="android.intent.action.MAIN" />
17-
1818
<category android:name="android.intent.category.LAUNCHER" />
1919
</intent-filter>
2020
</activity>
2121
</application>
22-
23-
</manifest>
22+
</manifest>

iterableapi-ui/build.gradle

+3-2
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ ext {
4848
siteUrl = 'https://github.com/Iterable/iterable-android-sdk'
4949
gitUrl = 'https://github.com/Iterable/iterable-android-sdk.git'
5050

51-
libraryVersion = '3.4.9'
51+
libraryVersion = '3.4.17'
5252

5353
developerId = 'davidtruong'
5454
developerName = 'David Truong'
@@ -60,7 +60,8 @@ ext {
6060
}
6161

6262
apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
63-
if(hasProperty("mavenPublishEnabled")) {
63+
64+
if (hasProperty("mavenPublishEnabled")) {
6465
apply from: '../maven-push.gradle'
6566
}
6667

iterableapi-ui/src/main/AndroidManifest.xml

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2+
xmlns:tools="http://schemas.android.com/tools"
23
package="com.iterable.iterableapi.ui">
4+
<uses-sdk tools:overrideLibrary="androidx.security"/>
35
<application>
46
<activity
57
android:name=".inbox.IterableInboxActivity"

iterableapi-ui/src/main/java/com/iterable/iterableapi/ui/inbox/IterableInboxFragment.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ public void onListItemTapped(@NonNull IterableInAppMessage message) {
255255

256256
@Override
257257
public void onListItemDeleted(@NonNull IterableInAppMessage message, @NonNull IterableInAppDeleteActionType source) {
258-
IterableApi.getInstance().getInAppManager().removeMessage(message, source, IterableInAppLocation.INBOX);
258+
IterableApi.getInstance().getInAppManager().removeMessage(message, source, IterableInAppLocation.INBOX, null, null);
259259
}
260260

261261
@Override

iterableapi/build.gradle

+14-3
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,20 @@ android {
77
compileSdkVersion 29
88
buildToolsVersion '29.0.3'
99

10+
compileOptions {
11+
sourceCompatibility 1.8
12+
targetCompatibility 1.8
13+
}
14+
1015
defaultConfig {
1116
minSdkVersion 16
1217
targetSdkVersion 27
1318

14-
buildConfigField "String", "ITERABLE_SDK_VERSION", "\"3.4.9\""
19+
buildConfigField "String", "ITERABLE_SDK_VERSION", "\"3.4.17\""
1520

1621
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1722
}
23+
1824
buildTypes {
1925
release {
2026
minifyEnabled false
@@ -25,11 +31,13 @@ android {
2531
multiDexEnabled true
2632
}
2733
}
34+
2835
testOptions.unitTests.all {
2936
testLogging {
3037
exceptionFormat "full"
3138
}
3239
}
40+
3341
testOptions.unitTests.includeAndroidResources = true
3442
}
3543

@@ -39,6 +47,7 @@ dependencies {
3947
api 'androidx.appcompat:appcompat:1.0.0'
4048
api 'androidx.annotation:annotation:1.0.0'
4149
api 'com.google.firebase:firebase-messaging:20.3.0'
50+
implementation "androidx.security:security-crypto:1.1.0-alpha06"
4251

4352
testImplementation 'junit:junit:4.12'
4453
testImplementation 'androidx.test:runner:1.3.0'
@@ -73,7 +82,7 @@ ext {
7382
siteUrl = 'https://github.com/Iterable/iterable-android-sdk'
7483
gitUrl = 'https://github.com/Iterable/iterable-android-sdk.git'
7584

76-
libraryVersion = '3.4.9'
85+
libraryVersion = '3.4.17'
7786

7887
developerId = 'davidtruong'
7988
developerName = 'David Truong'
@@ -85,12 +94,14 @@ ext {
8594
}
8695

8796
apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
88-
if(hasProperty("mavenPublishEnabled")) {
97+
98+
if (hasProperty("mavenPublishEnabled")) {
8999
apply from: '../maven-push.gradle'
90100
}
91101

92102
task javadoc(type: Javadoc) {
93103
source = android.sourceSets.main.java.srcDirs
104+
excludes = ['**/*.kt']
94105
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
95106

96107
exclude '**/*.kt'
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<manifest xmlns:tools="http://schemas.android.com/tools"
3-
xmlns:android="http://schemas.android.com/apk/res/android"
4-
package="iterable.com.iterableapi">
5-
<uses-sdk tools:overrideLibrary="android_libs.ub_uiautomator"/>
2+
<manifest xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android" package="iterable.com.iterableapi">
3+
<uses-sdk tools:overrideLibrary="android_libs.ub_uiautomator,androidx.security"/>
64
<application
75
android:label="IterableAPI"
8-
android:supportsRtl="true"/>
6+
android:supportsRtl="true" />
97
</manifest>

0 commit comments

Comments
 (0)