Skip to content

Commit e338d85

Browse files
authored
Merge pull request #364 from zapcannon87/developer
refactor: http response on internal queue
2 parents 0a4a0f1 + 30ac3e0 commit e338d85

File tree

7 files changed

+208
-105
lines changed

7 files changed

+208
-105
lines changed

LeanCloud.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
83BC11D61CDD76E900D7E7A6 /* LCACLTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83BC11D51CDD76E900D7E7A6 /* LCACLTestCase.swift */; };
6666
83D0DE6F1CC7B3FF00FC204E /* LCQueryTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83D0DE6E1CC7B3FF00FC204E /* LCQueryTestCase.swift */; };
6767
83FAF0931CC4D1E400A84063 /* LCObjectTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FAF0921CC4D1E400A84063 /* LCObjectTestCase.swift */; };
68+
D302D340246BD259003D9274 /* LiveQueryTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = D302D33F246BD259003D9274 /* LiveQueryTestCase.swift */; };
6869
D303BD752328CB1C004AE13D /* SwiftProtobuf in Frameworks */ = {isa = PBXBuildFile; productRef = D303BD742328CB1C004AE13D /* SwiftProtobuf */; };
6970
D303BD782328CDFC004AE13D /* Starscream in Frameworks */ = {isa = PBXBuildFile; productRef = D303BD772328CDFC004AE13D /* Starscream */; };
7071
D303BD7B2328D062004AE13D /* GRDB in Frameworks */ = {isa = PBXBuildFile; productRef = D303BD7A2328D062004AE13D /* GRDB */; };
@@ -208,6 +209,7 @@
208209
83D0DE6E1CC7B3FF00FC204E /* LCQueryTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LCQueryTestCase.swift; sourceTree = "<group>"; };
209210
83D5923D1CD88846007177C5 /* BridgingHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BridgingHeader.h; sourceTree = "<group>"; };
210211
83FAF0921CC4D1E400A84063 /* LCObjectTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LCObjectTestCase.swift; sourceTree = "<group>"; };
212+
D302D33F246BD259003D9274 /* LiveQueryTestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveQueryTestCase.swift; sourceTree = "<group>"; };
211213
D303BD7C2328D928004AE13D /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = "<group>"; };
212214
D303BD7D2328D9D8004AE13D /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
213215
D30A2F85224A092300C000D5 /* LeanCloud.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = LeanCloud.podspec; sourceTree = "<group>"; };
@@ -374,6 +376,7 @@
374376
D3783A1121F453C3006F6635 /* IMConversationTestCase.swift */,
375377
D3665C3621FEAAC1005B44B0 /* IMMessageTestCase.swift */,
376378
D3FE04512277EA6C0008C88A /* IMLocalStorageTestCase.swift */,
379+
D302D33F246BD259003D9274 /* LiveQueryTestCase.swift */,
377380
);
378381
path = LeanCloudTests;
379382
sourceTree = "<group>";
@@ -756,6 +759,7 @@
756759
D3FE04522277EA6C0008C88A /* IMLocalStorageTestCase.swift in Sources */,
757760
116A682621427442004141A5 /* LCRouterTestCase.swift in Sources */,
758761
1123922C2191669100ECCBCC /* RTMRouterTestCase.swift in Sources */,
762+
D302D340246BD259003D9274 /* LiveQueryTestCase.swift in Sources */,
759763
118763AF2176EA3A0078645B /* LCInstallationTestCase.swift in Sources */,
760764
8365CFA81D79849D006B856E /* LCTypeTestCase.swift in Sources */,
761765
D3DAD03C218DA402008BCD37 /* RTMConnectionTestCase.swift in Sources */,
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
//
2+
// LiveQueryTestCase.swift
3+
// LeanCloudTests
4+
//
5+
// Created by pzheng on 2020/05/13.
6+
// Copyright © 2020 LeanCloud. All rights reserved.
7+
//
8+
9+
import XCTest
10+
@testable import LeanCloud
11+
12+
class LiveQueryTestCase: RTMBaseTestCase {
13+
14+
func testUserLogin() {
15+
let appID = LCApplication.default.id!
16+
let appKey = LCApplication.default.key!
17+
let serverURL = LCApplication.default.serverURL!
18+
19+
let application1 = try! LCApplication(
20+
id: appID,
21+
key: appKey,
22+
serverURL: serverURL)
23+
let application2 = try! LCApplication(
24+
id: appID,
25+
key: appKey,
26+
serverURL: serverURL)
27+
28+
let username = uuid
29+
let password = uuid
30+
let user = LCUser(application: application1)
31+
user.username = username.lcString
32+
user.password = password.lcString
33+
let userSignUpResult = user.signUp()
34+
XCTAssertNil(userSignUpResult.error)
35+
36+
let user1LogInResult = LCUser.logIn(
37+
application: application1,
38+
username: username,
39+
password: password)
40+
XCTAssertNil(user1LogInResult.error)
41+
42+
if let objectId = user.objectId?.value,
43+
let user1 = user1LogInResult.object,
44+
let _ = user1.sessionToken,
45+
user1 === application1.currentUser {
46+
var liveQuery1: LiveQuery!
47+
var liveQuery2: LiveQuery!
48+
expecting(
49+
description: "user login",
50+
count: 4)
51+
{ (exp) in
52+
liveQuery1 = try! LiveQuery(
53+
application: application1,
54+
query: {
55+
let query = LCQuery(
56+
application: application1,
57+
className: LCUser.objectClassName())
58+
query.whereKey("objectId", .equalTo(objectId))
59+
return query
60+
}())
61+
{ (_, event) in
62+
switch event {
63+
case .login(user: let user):
64+
XCTAssertEqual(user.objectId?.value, objectId)
65+
exp.fulfill()
66+
default:
67+
break
68+
}
69+
}
70+
71+
liveQuery1.subscribe { (result) in
72+
XCTAssertTrue(Thread.isMainThread)
73+
XCTAssertTrue(result.isSuccess)
74+
XCTAssertNil(result.error)
75+
exp.fulfill()
76+
77+
liveQuery2 = try! LiveQuery(
78+
application: application1,
79+
query: {
80+
let query = LCQuery(
81+
application: application1,
82+
className: LCUser.objectClassName())
83+
query.whereKey("createdAt", .existed)
84+
return query
85+
}())
86+
{ (_, event) in
87+
switch event {
88+
case .login(user: let user):
89+
XCTAssertEqual(user.objectId?.value, objectId)
90+
exp.fulfill()
91+
default:
92+
break
93+
}
94+
}
95+
96+
liveQuery2.subscribe { (result) in
97+
XCTAssertTrue(Thread.isMainThread)
98+
XCTAssertTrue(result.isSuccess)
99+
XCTAssertNil(result.error)
100+
exp.fulfill()
101+
102+
let user2LogInResult = LCUser.logIn(
103+
application: application2,
104+
username: username,
105+
password: password)
106+
XCTAssertNil(user2LogInResult.error)
107+
}
108+
}
109+
}
110+
} else {
111+
XCTFail()
112+
}
113+
114+
application1.unregister()
115+
application2.unregister()
116+
}
117+
}

Sources/Foundation/HTTPClient.swift

Lines changed: 56 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -220,13 +220,16 @@ class HTTPClient {
220220
headers: HTTPHeaders,
221221
encoding: ParameterEncoding,
222222
parameters: [String: Any]?,
223-
completionDispatchQueue: DispatchQueue,
223+
completionQueue: DispatchQueue,
224224
completionHandler: @escaping (LCResponse) -> Void)
225225
{
226226
do {
227-
var request = try URLRequest(url: url, method: method, headers: headers)
227+
var request = try URLRequest(
228+
url: url,
229+
method: method,
230+
headers: headers)
228231
request = try encoding.encode(request, with: parameters)
229-
completionDispatchQueue.sync {
232+
completionQueue.sync {
230233
guard let cachedResponse = self.urlCache?.cachedResponse(for: request),
231234
let httpResponse = cachedResponse.response as? HTTPURLResponse else {
232235
completionHandler(self.response(
@@ -236,7 +239,7 @@ class HTTPClient {
236239
return
237240
}
238241
let result = Result {
239-
try JSONResponseSerializer(options: .allowFragments)
242+
try JSONResponseSerializer()
240243
.serialize(
241244
request: request,
242245
response: httpResponse,
@@ -255,9 +258,10 @@ class HTTPClient {
255258
completionHandler(response)
256259
}
257260
} catch {
258-
completionDispatchQueue.async {
261+
completionQueue.async {
259262
completionHandler(self.response(
260-
with: LCError(error: error)))
263+
with: LCError(
264+
error: error)))
261265
}
262266
}
263267
}
@@ -268,23 +272,21 @@ class HTTPClient {
268272
parameters: [String: Any]? = nil,
269273
headers: [String: String]? = nil,
270274
cachePolicy: LCQuery.CachePolicy = .onlyNetwork,
271-
completionDispatchQueue: DispatchQueue? = nil,
275+
completionQueue: DispatchQueue? = nil,
272276
completionHandler: @escaping (LCResponse) -> Void)
273277
-> LCRequest
274278
{
275-
let completionDispatchQueue = completionDispatchQueue
279+
let completionQueue = completionQueue
276280
?? self.defaultCompletionConcurrentQueue
277-
278281
guard let url = self.application.appRouter.route(path: path) else {
279-
completionDispatchQueue.sync {
282+
completionQueue.sync {
280283
completionHandler(self.response(
281284
with: LCError(
282285
code: .notFound,
283286
reason: "URL not found.")))
284287
}
285288
return LCSingleRequest(request: nil)
286289
}
287-
288290
let method = method.alamofireMethod
289291
let headers = HTTPHeaders(mergeCommonHeaders(headers))
290292
let encoding: ParameterEncoding
@@ -294,23 +296,25 @@ class HTTPClient {
294296
default:
295297
encoding = JSONEncoding.default
296298
}
297-
298299
let requestCachedResponse: () -> Void = {
299300
self.requestCache(
300301
url: url,
301302
method: method,
302303
headers: headers,
303304
encoding: encoding,
304305
parameters: parameters,
305-
completionDispatchQueue: completionDispatchQueue,
306+
completionQueue: completionQueue,
306307
completionHandler: completionHandler)
307308
}
308-
309309
switch cachePolicy {
310310
case .onlyNetwork, .networkElseCache:
311-
let request = session.request(url, method: method, parameters: parameters, encoding: encoding, headers: headers).validate()
311+
let request = self.session.request(
312+
url, method: method,
313+
parameters: parameters,
314+
encoding: encoding,
315+
headers: headers).validate()
312316
request.lcDebugDescription()
313-
request.responseJSON(queue: completionDispatchQueue) { afResponse in
317+
request.responseJSON(queue: completionQueue) { afResponse in
314318
afResponse.lcDebugDescription(request: request)
315319
let response = LCResponse(
316320
application: self.application,
@@ -331,82 +335,67 @@ class HTTPClient {
331335
return LCSingleRequest(request: nil)
332336
}
333337
}
334-
335-
/**
336-
Creates a request to REST API and sends it asynchronously.
337-
338-
- parameter url: The absolute URL.
339-
- parameter method: The HTTP Method.
340-
- parameter parameters: The request parameters.
341-
- parameter headers: The request headers.
342-
- parameter completionDispatchQueue: The dispatch queue in which the completion handler will be called. By default, it's a concurrent queue.
343-
- parameter completionHandler: The completion callback closure.
344-
345-
- returns: A request object.
346-
*/
338+
347339
func request(
348340
url: URL,
349341
method: Method,
350342
parameters: [String: Any]? = nil,
351343
headers: [String: String]? = nil,
352-
completionDispatchQueue: DispatchQueue? = nil,
344+
completionQueue: DispatchQueue? = nil,
353345
completionHandler: @escaping (LCResponse) -> Void)
354346
-> LCRequest
355347
{
356-
let method = method.alamofireMethod
357-
let headers = HTTPHeaders(mergeCommonHeaders(headers))
358-
var encoding: ParameterEncoding!
359-
348+
let method = method.alamofireMethod
349+
let headers = HTTPHeaders(mergeCommonHeaders(headers))
350+
let encoding: ParameterEncoding
360351
switch method {
361-
case .get: encoding = URLEncoding.default
362-
default: encoding = JSONEncoding.default
352+
case .get:
353+
encoding = URLEncoding.default
354+
default:
355+
encoding = JSONEncoding.default
363356
}
364-
365-
let request = session.request(url, method: method, parameters: parameters, encoding: encoding, headers: headers).validate()
366-
367-
let completionDispatchQueue = completionDispatchQueue
368-
?? self.defaultCompletionConcurrentQueue
369-
357+
let request = self.session.request(
358+
url, method: method,
359+
parameters: parameters,
360+
encoding: encoding,
361+
headers: headers).validate()
370362
request.lcDebugDescription()
371-
request.responseJSON(queue: completionDispatchQueue) { afResponse in
363+
request.responseJSON(
364+
queue: completionQueue ?? self.defaultCompletionConcurrentQueue)
365+
{ afResponse in
372366
afResponse.lcDebugDescription(request: request)
373-
completionHandler(LCResponse(application: self.application, afDataResponse: afResponse))
367+
completionHandler(LCResponse(
368+
application: self.application,
369+
afDataResponse: afResponse))
374370
}
375-
376371
return LCSingleRequest(request: request)
377372
}
378-
379-
/**
380-
Create request for error.
381-
382-
- parameter error: The error object.
383-
- parameter completionDispatchQueue: The dispatch queue in which the completion handler will be called. By default, it's a concurrent queue.
384-
- parameter completionHandler: The completion callback closure.
385-
386-
- returns: A request object.
387-
*/
373+
388374
func request<T: LCResultType>(
389375
error: Error,
390-
completionDispatchQueue: DispatchQueue? = nil,
391-
completionHandler: @escaping (T) -> Void) -> LCRequest
376+
completionQueue: DispatchQueue? = nil,
377+
completionHandler: @escaping (T) -> Void)
378+
-> LCRequest
392379
{
393-
return request(object: error, completionDispatchQueue: completionDispatchQueue) { error in
394-
completionHandler(T(error: LCError(error: error)))
380+
return self.request(
381+
object: error,
382+
completionQueue: completionQueue)
383+
{ error in
384+
completionHandler(T(
385+
error: LCError(
386+
error: error)))
395387
}
396388
}
397-
389+
398390
func request<T>(
399391
object: T,
400-
completionDispatchQueue: DispatchQueue? = nil,
401-
completionHandler: @escaping (T) -> Void) -> LCRequest
392+
completionQueue: DispatchQueue? = nil,
393+
completionHandler: @escaping (T) -> Void)
394+
-> LCRequest
402395
{
403-
let completionDispatchQueue = completionDispatchQueue
404-
?? self.defaultCompletionConcurrentQueue
405-
406-
completionDispatchQueue.async {
396+
(completionQueue ?? self.defaultCompletionConcurrentQueue).async {
407397
completionHandler(object)
408398
}
409-
410399
return LCSingleRequest(request: nil)
411400
}
412401
}

Sources/Foundation/Object.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,7 +1003,7 @@ open class LCObject: NSObject, LCValue, LCValueExtension, Sequence {
10031003
{
10041004
let sharedApplication = objects.first?.application ?? .default
10051005
for object in objects {
1006-
if object.application !== sharedApplication {
1006+
guard object.application === sharedApplication else {
10071007
return .failure(
10081008
error: LCError(
10091009
code: .inconsistency,
@@ -1021,13 +1021,13 @@ open class LCObject: NSObject, LCValue, LCValueExtension, Sequence {
10211021
{
10221022
let sharedApplication = objects.first?.application ?? .default
10231023
for object in objects {
1024-
if object.application !== sharedApplication {
1024+
guard object.application === sharedApplication else {
10251025
return sharedApplication.httpClient
10261026
.request(
10271027
error: LCError(
10281028
code: .inconsistency,
10291029
reason: "the applications of the `objects` should be the same instance."),
1030-
completionDispatchQueue: completionQueue,
1030+
completionQueue: completionQueue,
10311031
completionHandler: completion)
10321032
}
10331033
}

0 commit comments

Comments
 (0)