美文网首页
iOS原生项目集成 React Native 一 路由

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

作者: weithl | 来源:发表于2018-02-15 08:44 被阅读165次

    集成 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 一 导航

    相关文章

      网友评论

          本文标题:iOS原生项目集成 React Native 一 路由

          本文链接:https://www.haomeiwen.com/subject/xywytftx.html