2016-05-10 28 views
16

Chúng tôi sẽ chuyển đổi dần dần đơn đăng ký của tôi sang React Native. Và tôi tiếp tục gặp vấn đề với Dependency Injection trong React Native trên iOS.Tiêm phụ thuộc vào các mô-đun Native React

Tôi có một số dịch vụ trong ứng dụng tôi muốn sử dụng trong mô-đun gốc. Hiện tại, chúng được tiêm thông qua Typhoon và mọi thứ hoạt động tốt.

Tuy nhiên, phản ứng bản thân khởi tạo và duy trì bất kỳ mô-đun gốc nào dưới dạng singleton. Điều đó ngăn cản tôi cho phép Typhoon khởi tạo chúng, và vì vậy tôi không thể tiêm phụ thuộc vào chúng.

Có thể làm gì? Tạo RCTBridge bản thân mình là một lựa chọn, nhưng cảm thấy rất thấp cấp, và vẫn cần phải tìm ra cách để tiêm nó vào UIView ở nơi đầu tiên.

Trả lời

10

Tôi không chắc chắn lý do tại sao câu hỏi của bạn không nhận được nhiều phiếu bầu hơn; Bản thân tôi đã đấu tranh để trả lời cùng một câu hỏi và nghĩ rằng tôi nên nhảy lên và trả lời câu hỏi StackOverflow đầu tiên của tôi!

Đào xung quanh RCTBridge class cung cấp câu trả lời. Những gì bạn cần làm là khởi tạo một RCTBridge bằng tay với một thể hiện của một lớp mà thực hiện các RCTBridgeProtocol (và quan trọng là phương pháp 'extraModulesForBridge'; thậm chí bạn có thể thực hiện giao thức này trong View Controller của bạn nếu bạn muốn

// Initialise a class that implements RCTBridgeDelegate 
// Be warned, RCTBridge won't store a strong reference to your delegate. 
// You should there store this delegate as a property of your initialising class, or implement the protocol in the View Controller itself. 
id<RCTBridgeDelegate> moduleInitialiser = [[classThatImplementsRCTBridgeDelegate alloc] init]; 

// Create a RCTBridge instance 
// (you may store this in a static context if you wish to use with other RCTViews you might initialise. 
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:moduleInitialiser launchOptions:nil]; 

// Initialise an RCTRootView 
RCTRootView *rootView = [[RCTRootView alloc] 
        initWithBridge:bridge 
         moduleName:kModuleName 
        initialProperties:nil]; 

// Note that your class that implements RCTBridgeDelegate SHOULD implement the following methods and it might look something like this. 

// This will return the location of our Bundle 
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 
{ 
    return [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios"]; 
} 

// Importantly, this is the method we need to implement to answer this question 
// We must return an array of initialised Modules 
// Be warned, I am writing this off of the top of my head, so excuse any syntax errors there might be! 
- (NSArray *)extraModulesForBridge:(RCTBridge *)bridge 
{ 
    return @[[OurNativeModule alloc] initWithCustomInitialiser:customDependency]]; 
} 
.

Edit: tôi thêm này vào tài liệu Phản ứng bản địa https://facebook.github.io/react-native/docs/native-modules-ios.html#dependency-injection

+0

Tôi thực sự khám phá này trên của riêng tôi, nhưng không thể tìm thấy một cách tốt để tạo RCTModules (Tôi nghĩ đó là RCTModule, đó là một thời gian trước) trong khi sử dụng Swift, vì toàn bộ ứng dụng của chúng tôi là Swift Dựa . Tuy nhiên, tôi có thể xem lại điều này và chỉ sử dụng mục tiêu C cho hệ thống ống nước và viết mô-đun gốc thực tế nhanh chóng. Bạn có làm cho nó hoạt động không? – Rubys

+0

Có khả năng thay thế các mô-đun gốc chuẩn như DatePickerIOS bằng cách triển khai của riêng tôi, sử dụng một cái gì đó như API riêng để thay đổi màu sắc của bộ chọn không? – pinguinjkeke

2

Đoạn mã trên chỉ hoạt động tốt Dưới đây là phiên bản Swift 4 của mã

@objc(RNModuleInitialiser) 
final class RNModuleInitialiser: NSObject { 

    //Inject your dependencies here 
    init() { 

    } 

} 

extension RNModuleInitialiser: RCTBridgeDelegate { 

    func sourceURL(for bridge: RCTBridge!) -> URL! { 
     return URL(string: "http://localhost:8081/index.ios.bundle?platform=ios")! 
    } 

    func extraModules(for bridge: RCTBridge!) -> [RCTBridgeModule]! { 

     var extraModules = [RCTBridgeModule]() 

     //Initialise the modules here using the dependencies injected above 

     return extraModules 
    } 

} 

Khi khởi tạo cầu, vượt qua m... oduleInitialiser:

//Make sure to hold the strong reference to the moduleInitaliser 

self.moduleInitialiser = RNModuleInitialiser() 
self.bridge = RCTBridge(delegate: self.moduleInitialiser, launchOptions: nil) 
Các vấn đề liên quan