Skip to content

Commit

Permalink
Release 8.1.0 (#231)
Browse files Browse the repository at this point in the history
* Now exposing new APIs

* Updated to include privacy manifest in sample Xcode project

* Fixed linting errors
  • Loading branch information
mapierce authored Nov 4, 2024
1 parent 1b2a448 commit f85d913
Show file tree
Hide file tree
Showing 13 changed files with 164 additions and 14 deletions.
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,5 @@ dependencies {
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+" // From node_modules
implementation "com.google.firebase:firebase-messaging:${safeExtGet('firebaseMessagingVersion', '20.2.+')}"
implementation 'io.intercom.android:intercom-sdk:15.10.+'
implementation 'io.intercom.android:intercom-sdk:15.11.+'
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableMapKeySetIterator;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;

import java.util.ArrayList;
import java.util.Date;
Expand All @@ -16,6 +18,7 @@
import io.intercom.android.sdk.Company;
import io.intercom.android.sdk.Intercom;
import io.intercom.android.sdk.UserAttributes;
import io.intercom.android.sdk.identity.Registration;

public class IntercomHelpers {

Expand Down Expand Up @@ -241,4 +244,15 @@ public static String getValueAsStringForKey(ReadableMap map, String key) {
}
return value;
}

public static WritableMap deconstructRegistration(Registration registration) {
WritableMap registrationMap = Arguments.createMap();
if (registration.getEmail() != null) {
registrationMap.putString("email", registration.getEmail());
}
if (registration.getUserId() != null) {
registrationMap.putString("userId", registration.getUserId());
}
return registrationMap;
}
}
11 changes: 11 additions & 0 deletions android/src/main/java/com/intercom/reactnative/IntercomModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,17 @@ public void onFailure(@NonNull IntercomError intercomError) {
});
}

@ReactMethod
public void isUserLoggedIn(Promise promise) {
promise.resolve(Intercom.client().isUserLoggedIn());
}

@ReactMethod
public void fetchLoggedInUserAttributes(Promise promise) {
Registration registration = Intercom.client().fetchLoggedInUserAttributes();
promise.resolve(IntercomHelpers.deconstructRegistration(registration));
}

@ReactMethod
public void logout(Promise promise) {
try {
Expand Down
15 changes: 10 additions & 5 deletions example/ios/IntercomReactNativeExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
7D95B168267240E3008096E0 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
7D95B169267240E3008096E0 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
DE090379E5BDFCC31EBBB1FC /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = D19CD0A976BD44CB326047B6 /* PrivacyInfo.xcprivacy */; };
DE090379E5BDFCC31EBBB1FC /* BuildFile in Resources */ = {isa = PBXBuildFile; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand Down Expand Up @@ -75,7 +75,6 @@
13B07FB61A68108700A75B9A /* Info.plist */,
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */,
13B07FB71A68108700A75B9A /* main.m */,
D19CD0A976BD44CB326047B6 /* PrivacyInfo.xcprivacy */,
);
name = IntercomReactNativeExample;
sourceTree = "<group>";
Expand Down Expand Up @@ -223,7 +222,7 @@
files = (
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */,
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
DE090379E5BDFCC31EBBB1FC /* PrivacyInfo.xcprivacy in Resources */,
DE090379E5BDFCC31EBBB1FC /* BuildFile in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -646,7 +645,10 @@
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = "$(inherited)";
OTHER_CPLUSPLUSFLAGS = "$(inherited)";
OTHER_LDFLAGS = "$(inherited) ";
OTHER_LDFLAGS = (
"$(inherited)",
" ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
USE_HERMES = false;
Expand Down Expand Up @@ -712,7 +714,10 @@
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_CFLAGS = "$(inherited)";
OTHER_CPLUSPLUSFLAGS = "$(inherited)";
OTHER_LDFLAGS = "$(inherited) ";
OTHER_LDFLAGS = (
"$(inherited)",
" ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
USE_HERMES = false;
Expand Down
12 changes: 6 additions & 6 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ PODS:
- ReactCommon/turbomodule/core (= 0.73.8)
- fmt (6.2.1)
- glog (0.3.5)
- Intercom (18.1.0)
- intercom-react-native (8.0.0):
- Intercom (~> 18.1.0)
- Intercom (18.2.0)
- intercom-react-native (8.1.0):
- Intercom (~> 18.2.0)
- React-Core
- RCT-Folly (2022.05.16.00):
- boost
Expand Down Expand Up @@ -1197,8 +1197,8 @@ SPEC CHECKSUMS:
FBReactNativeSpec: bbe8b686178e5ce03d1d8a356789f211f91f31b8
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
Intercom: b3a7282d46c7a670d805b70430cb929d9473ddb1
intercom-react-native: f4e484301273c2a2ff7c1839eb3c9c2da1c0aa26
Intercom: e6febbddf5cfa4a15629c1d075b01a9825a23ad9
intercom-react-native: 2f0b89429e93befa1180dde37fc7d8916b762157
RCT-Folly: 7169b2b1c44399c76a47b5deaaba715eeeb476c0
RCTRequired: 0c7f03a41ee32dec802c74c341e317a4165973d5
RCTTypeSafety: 57698bb7fcde424922e201dab377f496a08a63e3
Expand Down Expand Up @@ -1247,4 +1247,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: 15fb131f3e1a2b2d9a606515df1414680c8e67b5

COCOAPODS: 1.12.1
COCOAPODS: 1.15.2
37 changes: 37 additions & 0 deletions example/ios/PrivacyInfo.xcprivacy
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>35F9.1</string>
</array>
</dict>
</array>
<key>NSPrivacyCollectedDataTypes</key>
<array/>
<key>NSPrivacyTracking</key>
<false/>
</dict>
</plist>
28 changes: 28 additions & 0 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ export default function App() {
Alert.alert(field, `Provided ${field} is not of correct format`);
};

const showLoggedInStatusAlert = () => {
Intercom.isUserLoggedIn().then((res) => {
Alert.alert(`Logged in status: ${res ? 'Yes' : 'No'}`);
});
};

const showLoggedInUserAttributes = () => {
Intercom.fetchLoggedInUserAttributes().then((res) => {
Alert.alert('User Attributes', JSON.stringify(res));
});
};

const validateEmail = (email: string | undefined) => {
return String(email)
.toLowerCase()
Expand Down Expand Up @@ -295,6 +307,22 @@ export default function App() {
});
}}
/>
<Button
intercom_accessibilityLabel="show-logged-in-status"
intercom_title="Show logged in status"
intercom_onPress={() => {
showLoggedInStatusAlert();
}}
/>
<Button
intercom_accessibilityLabel="show-logged-in-attributes"
// intercom_disabled={!loggedUser}
intercom_title="Show logged in attributes"
intercom_onPress={() => {
showLoggedInUserAttributes();
}}
/>

<Input
title="Conversation Id"
accessibilityLabel="conversation-id"
Expand Down
2 changes: 1 addition & 1 deletion intercom-react-native.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ Pod::Spec.new do |s|
s.resource_bundles = { 'IntercomFramework' => ['ios/assets/*'] }

s.dependency "React-Core"
s.dependency "Intercom", '~> 18.1.0'
s.dependency "Intercom", '~> 18.2.0'
end
1 change: 1 addition & 0 deletions ios/IntercomAttributesBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@

@interface IntercomAttributesBuilder : NSObject
+ (ICMUserAttributes *)userAttributesForDictionary:(NSDictionary *)attributesDict;
+ (NSMutableDictionary *)dictionaryForUserAttributes:(ICMUserAttributes *)attributes;
@end
29 changes: 29 additions & 0 deletions ios/IntercomAttributesBuilder.m
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,35 @@ + (ICMUserAttributes *)userAttributesForDictionary:(NSDictionary *)attributesDic
return attributes;
}

+ (NSMutableDictionary *)dictionaryForUserAttributes:(ICMUserAttributes *)attributes {
NSMutableDictionary *attributesDict = [NSMutableDictionary new];
if (attributes.email) {
attributesDict[@"email"] = attributes.email;
}
if (attributes.userId) {
attributesDict[@"userId"] = attributes.userId;
}
if (attributes.name) {
attributesDict[@"name"] = attributes.name;
}
if (attributes.phone) {
attributesDict[@"phone"] = attributes.phone;
}
if (attributes.languageOverride) {
attributesDict[@"languageOverride"] = attributes.languageOverride;
}
if (attributes.signedUpAt) {
attributesDict[@"signedUpAt"] = @([attributes.signedUpAt timeIntervalSince1970]);
}
if (attributes.unsubscribedFromEmails) {
attributesDict[@"unsubscribedFromEmails"] = @(attributes.unsubscribedFromEmails);
}
if (attributes.customAttributes) {
attributesDict[@"customAttributes"] = attributes.customAttributes;
}
return attributesDict;
}

+ (ICMCompany *)companyForDictionary:(NSDictionary *)attributesDict {
ICMCompany *company = [ICMCompany new];
if ([self stringValueForKey:@"id" inDictionary:attributesDict]) {
Expand Down
10 changes: 10 additions & 0 deletions ios/IntercomModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,16 @@ - (NSData *)dataFromHexString:(NSString *)string {
}];
};

RCT_EXPORT_METHOD(isUserLoggedIn:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
BOOL loggedIn = [Intercom isUserLoggedIn];
resolve(@(loggedIn));
};

RCT_EXPORT_METHOD(fetchLoggedInUserAttributes:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
ICMUserAttributes *attributes = [Intercom fetchLoggedInUserAttributes];
resolve([IntercomAttributesBuilder dictionaryForUserAttributes:attributes]);
};

RCT_EXPORT_METHOD(setUserHash:(NSString *)userHash
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@intercom/intercom-react-native",
"version": "8.0.0",
"version": "8.1.0",
"description": "React Native wrapper to bridge our iOS and Android SDK",
"main": "lib/commonjs/index",
"module": "lib/module/index",
Expand Down
15 changes: 15 additions & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,18 @@ export type IntercomType = {
*/
updateUser(userAttributes: UserAttributes): Promise<boolean>;

/**
* Determines if there is currently a user logged in.
*/
isUserLoggedIn(): Promise<boolean>;

/**
* Gets a logged in user's attributes
*
* @return {Promise<UserAttributes>} A promise to the user's attributes with `email`and/or `userId` populated..
*/
fetchLoggedInUserAttributes: () => Promise<UserAttributes>;

/**
* Log an event with a given name and metaData.
* You can log events in Intercom based on user actions in your app.
Expand Down Expand Up @@ -292,6 +304,9 @@ const Intercom: IntercomType = {
logout: () => IntercomModule.logout(),
setUserHash: (hash) => IntercomModule.setUserHash(hash),
updateUser: (userAttributes) => IntercomModule.updateUser(userAttributes),
isUserLoggedIn: () => IntercomModule.isUserLoggedIn(),
fetchLoggedInUserAttributes: () =>
IntercomModule.fetchLoggedInUserAttributes(),
logEvent: (eventName, metaData = undefined) =>
IntercomModule.logEvent(eventName, metaData),

Expand Down

0 comments on commit f85d913

Please sign in to comment.