如何知道用户何时更改了设置捆绑包。

12
我允许用户在iPhone的设置区域更改他们的设置。在下一次网络同步期间,我想将用户的更改发送到服务器。但仅在进行更改时发送。
但是,如何知道用户何时在设置区域内进行更改?
如果可以的话,我想避免始终发送信息(无论是否更改)的选项或者首先从服务器获取信息,然后在与用户默认值不同的情况下更新。
有没有一个优美而简洁的方法来解决这个问题?谢谢您的帮助!
一周过去了还没有答案... 这个问题太难了,还是根本没有意义吗?
4个回答

18
啊,我有点傻!下面有一种优雅的方式。在XCode中的苹果文档中搜索AppPrefs,它将显示一个示例应用程序,完全可以做到你想做的事情。只需编译和运行!它使用了NSUserDefaultsDidChangeNotification
这是正在使用的注册观察者的代码:
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(defaultsChanged:)
                                             name:NSUserDefaultsDidChangeNotification
                                           object:nil];

旧回答:

似乎不能从NSUserDefaults中获取修改日期。 我只能想到以下方法:

NSUserDefaults *previousDefaults = [someInstance previousUserDefaults];
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];

if([previousDefaults isEqualToDictionary:currentDefaults]) 
{
    [someOtherInstance sendModifiedUserDefaultsToServerWithDefaults:currentDefaults];
    [yetAnotherInstance saveModified]
}

当应用程序首次启动时,您必须将用户默认设置保存为字典并保存到磁盘上:这是您的默认值。然后,每次打开应用程序时,您都需要比较这两个字典。如果它们


嗯,让我觉得有更好的方法的原因是,当您在iPhone上更改网络设置时,它会自动尝试查找并连接到它。这必须意味着用户设置更改已触发了某个操作。这对我来说也是一个不错的解决方案。他们是如何做到的? - san
这里有一个优雅而简单的解决方案来解决这个问题。 - Nick Weaver
哦,太好了!但是这会触发任何设置的更改。有没有一种方法只在特定属性更改时进行操作? - san
我认为我们已经达到了可能性的底部。请查看NSUserDefaults类参考,它没有给我提供更有用的信息。但如果你找到了方法,请在这里告诉我们。 - Nick Weaver
@Will 我不这么认为。无论如何,用户默认值是每个沙盒独立的,因此只能由应用程序自己进行更改。 - Nick Weaver

2

并不是这个问题太难,只是没有简单的方法来完成你所要求的事情。据我所知,NSUserDefaults不会为每个应用程序的设置记录“上次修改”的日期,因此,如果用户使用设置应用程序更改了一些设置,除了查看所有设置之外,没有好的方法来检测。

如果您真的需要这样做,我认为最好的方法是将您感兴趣的同步设置读入某个数据结构中,并基于该结构计算某种哈希或校验和。将该值与上次运行应用程序时计算的值进行比较,如果不同,则与服务器进行同步。您可以将该值存储在NSUserDefaults中,但请确保不要将其包含在计算中。


谢谢 Caleb。我不想让我的解决方案太复杂。我很惊讶居然不需要像这样的东西,而且库中也没有支持这个想法的内容,例如响应用户设置的更改。 - san
通常,应用程序并不关心它的偏好设置是否最近发生了变化--无论何时需要这些设置,它都会从默认系统中读取它们,因此如果有什么变化,应用程序会自动获取新值。此外,NSUserDefaults来自MacOS X,在那个上下文中,用户应该能够删除应用程序的偏好文件而不会产生任何不良影响;应用程序应该只是回退到其内置的默认值。即使在iOS上,我也不会将关键信息存储在默认系统中。 - Caleb

0

仅限Swift

如果您想要,也可以仅使用Swift:

NotificationCenter.default.addObserver(forName: UserDefaults.didChangeNotification, object: nil, queue: OperationQueue.main) { notification in
    // Do something
}

0

Swift

观察变化并在变化时调用方法:

NotificationCenter.default.addObserver(
    self,
    selector: #selector(updateStateFromSettingsBundle),
    name: UserDefaults.didChangeNotification,
    object: nil
)

@objc func updateStateFromSettingsBundle() {}

你在这里仍在使用ObjC,因为你正在引用一个@objc函数。 - Boothosh81
使用ObjC并不会将Swift代码转换为Objective-C :) 这意味着它可以被Objective-C运行时所识别。而NotificationCenter类则继承自NSObject,后者是一个Objective-C类 ;) @Boothosh81 - Mojtaba Hosseini

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接