Swift项目和oc混编-命名空间问题

本文结合本人项目遭遇所得

新项目是swift写的,新东西用了真的戒不掉,只是和oc混编最为致命。。。

举个栗子

我们项目中因为用到了第三方的IM服务(市面上基本上所有第三方IM服务提供的库和代码也都是oc的),坑就这么来了,以下是情景:

NSString *contentStr = [layoutConfig cellContent:self.model]; // 获得类名字符串
Class clazz = NSClassFromString(contentStr); // 字符串转Class
NIMSessionMessageContentView *contentView =  [[clazz alloc] initSessionMessageContentView];
NSAssert(contentView, @"can not init content view");
复制代码

解读一下,这段IM-UI库代码的作用是用model中的字符串创建contentView的类。

例如:IM-UI库中中的OC类NIMSessionLocationContentView.h,则 contentStr = @"NIMSessionLocationContentView"然后得到对应的clazz为NIMSessionLocationContentView.

因为是Swift项目,以及自定义contentView类,所以便有了我们项目的Swift文件的ContentView -> CDNetCallTipContentView。那么问题来了,contentStr = @"CDNetCallTipContentView"没毛病,但是clazz却为nil

后面查到,这种混编情况要指明命名空间!命名空间为自己项目的Target名。例如Target是CDApp。则OC文件中正确获得CDNetCallTipContentView的方式是`contentStr = @"CDApp.CDNetCallTipContentView"。

但是问题还没有完全解决!

很多朋友因为需要,项目存在多个Target(区分开发版本或者环境等原因)。例如原Target是CDApp,开发环境的CDApp Dev。开发环境的Target名中间有空格,这时候如果contentStr = @"CDApp Dev.CDNetCallTipContentView",最后clazz却是nil。问题就出在空格上,要把空格替换成单下划线_contentStr = @"CDApp_Dev.CDNetCallTipContentView"

以下是修改后的代码:

NSString *contentStr = [layoutConfig cellContent:self.model];
Class clazz = NSClassFromString(contentStr);
if (!clazz){
    NSString * nameSpace = [NSBundle mainBundle].infoDictionary[@"CFBundleName"];
    contentStr = [[NSString stringWithFormat:@"%@.%@",nameSpace,contentStr] stringByReplacingOccurrencesOfString:@" " withString:@"_"]; // 空格要换成下划线
    clazz = NSClassFromString(contentStr);
}
NIMSessionMessageContentView *contentView =  [[clazz alloc] initSessionMessageContentView];
NSAssert(contentView, @"can not init content view");
复制代码

转载于:https://juejin.im/post/5a5862e46fb9a01c9950beaa

你可能感兴趣的:(swift)