最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

[基本解决]swift保存程序当前状态和界面

Swift crifan 3912浏览 0评论

要保证 下次app登录后,还是看到之前的状态

至少聊天窗口内的历史消息记录是不变的:

不需要重新从服务器获取

swift restore state

shagedorn/StateRestorationDemo · GitHub

UIStateRestoring in Swift

State Preservation and Restoration – Use Your Loaf

swift store restore state

An Overview of iOS 7 Application State Preservation and Restoration – Techotopia

An iOS 7 State Preservation and Restoration Tutorial – Techotopia

Restoration Classes and UIWebViews – Use Your Loaf

ios restore preservation

此处很是诡异:

一堆的apple的develop的网页都是403禁止打开。。。

https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/PreservingandRestoringState.html

最后是自己在Xcode中代码中输入:

UIViewControllerRestoration

然后搜:

encodeRestorableStateWithCoder

而找到:

// Conform to this protocol if you want your objects to participate in state restoration.
//
// To participate in state restoration, the function registerObjectForStateRestoration must
// be called for the object.
public protocol UIStateRestoring : NSObjectProtocol {
   
    // The parent property is used to scope the restoration identifier path for an object, to
    // disambiguate it from other objects that might be using the same identifier. The parent
    // must be a restorable object or a view controller, else it will be ignored.
    optional public var restorationParent: UIStateRestoring? { get }
   
    // The restoration class specifies a class which is consulted during restoration to find/create
    // the object, rather than trying to look it up implicitly
    optional public var objectRestorationClass: AnyObject.Type? { get }
   
    // Methods to save and restore state for the object. If these aren’t implemented, the object
    // can still be referenced by other objects in state restoration archives, but it won’t
    // save/restore any state of its own.
    optional public func encodeRestorableStateWithCoder(coder: NSCoder)
    optional public func decodeRestorableStateWithCoder(coder: NSCoder)
   
    // applicationFinishedRestoringState is called on all restored objects that implement the method *after* all other object
    // decoding has been done (including the application delegate). This allows an object to complete setup after state
    // restoration, knowing that all objects from the restoration archive have decoded their state.
    optional public func applicationFinishedRestoringState()
}

但是加了UIStateRestoring后,出错:

 Redundant conformance of ‘MainViewController’ to protocol ‘UIStateRestoring’

objective c – iOS 6 Preservation and Restoration without Storyboards – Stack Overflow

目前实现了一个,最最基本的内容的保存和恢复:

现在app的delegate中加上shouldSaveApplicationState和shouldRestoreApplicationState:

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    func application(application: UIApplication, willFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
       
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
       
        self.window?.restorationIdentifier = "JiandaoRootWindow"
}
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
        if gMainNVC != nil {
            self.showMainView()
        }else {
            self.showLoginView()
        }
        self.window!.makeKeyAndVisible()
       
        return true
    }
    func application(application: UIApplication, shouldSaveApplicationState coder: NSCoder) -> Bool {
        return true
    }
    func application(application: UIApplication, shouldRestoreApplicationState coder: NSCoder) -> Bool {
        return true
    }

对应的自己的视图控制器MainViewController中加上UIViewControllerRestoration和UIStateRestoring:

class MainViewController: UITabBarController, UIGestureRecognizerDelegate, UIViewControllerRestoration {
    init(){
。。。        
        super.init(nibName: nil, bundle: nil)
       
        self.restorationIdentifier = String(self.dynamicType)
       
        self.restorationClass = self.dynamicType
    }
    // MARK: – State Restoring
    private let encodeKeyCurrentTeamLabelText = "encodeKeyCurrentTeamLabelText"
   
    override func encodeRestorableStateWithCoder(coder: NSCoder)  {
        super.encodeRestorableStateWithCoder(coder)
        guard isViewLoaded() else {
            /*
            If the view has not been loaded, the app will crash
            upon accessing force-unwrapped outlets
            */
            return
        }
       
        coder.encodeObject(self.currentTeamLabel.text, forKey: encodeKeyCurrentTeamLabelText)
    }
   
    override func decodeRestorableStateWithCoder(coder: NSCoder)  {
        super.decodeRestorableStateWithCoder(coder)
        assert(isViewLoaded(), "We assume the controller is never restored without loading its view first.")
       
        if let currentTeamLabelText = coder.decodeObjectForKey(encodeKeyCurrentTeamLabelText) as? String {
            self.currentTeamLabel.text = currentTeamLabelText
        }
    }
   
    override func applicationFinishedRestoringState() {
        print("MainViewController finished restoring")
    }
   
    // MARK: – UIViewControllerRestoration
   
    class func viewControllerWithRestorationIdentifierPath(identifierComponents: [AnyObject], coder: NSCoder) -> UIViewController? {
        assert(String(self) == (identifierComponents.last as! String), "unexpected restoration path: \(identifierComponents)")
        resetMainVC()
        return gMainVC
    }

效果是:

用Xcode去Run后,正常运行:

之后,再去回到iOS 的主界面:

iOS模拟器用Hardware-》Home(快捷键:Shift+Command+H)

如此就使得:

AppDelegate.swift中的shouldSaveApplicationState被调用:

-》接着调用每个视图控制器中的encodeRestorableStateWithCoder:

然后再去停止程序的运行:

Xcode中点击Stop键

然后重新运行你的程序:

iOS模拟器中点击程序:

此时:

对于登录界面,由于也实现了保存和恢复,所以也可以看到之前的数据了:

之前输入的用户名和密码

-》

然后如果实现了

MainViewController的viewControllerWithRestorationIdentifierPath

则恢复后,就可以看到之前保存的团队的标题了:

-》

然后之后就是更复杂的针对于每个子的ViewController去支持对应的保存和恢复了。。。

转载请注明:在路上 » [基本解决]swift保存程序当前状态和界面

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
84 queries in 0.179 seconds, using 22.11MB memory