iOS原生项目集成 React Native 一 路由

2018-02-15  本文已影响165人  weithl

集成 RN 的目的

团队考虑集成 RN 主要是为了代码热更新。

相对于原生开发,使用 RN,初期成本可能会有些高。

如果团队人员足够,而且不存在审核方面的问题,不建议在现有项目里面集成 RN。

存在的问题

由于项目已使用原生代码开发了完整的功能,集成 RN 大多是新模块的开发,所以就涉及到原生与 RN 间相互跳转传参。RN 模块自身使用 StackNavigator 可以很好的进行导航管理;Native 跳转 RN,主要是提供 View Controller 作为容器,承载 RCTRootView;关键在于RN 跳转 Native,不可能对每一个对应的跳转都写一次 Bridge 方法。考虑到这里,就想到了路由。以路由的方式,可以方便的对项目进行解耦,统一处理 Native 与 RN 间的跳转。
Demo中选用了 JLRoutes 方案。

集成步骤

1、定义跳转协议

plist 中加入下列代码

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>CCDemo</string>
        </array>
    </dict>
</array>    

这里,使用 CCDemo 作为协议,使用 CCDemo:// 就可以跳转到应用内了。

2、定义跳转规则

这里新建一个 RouterManager 统一处理 router 相关。这里也建议大家这样做,如果以后要修改或新增跳转协议类型(多Target),会简单得多。

CCRouterManager

- (void)setupRouterRule {
    /// vc from code 
    [[JLRoutes globalRoutes] addRoute:@"/NavPush/:controller" handler:^BOOL(NSDictionary<NSString *,NSString *> * _Nonnull parameters) {
        UIViewController *v = [[NSClassFromString(parameters[@"controller"]) alloc] init];
        [self paramToVc:v param:parameters];
        [[AppDelegate sharedDelegate].currentVC pushViewController:v animated:YES];
        return YES;
    }];
}

- (void)paramToVc:(UIViewController *) v param:(NSDictionary<NSString *,NSString *> *)parameters {
    unsigned int outCount = 0;
    objc_property_t * properties = class_copyPropertyList(v.class , &outCount);
    for (int i = 0; i < outCount; i++) {
        objc_property_t property = properties[i];
        NSString *key = [NSString stringWithUTF8String:property_getName(property)];
        NSString *param = parameters[key];
        if (param != nil) {
            [v setValue:param forKey:key];
        }
    }
}

这里只实现了从代码中加载 VC,从 Xib 或 StoryBoard 加载可以自行实现。

AppDelegate

static AppDelegate *sInstance = nil;

+ (instancetype)sharedDelegate {
    if (sInstance == nil) {
        sInstance = [[AppDelegate alloc] init];
    }
    return sInstance;
}

- (id)init {
    if (self = [super init]) {
        sInstance = self;
    }
    return self;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    [[CCRouterManager sharedInstance] setupRouterRule];
    
    return YES;
}

- (UINavigationController *)currentVC
{
    return (UINavigationController *)self.window.rootViewController;
}

3、handle url

AppDelegate 中加入如下代码

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
    if ([url.absoluteString containsString:@"CCDemo://"]) {
        return [[CCRouterManager sharedInstance] canRouteURL:url];
    }
    return  YES;
}

到这里,router 部分就完成了,现在可以通过

NSDictionary *para = @{
                           @"labelText" : @"CCOneController-labelText",
                           };
[[CCRouterManager sharedInstance] pushToVC:@"CCOneController" paramters:para];

来实现跳转了。
demo 地址 tag: router

与原生页面相互跳转见下节 iOS原生项目集成 React Native 一 导航

上一篇下一篇

猜你喜欢

热点阅读