Ios 将对象保存为可在任何位置访问

Ios 将对象保存为可在任何位置访问,ios,swift,Ios,Swift,我这里有一个条件,假设用户通过调用API登录。并且响应包含用户的详细信息。我们是否可以将用户的详细信息保存为对象,并可以全局访问?下面是我如何使用ObjectMapper调用api的 对于模型类: import ObjectMapper class User: Mappable { var id: Int? var userId: Int? var orgId: Int? var type: Int? var email: String? var lang: String? var nick

我这里有一个条件,假设用户通过调用API登录。并且响应包含用户的详细信息。我们是否可以将用户的详细信息保存为对象,并可以全局访问?下面是我如何使用ObjectMapper调用api的 对于模型类:

import ObjectMapper

class User: Mappable {

var id: Int?
var userId: Int?
var orgId: Int?
var type: Int?
var email: String?
var lang: String?
var nickname: String?
var status: Int?
var token: String?

required init(map: Map) {
    mapping(map: map)
}

func mapping(map: Map) {
    id <- map["id"]
    userId <- map["userId"]
    orgId <- map["orgId"]
    type <- map["type"]
    failedAttempt <- map["failedAttempt"]
    email <- map["email"]
    lang <- map["lang"]
    nickname <- map["nickname"]
    status <- map["status"]
    token <- map["token"]
}
导入对象映射器
类用户:可映射{
变量id:Int?
var userId:Int?
变量orgId:Int?
变量类型:Int?
var电子邮件:字符串?
瓦朗:字符串?
变量昵称:字符串?
变量状态:Int?
变量标记:字符串?
必需的初始化(映射:映射){
映射(映射:映射)
}
func映射(映射:映射){

id我同意在
UserDefaults
中保存9个单独的键是不实际的。但是为什么不将整个内容编码为JSON并保存生成的
数据呢

扩展用户:可编码{}
//假设user是user的实例
guard let userJSON=try?JSONEncoder().encode(user)else{
//句柄编码失败
}
让userDefaultsKeyForUser=“com.yourdomain.snazzyapp.userInfo”
UserDefaults.standard.set(userJSON,forKey:userDefaultsKeyForUser)
我认为Swift将自动为您的
用户
类综合
Codable
一致性,但您可能需要将其设置为
final
。或者显式实现
Codable

取回它

guard let userJSON=UserDefaults.standard.data(forKey:userDefaultsKeyForUser)else{
//处理丢失的数据(可能是第一次运行?)
}
guard let user=try?JSONDecoder().decode(user.self,from:userJSON)else{
//处理解码失败
} 
替代编码/解码方法 尽管遵循
Codable
是实现这一点的首选方法,但这有时对类来说可能是个问题,特别是在涉及继承的情况下。尤其是
Codable
可编码的
可解码的
的组合
可解码的
有时对c来说是个问题这个问题与
required init有关(来自解码器:解码器)抛出必须直接在类中声明而不是在扩展中声明的
,然后您可能在编码
超级
时遇到问题。如果您的类是基
,这应该不是问题。这主要是从AppKit/UIKit类继承时的问题

如果由于某种原因,
User
无法符合
Codable
,您可以使用
NSCoding
。它的工作原理稍有不同

在最坏的情况下,您可以实现手动将每个属性显式编码/解码为数据的方法。您甚至可以将它们存储为二进制,但您可能需要执行一些操作,例如存储字符串的字节计数,以便知道每个属性的开始和结束位置,并且您需要提出一个方案来指示它们何时开始e> 编码中为零。它没有JSON灵活,这就是为什么它是最后的选择…虽然我会注意到它要快得多。这对你的
用户
类没有多大关系,但我编写了一个神经网络库,我想在训练期间将模型保存在检查点,这意味着编码许多非常大的层次e矩阵。数百万个参数。使用我自己的二进制编码,读写模型比让
Codable
处理要快20倍左右,即使我将其保存为二进制plist

第三种选择是重新处理
用户
类。要么将其设置为
结构
,要么在内部使用
结构
存储其属性,并使用计算属性在
中获取和设置它们。您的类的所有属性都已符合
可编码
,因此Swift肯定可以合成esize
Codable
使
结构符合这些属性。如果您仍然将
结构
包装在
中,那么您只需要有一个初始值设定项,该初始值设定项接受
数据
,并执行我上面显示的相同解码,以设置包装的
结构
,以及
编码
方法(甚至是一个计算的
var
),它对上述
结构进行编码并返回
数据


我认为您不需要这些替代解决方案,但我提到它们只是为了以防万一,因为它们对于未来的情况非常有用。

您必须问问自己,您希望如何使用编译器自动补全功能从应用程序的不同位置访问此对象。其次,对象的寿命是多长?t在登录/注销、应用程序会话或应用程序生命周期期间,对象是否应可访问

让我们从对象的生命周期开始。

  • 登录/注销时,对象可以存储在内存中
  • 应用程序会话,对象可以存储在内存中
  • 应用程序安装/删除时,对象应存储在UserDefaults、数据库或文件中

自动完成驱动的开发又名ADD

决定在何处存储userDetails对象以及如何访问它

假设您在视图控制器中有一个逻辑,可以在viewDidLoad中定义的初始配置中隐藏或取消隐藏视图。请编写一些原型代码,以确定您希望如何从应用程序的不同位置访问“userDetails”对象

func viewDidLoad() {
   super.viewDidLoad()

   if userDetails.status {
     //userDetails is a global instance of a user object
   }

   if session.userDetails.status {
     //session is a global instance of a Session object which has a property which stores a User instance in userDetails
   }

   if Session.current.userDetails.status {
     // Session is a type and 'current' is a singleton of that type which has a userDetails property which stores an instance of User type
   }

   if User.userDetails.status {
     // User is your type which can have a static property 'userDetails' which stores a User instance
   }

}

嗯……那么你会如何检索它呢?正如我们通常从userdefaults检索一样,唯一的补充是在检索后将其返回给用户?我更新了我的答案以解决检索问题。或者,你可以从应用程序沙箱中已知位置的文件中读/写
userdefaults
。如果你这样做的话使用
UserDefaults.standard
,您可能希望使用与应用程序相同的捆绑包标识符预先添加密钥…可能类似于“com.yourdomain.snazzyapp.userInfo”的内容再次更新,以反映我对
UserDefa的建议
func viewDidLoad() {
   super.viewDidLoad()

   if userDetails.status {
     //userDetails is a global instance of a user object
   }

   if session.userDetails.status {
     //session is a global instance of a Session object which has a property which stores a User instance in userDetails
   }

   if Session.current.userDetails.status {
     // Session is a type and 'current' is a singleton of that type which has a userDetails property which stores an instance of User type
   }

   if User.userDetails.status {
     // User is your type which can have a static property 'userDetails' which stores a User instance
   }

}