Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: check if pass already exists in wallet #3

Open
fiznool opened this issue Nov 25, 2021 · 3 comments
Open

feature: check if pass already exists in wallet #3

fiznool opened this issue Nov 25, 2021 · 3 comments

Comments

@fiznool
Copy link

fiznool commented Nov 25, 2021

Hi! 👋

Just wanted to start by saying a huge thank you for taking on this package and modernising it with Typescript. Its really well written, and has almost(!) everything I need for my current project. ❤️

I have the need for an extra feature - checking if a pass already exists in the Wallet, according to the passTypeIdentifier. I used patch-package to patch [email protected] in order to add in this functionality on my current project, which is working nicely.

I've pasted the diff I'm using below, but I would be happy to package this up as a PR, if you feel it would be a useful addition?

diff --git a/android/src/main/java/com/thewirv/RNWalletPasses/RNWalletPassesModule.java b/android/src/main/java/com/thewirv/RNWalletPasses/RNWalletPassesModule.java
index 4ebc427..99f5a5c 100644
--- a/android/src/main/java/com/thewirv/RNWalletPasses/RNWalletPassesModule.java
+++ b/android/src/main/java/com/thewirv/RNWalletPasses/RNWalletPassesModule.java
@@ -62,6 +62,11 @@ public class RNWalletPassesModule extends ReactContextBaseJavaModule {
         }
     }

+    @ReactMethod
+    public void hasPassWithTypeIdentifier(String passTypeIdentifier, Promise promise) {
+        promise.reject(new JSApplicationCausedNativeException("hasPassWithTypeIdentifier is not available on Android"));
+    }
+
     @ReactMethod
     public void addPass(String encodedPassFile, String fileProvider, Promise promise) {
         try {
diff --git a/ios/RNWalletPasses/RNWalletPasses.m b/ios/RNWalletPasses/RNWalletPasses.m
index eba5692..96f1a16 100644
--- a/ios/RNWalletPasses/RNWalletPasses.m
+++ b/ios/RNWalletPasses/RNWalletPasses.m
@@ -22,6 +22,13 @@ RCT_EXPORT_METHOD(canAddPasses:(RCTPromiseResolveBlock)resolve
     resolve(@([PKAddPassesViewController canAddPasses]));
 }

+RCT_EXPORT_METHOD(hasPassWithTypeIdentifier:(NSString *)passTypeIdentifier
+                  resolver:(RCTPromiseResolveBlock)resolve
+                  rejector:(RCTPromiseRejectBlock)reject) {
+
+    resolve(@([self passAlreadyExistsWithTypeIdentifier:passTypeIdentifier]));
+}
+
 RCT_EXPORT_METHOD(addPass:(NSString *)base64Encoded
                   resolver:(RCTPromiseResolveBlock)resolve
                   rejector:(RCTPromiseRejectBlock)reject) {
@@ -34,6 +41,13 @@ RCT_EXPORT_METHOD(addPass:(NSString *)base64Encoded
         return;
     }

+    // Check if pass already exists: if so, don't try to add again
+    PKPassLibrary *passLibrary = [[PKPassLibrary alloc] init];
+    if([passLibrary containsPass:pass]) {
+        resolve(nil);
+        return;
+    }
+
     dispatch_async(dispatch_get_main_queue(), ^{
         UIViewController *rootViewController = [self getPresenterViewController];
         if (rootViewController) {
@@ -103,4 +117,15 @@ RCT_EXPORT_METHOD(addPass:(NSString *)base64Encoded
     return presentingViewcontroller;
 }

+-(BOOL)passAlreadyExistsWithTypeIdentifier:(NSString *)passTypeIdentifier {
+    PKPassLibrary *passLibrary = [[PKPassLibrary alloc] init];
+    NSArray<PKPass *> *existingPasses = [passLibrary passes];
+    for (PKPass *pass in existingPasses) {
+        if([[pass passTypeIdentifier] isEqualToString:passTypeIdentifier]) {
+            return YES;
+        }
+    }
+    return NO;
+}
+
 @end
diff --git a/lib/commonjs/WalletPasses.js b/lib/commonjs/WalletPasses.js
index 52ed261..a428b42 100644
--- a/lib/commonjs/WalletPasses.js
+++ b/lib/commonjs/WalletPasses.js
@@ -24,6 +24,20 @@ const WalletPasses = {
     return new Promise(resolve => resolve(false));
   },

+
+  /**
+   * Checks whether a pass with the provided `passIdentifierType` is already present in the Wallet. iOS only.
+   *
+   * @param passTypeIdentifier Pass type identifier, used to search for an existing pass in the Wallet
+   */
+   hasPassWithTypeIdentifier: (passTypeIdentifier) => {
+    if (_reactNative.Platform.OS === 'ios') {
+      return RNWalletPasses.hasPassWithTypeIdentifier(passTypeIdentifier);
+    }
+
+    return Promise.reject(new Error('Checking that a pass is already added to the Wallet is only supported on iOS.'))
+  },
+
   /**
    * Adds a pass to the Wallet.
    *
diff --git a/lib/module/WalletPasses.js b/lib/module/WalletPasses.js
index 1ccea93..60f9228 100644
--- a/lib/module/WalletPasses.js
+++ b/lib/module/WalletPasses.js
@@ -16,6 +16,19 @@ const WalletPasses = {
     return new Promise(resolve => resolve(false));
   },

+  /**
+   * Checks whether a pass with the provided `passIdentifierType` is already present in the Wallet. iOS only.
+   *
+   * @param passTypeIdentifier Pass type identifier, used to search for an existing pass in the Wallet
+   */
+   hasPassWithTypeIdentifier: (passTypeIdentifier) => {
+    if (Platform.OS === 'ios') {
+      return RNWalletPasses.hasPassWithTypeIdentifier(passTypeIdentifier);
+    }
+
+    return Promise.reject(new Error('Checking that a pass is already added to the Wallet is only supported on iOS.'))
+  },
+
   /**
    * Adds a pass to the Wallet.
    *
diff --git a/lib/typescript/WalletPasses.d.ts b/lib/typescript/WalletPasses.d.ts
index 3b16f78..2547c66 100644
--- a/lib/typescript/WalletPasses.d.ts
+++ b/lib/typescript/WalletPasses.d.ts
@@ -3,6 +3,12 @@ declare const WalletPasses: {
      * Checks whether Wallet passes can be added on this device.
      */
     canAddPasses: () => Promise<boolean>;
+    /**
+     * Checks whether a pass with the provided `passIdentifierType` is already present in the Wallet. iOS only.
+     *
+     * @param passTypeIdentifier Pass type identifier, used to search for an existing pass in the Wallet
+     */
+    hasPassWithTypeIdentifier: (passTypeIdentifier: string) => Promise<boolean>;
     /**
      * Adds a pass to the Wallet.
      *
diff --git a/src/WalletPasses.ts b/src/WalletPasses.ts
index 36c3aac..728c2b8 100644
--- a/src/WalletPasses.ts
+++ b/src/WalletPasses.ts
@@ -16,6 +16,19 @@ const WalletPasses = {
     return new Promise((resolve) => resolve(false));
   },

+  /**
+   * Checks whether a pass with the provided `passIdentifierType` is already present in the Wallet. iOS only.
+   *
+   * @param passTypeIdentifier Pass type identifier, used to search for an existing pass in the Wallet
+   */
+   hasPassWithTypeIdentifier: (passTypeIdentifier: string): Promise<boolean> => {
+    if (Platform.OS === 'ios') {
+      return RNWalletPasses.hasPassWithTypeIdentifier(passTypeIdentifier);
+    }
+
+    return Promise.reject(new Error('Checking that a pass is already added to the Wallet is only supported on iOS.'))
+  },
+
   /**
    * Adds a pass to the Wallet.
    *
@pke
Copy link

pke commented Feb 9, 2022

I wouldn't reject if this function is called from Android. Just return false and emit a warning to the console would make the handling of this new API much cleaner.

@labmorales
Copy link

Hey, @fiznool I think this would be a great addition to the plugin. Could you wrap this up in a PR?

@fiznool
Copy link
Author

fiznool commented Oct 13, 2022

Hi @labmorales - I've moved on to another project and sadly don't have the time to create a PR, but if somebody else would like to do so instead, it would be a great addition to the library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants