Comment faire un pont entre la promesse des natifs et Swift

Hi collègues logiciel de passionnés,

je travaille actuellement sur un projet natif React pour lequel j'ai besoin d'ajouter un peu de logique qui a été écrit dans swift. Je suis capable de déclencher une base swift fonction de transition d'Objective-C et Swift.

Le problème survient lorsque j'essaie de faire quelque chose avec des promesses. La page I décrivant ceci est claire sur la partie de L'Objectif C pour les promesses et aussi pour passer à Swift, mais pas sur les promesses à swift: https://facebook.github.io/react-native/docs/native-modules-ios.html

voici ce que j'ai:

Projet-Un Pont-D'En-Tête.h

#import <React/RCTBridgeModule.h>

MyLoginBridge.m

#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>

@interface RCT_EXTERN_REMAP_MODULE(MyCustomLoginJSName, MyLoginModule, NSObject)

RCT_EXTERN_REMAP_METHOD(loginWithEmail,
                    resolver:(RCTPromiseResolveBlock)resolve
                    rejecter:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(testMethod)

@end

MyLoginModule.swift

import Foundation

@objc(TripleASDKModule)
class TripleASDKModule: NSObject {

  @objc
  func loginWithEmail(resolver resolve: RCTPromiseResolveBlock,  rejecter reject: RCTPromiseRejectBlock) -> Void {
    resolve("This method is troublesome")
  }

  @objc func testMethod() -> Void {
    print("This Does appear")
  }
}

lorsque je déclenche la méthode testMethod, L'impression est affichée en Xcode, de sorte que le code swift est exécuté. Mais quand j'appelle la méthode loginWithEmail, je reçois l'infâme rouge Réagir Natif écran d'erreur disant:

Exception 'resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject is not a recognized Objective-C method.' was thrown while invoking loginWithEmail on target MyCustomLoginJSName with params (
    30,
    31
)

Et par souci d'exhaustivité, le Javascript côté:

const loginWithEmail = () => NativeModules.TripleA.loginWithEmail()
    .then(result => console.log(result));

j'ai essayé presque toutes les variantes de RCT_EXTERN_REMAP_METHOD et ce que j'ai pu trouver, à la fois avec et sans Remapper en répétant le nom, etc. Donc si ce problème familier, ou vous pourrait me guider dans la bonne direction, veuillez le faire, toute aide est appréciée.

8
demandé sur Koen. 2017-03-03 14:19:17

3 réponses

extrait des réponses à A "n'est pas reconnu en Objective-C méthode" lors de l'intégration rapide à Réagir Natif; le fait qu'il ne fonctionne pas, est en raison de la différence dans les étiquettes de premier argument.

pour que cela fonctionne avec votre code initial, vous devriez écrire votre méthode Swift comme ceci:

@objc
func loginWithEmail(_ resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) -> Void {
    //   the trick  ^
    resolve("This method is no longer troublesome")
}
6
répondu Koen. 2017-07-01 17:54:20

ajout de façon à ce que la solution complète soit affichée

.m-notez que le paramètre resolve n'est pas"named"

RCT_EXTERN_METHOD(loginWithEmail: (RCTPromiseResolveBlock)resolve
                                  rejecter:(RCTPromiseRejectBlock)reject)

.swift - même comme @Koen

@objc func loginWithEmail(_ resolve: @escaping RCTPromiseResolveBlock,
                            rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void {}
3
répondu pwcremin 2017-08-03 22:19:18

j'ai finalement trouvé une solution. Ce n'est pas exactement comme les Autochtones réagissaient à l'intention je crois, mais cela fonctionne. Donc, je peux continuer et peut-être que quelqu'un d'autre est sur la bonne voie avec ma solution. Bien, merci de poster la façon dont il est censé être.

J'ai donc décidé de commencer par la méthode Objective-C. J'ai donc créé une .fichier h pour mon module.

MyLoginBridge.h

#import <React/RCTBridgeModule.h>

@interface MyLoginBridge : NSObject <RCTBridgeModule>
@end

alors modifiez le .m le fichier

#import "MyLoginBridge.h"
#import "MyProject-Swift.h" // Include the swift header manually

@implementation MyLoginBridge

RCT_EXPORT_MODULE(MyCustomLoginJSName);

RCT_EXPORT_METHOD(loginWithEmail:(RCTPromiseResolveBlock)resolve   rejecter:(RCTPromiseRejectBlock)reject)
{
    // Manually init the module and call swift function
    MyLoginModule* module = [[MyLoginModule alloc] init];
    [module loginWithEmailWithResolver:resolve rejecter:reject];
}

@end

le fichier swift et l'en-tête passerelle sont demeurés les mêmes. Les travaux de cette.

0
répondu stephanmantel 2017-03-03 13:20:59