我想在我的应用程序中进行状态恢复,不使用故事板.我看到我的主要应用程序ViewController在状态恢复期间实例化了两次 - 你如何确保它只创建一次?
就我了解的流动,application:willFinishLaunchingWithOptions
并且pplication:didFinishLaunchingWithOptions
将使用commonInit
这将设置应用程序的UIWindow方法及其RootViewController的.在我的例子中,rootViewController是一个UINavigationController,其中一个名为"MyMainViewController"的类充当UINavigation的rootViewController.
除此之外,我也分别处理willEncodeRestorableStateWithCoder
和处理didDecodeRestorableStateWithCoder
.但似乎到了我的时候didDecodeRestorableStateWithCoder
,我看到MyMainViewController创建了两个独立的实例.
确保在恢复期间只创建一个UIViewController的方法是什么?
恢复期间的呼叫顺序:
这是我在AppDelegate中所做的事情:
NSString * const kRootViewControllerKey = @"RootViewControllerKey";
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self commonInitWithOptions:launchOptions];
return YES;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self commonInitWithOptions:launchOptions];
return YES;
}
- (void)commonInitWithOptions:(NSDictionary *)launchOptions {
static dispatch_once_t predicate;
dispatch_once(&predicate, ^ {
// While this will be called only once during the lifetype of the app, when the process is killed …
Run Code Online (Sandbox Code Playgroud) 我在实例化我的CBCentralManager时遇到了问题.从iOS控制台监控时,我收到"重复问题"消息(它没有显示在XCode控制台中).
我已经尝试更新队列名称和恢复密钥ID但没有成功.这是我实例化我的中央管理器的方式:
CBCentralManager *central = [[CBCentralManager alloc] initWithDelegate: self
queue: dispatch_queue_create("com.mydomain.myapp.scanner", NULL)
options: @{
CBCentralManagerOptionRestoreIdentifierKey: @"hexa-string-comes-here"
}];
Run Code Online (Sandbox Code Playgroud)
这些是我得到的错误:
CKLs-iPhone-5S securityd [78]:securityd_xpc_dictionary_handler MyApp [2571] add操作无法完成.(OSStatus错误-25299 - 重复项目O,genp,E99372E2,L,ck,X2W6M5UYJ9.com.mydomain.myapp,0,acct,svce,v_Data,20151218165347.298588Z,2CAE5650)
CKLs-iPhone-5S MyApp [2571]:SecOSStatusWith错误:[ - 25299]操作无法完成.(OSStatus错误-25299 - 远程错误:操作无法完成.(OSStatus错误-25299 - 重复项目O,genp,E99372E2,L,ck,X2W6M5UYJ9.com.mydomain.myapp,0,acct,svce,v_Data ,20151218165347.298588Z,2CAE5650))
有任何想法吗?
在iOS 6中,Apple将状态恢复添加到UIViewController
相关类中.这允许应用程序在终止时保存状态,并在用户恢复应用程序时将其恢复.
一切似乎都很好,但是我已经达到了一个不想融入模式的奇怪场景.
假设我们有两个视图控制器,ViewControllerOne
并且ViewControllerTwo
它们都存储了一些成功恢复的任意状态.现在让我们假设ViewControllerOne
有一个delegate
属性,那ViewControllerTwo
就是委托(这是模态视图控制器的常见模式).谁负责恢复这种关系?它应该如何存储/恢复?
在我的特定情况下,不涉及故事板,恢复发生在代码中,通过 restorationClass
属性.我的第一直觉是尝试恢复关系,同时在restorationClass中创建视图控制器,但由于restorationClass
不知道其他现有的控制器,它无法完全恢复这种关系.
或者,如果是视图控制器声明delegate
属性,那应该是恢复关系,那么现在如何在其他类中恢复的控制器实例呢?
简而言之,这似乎是一个记录不完整的情景,我希望有人能够对此有所了解.
我的应用程序使用Stanford课程的CoreDataTableViewController,它是UITableViewController的子类.
对于我的应用程序的特定视图,我创建CoreDataTableViewController的子类来管理特定视图.
我刚刚在我的大多数应用程序中连接状态编码和恢复,这一切似乎都正常工作.我唯一留下的就是实现UIDataSourceModelAssociation协议,据称保留UITableViews的可见和选定行(我也希望它可以保留表视图的编辑状态,如果我选择了它,则保留特定行的编辑状态删除,但尚未确认).
我在CoreDataTableViewController中实现了UIDataSourceModelAssociation,希望它能够适用于我的所有视图,但是在调试它时该功能不起作用,并且添加断点我发现当我将我的应用程序放入时,两个UIDataSourceModelAssociation方法都没有被调用使用主页按钮的背景,或通过在XCode中重新运行来恢复它.
CoreDataTableViewController及其子类实现了一些dataSource方法,以实际显示表视图中的行.我四处搜索,发现UITableViewController自动将自己添加为tableView的dataSource.
我在表单的子类viewDidLoad函数中添加了sanity asserts
assert(self.tableView);
assert(self.tableView.dataSource == self); <--- fails here
Run Code Online (Sandbox Code Playgroud)
在检查dataSource是我们自己时失败了.我可以通过记录和使用调试器来看到此时dataSource是非零的.
我想我只是想知道当我们对一个类进行子类化时,每个类是否共享相同的自身值,或者是因为我的UITableViewController将自己设置为dataSource,但是当我将它子类化为两次时,我的特定视图实例它的self与父UITableViewController略有不同.或者是其他东西拦截dataSource并根据需要转发.作为修复,我应该考虑将自己的子类硬编码为self,或者让CoreDataTableViewController将其自身添加为dataSource,因为这是实现UIDataSourceModelAssociation方法的地方.
作为参考我的视图层次结构包含我的UITableViewController子视图生活在NavigationControllers中,我听说可能会导致问题.
稍微清楚一下子类应如何在各类的自指针方面起作用,并想知道是否有人能够弄清楚为什么我的协议方法没有被调用会非常感激.
干杯
状态保存和恢复由于状态保存和恢复被内置于核心蓝牙功能,您的应用程序可以选择加入此功能要求系统保留您的应用程序的中枢和外周管理者的状态,并继续执行某些蓝牙相关的任务,他们的代表,即使你的应用程序不再运行.当其中一个任务完成后,系统会将您的应用重新启动到后台,并为您的应用提供恢复其状态和适当处理事件的机会.在上述的家庭安全应用程序的情况下,系统会监控连接请求,并再次重新启动应用程序来处理centralManager:didConnectPeripheral:委托回调当用户回到家中的连接请求完成.
如何触发此操作并测试代码?
我有一个服务配件.我有一个应用程序扫描服务,我选择了状态保存.但是我不确定如何对它进行逻辑测试,因为我不知道触发它需要什么.这些是我尝试失败的选项:
A - kill the app from Xcode
B - kill the app manually
C - power off the phone
D - something else
Run Code Online (Sandbox Code Playgroud)
在所有这些选项中,我试图转到Xcode - >设备并查看日志,但没有看到任何状态恢复日志.
谢谢
xcode bluetooth ios state-restoration ble-state-preservation
在iOS中,是否可以为UI对象分配字符串ID,然后通过该ID在代码中检索它们?
我正在寻找类似Android的东西 findViewById(id)
在Apple的文档中,他们说如果是基于文档的应用程序,你应该恢复调用(restoreStateWithCoder:和encodeRestorableStateWithCoder :)到NSApplication,NSWindow,NSWindowController,然后是整个响应者链(这里).
我想实现这个,但我只在NSWindowController/NSDocument子类中获得恢复调用,而不是NSViews或NSViewControllers.
我创建了一个新的基于文档的应用程序来测试这个(这里),但我只在NSDocument子类中获得了恢复调用,但是没有NSViewController或NSView.
测试项目的代码:
NSDocument子类(恢复工作):
class Document: NSDocument {
override func restoreState(with coder: NSCoder) {
super.restoreState(with: coder)
// Gets called after reopening the app
}
override func encodeRestorableState(with coder: NSCoder) {
super.encodeRestorableState(with: coder)
// Gets called when leaving the window for the first time
}
}
Run Code Online (Sandbox Code Playgroud)
NSViewController子类(恢复不起作用):
class ViewController: NSViewController {
override func restoreState(with coder: NSCoder) {
super.restoreState(with: coder)
// Not called
}
override func encodeRestorableState(with coder: NSCoder) {
super.encodeRestorableState(with: coder)
// Not called
} …
Run Code Online (Sandbox Code Playgroud) 我从XCode获取这些崩溃报告(我在底部粘贴了一个),我无法重现错误或弄清楚问题是什么.
从回溯中我认为它可能与这些decodeObject
东西有关......我确实遇到了新的decodeBool
和decodeDouble
函数的问题,所以为了确保我做了一个NSCoder扩展:
func safeDecodeDouble(key: String) -> Double? {
if self.containsValue(forKey: key) {
if let value = self.decodeObject(forKey: key) as? Double {
return value
}
return self.decodeDouble(forKey: key)
}
return nil
}
func safeDecodeBool(key: String) -> Bool? {
if self.containsValue(forKey: key) {
if let value = self.decodeObject(forKey: key) as? Bool {
return value
}
return self.decodeBool(forKey: key)
}
return nil
}
func safeDecodeDate(key: String) -> Date? {
if self.containsValue(forKey: key) {
if let value = …
Run Code Online (Sandbox Code Playgroud) 我在我的应用程序中的大多数模态中都采用了新的 iOS 13 模态呈现样式,但是一个导航控制器并不能很好地适应新样式,因此我将其设置为
UIModalPresentationFullScreen
在展示它时效果很好。
我刚刚注意到一个错误,当我的应用程序在 ViewController 上进行状态保存和恢复时,它会在以 UIModalPresentationPageSheet 的 modalPresentationStyle 恢复后以模态呈现。
作为 ViewController 的内置属性,它们的状态恢复是 Apple 的责任,我猜他们只是错过了正确处理它。
谢天谢地,我已经能够通过将以下内容添加到我现有的状态恢复处理中来解决这个问题
- (void)decodeRestorableStateWithCoder:(NSCoder *)aDecoder
{
...
self.navigationController.modalPresentationStyle = UIModalPresentationFullScreen;
}
Run Code Online (Sandbox Code Playgroud)
其他人遇到过这个问题或有其他解决方案吗?
干杯
我只是想在我的一个应用程序中实现iOS State-Restoration API.在最终实现它之后,我发现我以模态方式呈现的ViewController使用动画来恢复,这不是我想要的.我希望我的应用程序只是处于我离开它的状态,但没有让用户看到他到达那里的热点.
所以我继续下载Apple示例代码:https://developer.apple.com/library/ios/samplecode/StateRestore/Introduction/Intro.html并想看看它是否也在那里发生.事实证明它确实如此.
此外,日志中还有一个警告:
Unbalanced calls to begin/end appearance transitions for <UINavigationController: 0x7b0512b0>.
Run Code Online (Sandbox Code Playgroud)
你能否告诉我,我和Apples示例代码是否做错了,或者是否是iOS中的错误?
顺便说一句.我在iOS8上测试
感谢任何帮助,乔治
ios ×8
bluetooth ×2
swift ×2
datasource ×1
duplicates ×1
findviewbyid ×1
ios13 ×1
macos ×1
nscoder ×1
nscoding ×1
objective-c ×1
tags ×1
uitableview ×1
xcode ×1