一.产品介绍
BBS是一个论坛SDK项目,用户通过简单的几句代码就可以集成整个论坛模块.项目通过模块化开发,多个模块功能分离,用户可以选择需要的模块进行集成.
BBS的整体结构如下图所示:
BBS由三大核心模块组成:MOBFondation.framework,BBSSDK.framework,BBSSDKUI.framework.
MOBFondation.framework是公有framework,里面封装了一系列通用的功能模块,比如获取设备信息,加解密,Native和js的桥接,网络处理,数据解析......
BBSSDK.framework是数据framework,内部封装了所有数据接口.BBSSDK.framework可以独立作为SDK进行使用,只需要自己写UI,调用BBSSDK.framework,就能够实现论坛项目的开发.不过由于BBSSDK.framework引用了MOBFondation.framework,所以在使用BBSSDK.framework时,需要添加MOBFondation.framework.
BBSSDKUI.framework是对界面的封装,它以BBSSDK.framework为接口,穿插MOBFondation.framework的使用,包装成一个完整的论坛UI模块,开发者集成这个framework,可以通过简单的几句代码实现BBS的接入.
ShareSDK和MobLink通过弱引用的方式实现了BBSSDKUI的拓展,通过ShareSDK实现了对分享功能的支持,通过MobLink实现了对网页跳转App的支持.对于如何实现的弱引用,下文会有涉及.
BBSSDKUI分为简约版和时尚版两个版本,各自的主界面如下图所示:
这两个版本除了展示效果的不同,功能完全一致.简约版注重UI的简洁,界面清晰利落.时尚版追求UI的炫酷,里面实现了很多毛玻璃,动画等效果.具体选择哪个版本,依据不同业务需求而定.
主界面展示了论坛和门户两大模块.这两个模块实现不同业务功能,但并不一定全部展示.展示哪个模块由后台决定,用户可以通过后台进行手动配置.
我们看一下BBSSDKUI的功能结构:
四.源码解读
开屏策略提供了全局必要配置,通过调用如下接口实现
```
/**获取全局配置@param result回调*/+ (void)getGlobalSettings:(void(^)(NSDictionary*settings,NSError*error))result;
```
由于开屏策略必须在调用其他接口之前完成,所以这里使用了信号量进行控制: 在时尚版的BBSUIHomeViewController里,
```
self.semaphore = dispatch_semaphore_create(0);self.queue= dispatch_queue_create("HomeViewControllerQueue", DISPATCH_QUEUE_SERIAL); dispatch_async(_queue, ^{//阻塞线程,直到获取配置信息完成之后dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER); });[BBSSDK getGlobalSettings:^(NSDictionary *settings, NSError *error) {if(!error && settings) {......dispatch_semaphore_signal(self.semaphore); } }];
```
主界面上滑左右滑效果
在时尚版的主页以及时尚版的个人中心,我们从上面的图中可以看到,tableView可以左右滑动,也可以上下滑动.当TableView左右滑动的时候,其"header"不会跟着滑动,而当TableView上下滑动的时候,其"header"会跟着滑动.这种效果是怎么实现的呢?
我们先看看这种效果的UI结构:
可见,UI大致是通过上下两个ScrollView实现的.最外层的ScrollView用来切换各个子视图(TableView).内层的ScrollView(即TableView)上下滑动.表头其实是一个UIView,通过监听TableView的contentOffSet,对表头进行Frame设置.
```
BBSUIPortalViewController:/**这里通过封装将TableView的实现集成到BBSUIThreadListViewController里,通过block的方式拿到contentOffSet */for(BBSPortalCatefories *obj inself.categoriesList) {BBSUIThreadListViewController *vc = [[BBSUIThreadListViewController alloc] initWithCatid:obj.catid allowcomment:obj.allowcomment];vc.viewType =BBSUIThreadListViewTypePortal;[vcsaddObject:vc];[titlesaddObject:obj.catname];vc.offSetBlock = ^(CGFloat offSet){ // NSLog(@"============== %f",offSet);[self setContentOffSet:offSet];};vc.refreshBannerBlock = ^(NSArray *bannnerList, NSError *error) { [self _refreshBannerWithBannnerList:bannnerList error:error];};}
```
```
/**进行表头Frame的处理*/- (void)setContentOffSet:(CGFloat)offSet{CGRectframe =self.headerView.frame; frame.origin.y = -offSet + _iphoneXTopPadding;self.headerView.frame = frame; _lastTableViewOffsetY = offSet;//考虑到segmentBar,在到达navigationbar位置的时候,segmentBar需要"悬停"if(offSet <=245-64) {CGRectsegmentFrame =self.segmentControl.frame; segmentFrame.origin.y =245-offSet + _iphoneXTopPadding;self.segmentControl.frame = segmentFrame; }else{CGRectsegmentFrame =self.segmentControl.frame; segmentFrame.origin.y =64+ _iphoneXTopPadding;self.segmentControl.frame = segmentFrame; }if(self.offSetBlock) {self.offSetBlock(offSet); }}
```
弱引用的实现
BBSSDKUI对ShareSDK和MobLink采取弱引用的集成方式.在集成BBSSDKUI.framework的时候,即使不添加ShareSDK和MobLink这两个模块,也不会报错,只不过相关的功能不能使用而已.这和对BBSSDK.framework和MOBFondation.framework的强依赖是不一样的.
怎么实现的呢?
在项目初始化的时候,MOBFondation会通过hock的方式拿到所有的类名,在使用这个SDK的时候,通过协议的方式间接拿到这个类,然后通过私有方法进行调用.
```
- (void)_authLoginWithType:(NSInteger)type{ ......NSArray*components = [[MOBFComponentManager defaultManager] getComponents:@protocol(IMOBFShareComponent)];if(components.count >0) {id ShareComponent = components[0];if(ShareComponent && [ShareComponent conformsToProtocol:@protocol(IMOBFShareComponent)]){ [SVProgressHUD show]; [ShareComponent authorize:authType settings:nilonStateChanged:^(NSIntegerstate,id user,NSError*error) { ...... }]; } }else{NSLog(@"没有接入ShareSdk"); }}
```
这种方式避免了强依赖导致的高耦合,在接入过程中,可以选择性的接入需要的组件,不需要的组件可以不接入,但也不会报错.
网友评论