Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support multiple applications #63

Closed
wants to merge 13 commits into from

Conversation

tang3w
Copy link
Contributor

@tang3w tang3w commented Jun 27, 2018

支持实例化多个应用。

SDK 初始化接口发生了变化,示例代码如下:

LCApplication.default = LCApplication(
    ID:  "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
    key: "kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk",
    region: .cn)

其中 LCApplication.default 是默认 application。

创建 application-specific 对象时,如果不显式指定,则关联到默认 application。

Object、Query 等类型的构造函数增加了一个名为 application 的可选参数,例如:

class LCObject {
    init(className: String, application: LCApplication = .current ?? .shared)
}

该参数用于显式指定 application。如果不指定,则会从当前上下文中寻找,如果找不到,则使用默认 application。

Object 只能与同一个应用下的其他 object 建立关系,下面代码会抛出异常。

let application1 = LCApplication()
let application2 = LCApplication()

let object1 = TestObject(application: application1)
let object2 = TestObject(application: application2)

// Cannot establish a relationship between objects in different applications.
object1.set("object", value: object2)

Query 也是这样,只有同一 application 下的 query 才能参与 and 或 or 运算。

用户更新 SDK 后,只需修改一下 SDK 初始化代码就可以运行。

示例代码可参考 ApplicationTestCase.swift 这个测试用例。

@zapcannon87 @leancloud/sdk-only

@tang3w
Copy link
Contributor Author

tang3w commented Jun 28, 2018

LCApplication.shared 更名为 LCApplication.default 了。

@tang3w
Copy link
Contributor Author

tang3w commented Jun 28, 2018

删除了 LCApplication.Identity 类型。把 ID、key 和 region 作为 LCApplication 对象的直接属性。减少了一个概念,也简化了初始化 SDK 的语句。

@tang3w
Copy link
Contributor Author

tang3w commented Jun 28, 2018

删除 LCApplication.Identity 后,default application 和其他 application 的实例化也一致了。

@tang3w
Copy link
Contributor Author

tang3w commented Jun 28, 2018

记录一些容易忽略的细节。批量接口需要能按 application 筛选 objects 并分批请求,LCApplication 需要正确地 propagate 到各个对象,例如 query 查询出来的对象也要关联到正确的 application 上。


private static let currentKey = "CurrentLeanCloudApplication"

public static var current: LCApplication? {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感觉这里是不是有问题?按照 current 和 perform 的实现,threadDictionary 里是不会储存 LCApplication 的实例的。

threadDictionary 初始化时为空,所以 perform 实现里,original 初始值就为 nil,perform 执行完后,会用为 nil 的 original 覆盖到 key 对应的 value,最终 threadDictionary 还是为空。

另外,我对这里的设计有点异议,如果是想让从后端获取的 JSON 数据转化为 swift 里对应的 object,那么直接将对应的 HTTPClient 的 LCApplication 实例 set 到该 object 就行了吧。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

方法 perform 用来创建一个 application 上下文,属性 current 的访问应该出现在 perform 方法的 closure 中:

application.perform {
    print(LCApplication.current)
}

引入 perform 方法的本意是更好地支持 object 反序列化。反序列化的构造函数如下:

public required convenience init?(coder aDecoder: NSCoder)

Cocoa 约定了该构造函数的形式,因此无法增加一个参数让用户在反序列化 object 时指定 application。这样很容易导致 object 关联到错误的 application 上。因此我在该构造函数中增加了一些逻辑,要求用户必须用 perform 方法来创建一个 application 上下文,然后在这个 application 上下文中反序列化对象。

另外,perform 还可以简化实例化 object 的代码(坦白说,这是我强行列出的理由)。

threadDictionary 不会永久存储 LCApplication 实例,是短暂的,局部于 perform 方法调用。

perform 方法跟把 JSON 反序列化没有关系。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里还有个方案是归档的时候,把 application 也一起归档。这样就不需要 perform 方法了。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我感觉「把 application 也一起归档」似乎是个更好的方案,用户一般是能少写一行就少写一行😏

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tenor

@zapcannon87
Copy link
Contributor

这个 PR 可以关了吧?

@tang3w
Copy link
Contributor Author

tang3w commented Sep 5, 2018

可以关了,关掉吧。

@tang3w tang3w closed this Sep 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants