- app刚刚启动的时候,要去选择他的根控制器,这是每个app必须思考处理的问题,launch的基本事情是这样的,1,2,3,(4一会在讨论)
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
//1创建
window = UIWindow()
window?.frame = UIScreen.mainScreen().bounds
//2设置根目录,WXMainController
window?.rootViewController = defaultRootController() //一个获取默认控制器的方法,在本类中
//3设置可视化
window?.makeKeyAndVisible()
//4注册监听通知
WXNotificationCenter.addObserver(self, selector: "updateRootViewController:", name: WXChangeRootViewControllerNotification, object: nil)
return true
}
但是具体如何选择默认控制器那?我们那微博举例,就是主控制器(要区分是否登录),欢迎控制器,新特性控制器
ps:注意,已登录,和未登录页面我用的是同一个控制器,只不过是调用这个控制器的时候,重写了load方法,去判断一下是否登录,然后去加载不同的页面
//loadView
override func loadView() {
let usr = WXUser.fetchUserInfo()
userLogin ? super.loadView() : setupVisitorView()
}
- 那么如何去判断到底如何跳转那,其实基本的app的跳转不外乎这几种
在appDelegate类中,可以添加一个方法,专门去判断的默认控制器(如果你认为不好,可以专门提取,做一个工具栏,用来判断)
/**
返回默认的根控制器
:returns: 跟控制器
*/
private func defaultRootController() -> UIViewController{
//判断是否登录
if WXUser.isLogin() //登录了
{
//判断是不是新的版本
return isNewUpdateVersion() ? WXNewFeatureController() : WXWelcomeController()
}else{//没有登录
return WXMainController()
}
}
判断是不是新的版本
/**
判断是不是新的版本
:returns: 是或者不是新版本
*/
private func isNewUpdateVersion() -> Bool{
/**
* 如果是给公司开发些项目,我们比较版本号的规则是:1.冲网络上获取版本号,2.通过键“shortString”来获取该版本号,然后比较,基本不用保存到本地
但是微博等项目,我们比较的方法确不同:1.通过“shortString”获取该版本号,2.冲本地获取保存的版本号
*/
//1.通过“shortString”获取该版本号
let currentVersion = NSBundle.mainBundle().infoDictionary!["CFBundleShortVersionString"] as! String
//2.本地获取版本
let saveVersion = NSUserDefaults.standardUserDefaults().objectForKey("BundleVersionString") as? String ?? ""
//3.比较连个版本
if currentVersion.compare(saveVersion) == NSComparisonResult.OrderedDescending
{
//4.保存新的版本号
NSUserDefaults.standardUserDefaults().setObject(currentVersion, forKey: "BundleVersionString")
return true
}
return false
}
说明几点:
- 这里要说苹果一个很牛逼的方法,及时compare这个,返回的数据都是字符串,1.2.3和空字符串能比较,也可以和1.5比较,太神奇了,
2.NSUserDefaults.standardUserDefaults().objectForKey("BundleVersionString") as? String ?? ""的作用:就是as前边的如果是nil,那么就给他as后边的“”,当然你也可以给他别的~
3.如果在欢迎Vc,或者新版本Vc,最后都要去mainVC,怎么去?
直接使用和这个UIApplication.sharedApplication().keyWindow?.rootViewController = 要选择的控制器
,直接给控制器。
4.真实公司的项目,和微博的项目的比较version的区别请认真看上边的那一大段注释文字
5.文章开始的代码中,为毛要注册通知?当我们要在其他控制器设置根控制的时候,直接给Windows.rootVc 设置值就好了,微博项目就有新特性VC,欢迎VC需要赋值,不多,但是对于大项目,好多地方可以,所以感觉乱乱的代码,不方便同意管理,所以我认为将他放到appDelegate中统一管理就好,那么问题来了,那么远,怎么管理,聪明的同学想到了就是通知!
所以才有了一开始注册通知的代码,既然有注册,就要有移除
- 移除监听
deinit{
WXNotificationCenter.removeObserver(self, name: WXChangeRootViewControllerNotification, object: nil)
}
- 接收通知相应的事件
/**
当接收通知的时候,用来去更新rootViewcontroller
ps:接收通知的时候,调用的方法,千万不要去用private修饰,有问题
:param: notifi 接收的通知
*/
func updateRootViewController(notifi : NSNotification){
/**
//打印出来的notifi内容
NSConcreteNotification 0x7f9be950f2a0 {name = WXChangeRootViewControllerNotification; object = 1}
*/
let isMainVc = notifi.object as! Bool
if isMainVc == true {
window?.rootViewController = WXMainController()
}else{
window?.rootViewController = WXWelcomeController()
}
}
远处发来幽怨的通知,记住要发true,或者false,我这里是判断去那个页面的
WXNotificationCenter.postNotificationName(WXChangeRootViewControllerNotification, object: true)
- 你问我这个
WXNotificationCenter
,WXChangeRootViewControllerNotification
,这个为毛写的这么好,可以看看我的另一篇文章ios代码规范
最后还要说明一下,就是swift中如何定义常量字符串和宏定义
1.全局的
let WXChangeRootViewControllerNotification = "WXChangeRootViewControllerNotification"
var WXScreenWidth = UIScreen.mainScreen().bounds.size.width
let WXNotificationCenter = NSNotificationCenter.defaultCenter()
2.私有的
private let reuseIdentifier = "Cell"