Skip to content

Commit 4b0c572

Browse files
committed
Merge pull request #515 from ParsePlatform/nlutsenko.persist.installationid
Rewrite InstallationIdentifierStore to use Persistence groups and be fully async.
2 parents 651f199 + b414e07 commit 4b0c572

13 files changed

+198
-156
lines changed

Parse/Internal/Commands/CommandRunner/URLRequestConstructor/PFCommandURLRequestConstructor.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@
99

1010
#import <Foundation/Foundation.h>
1111

12+
#import <Parse/PFConstants.h>
13+
1214
#import "PFDataProvider.h"
1315

16+
@class BFTask PF_GENERIC(BFGenericType);
1417
@class PFRESTCommand;
1518

1619
@interface PFCommandURLRequestConstructor : NSObject
@@ -29,15 +32,15 @@
2932
/// @name Data
3033
///--------------------------------------
3134

32-
- (NSURLRequest *)dataURLRequestForCommand:(PFRESTCommand *)command;
35+
- (BFTask PF_GENERIC(NSURLRequest *)*)getDataURLRequestAsyncForCommand:(PFRESTCommand *)command;
3336

3437
///--------------------------------------
3538
/// @name File Upload
3639
///--------------------------------------
3740

38-
- (NSURLRequest *)fileUploadURLRequestForCommand:(PFRESTCommand *)command
39-
withContentType:(NSString *)contentType
40-
contentSourceFilePath:(NSString *)contentFilePath;
41+
- (BFTask PF_GENERIC(NSURLRequest *)*)getFileUploadURLRequestAsyncForCommand:(PFRESTCommand *)command
42+
withContentType:(NSString *)contentType
43+
contentSourceFilePath:(NSString *)contentFilePath;
4144

4245
///--------------------------------------
4346
/// @name Headers

Parse/Internal/Commands/CommandRunner/URLRequestConstructor/PFCommandURLRequestConstructor.m

Lines changed: 58 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#import "PFCommandURLRequestConstructor.h"
1111

12+
#import "BFTask+Private.h"
1213
#import "PFAssert.h"
1314
#import "PFCommandRunningConstants.h"
1415
#import "PFDevice.h"
@@ -47,58 +48,62 @@ + (instancetype)constructorWithDataSource:(id<PFInstallationIdentifierStoreProvi
4748
#pragma mark - Data
4849
///--------------------------------------
4950

50-
- (NSURLRequest *)dataURLRequestForCommand:(PFRESTCommand *)command {
51-
NSURL *url = [PFURLConstructor URLFromAbsoluteString:[PFInternalUtils parseServerURLString]
52-
path:[NSString stringWithFormat:@"/1/%@", command.httpPath]
53-
query:nil];
54-
NSDictionary *headers = [self _URLRequestHeadersForCommand:command];
55-
56-
NSString *requestMethod = command.httpMethod;
57-
NSDictionary *requestParameters = nil;
58-
if (command.parameters) {
59-
NSDictionary *parameters = nil;
60-
61-
// The request URI may be too long to include parameters in the URI.
62-
// To avoid this problem we send the parameters in a POST request json-encoded body
63-
// and add a custom parameter that overrides the method in a request.
64-
if ([requestMethod isEqualToString:PFHTTPRequestMethodGET] ||
65-
[requestMethod isEqualToString:PFHTTPRequestMethodHEAD] ||
66-
[requestMethod isEqualToString:PFHTTPRequestMethodDELETE]) {
67-
NSMutableDictionary *mutableParameters = [command.parameters mutableCopy];
68-
mutableParameters[PFCommandParameterNameMethodOverride] = command.httpMethod;
69-
70-
requestMethod = PFHTTPRequestMethodPOST;
71-
parameters = [mutableParameters copy];
72-
} else {
73-
parameters = command.parameters;
51+
- (BFTask PF_GENERIC(NSURLRequest *)*)getDataURLRequestAsyncForCommand:(PFRESTCommand *)command {
52+
return (BFTask *)[[self _getURLRequestHeadersAsyncForCommand:command] continueWithSuccessBlock:^id(BFTask PF_GENERIC(NSDictionary *)*task) {
53+
NSURL *url = [PFURLConstructor URLFromAbsoluteString:[PFInternalUtils parseServerURLString]
54+
path:[NSString stringWithFormat:@"/1/%@", command.httpPath]
55+
query:nil];
56+
NSDictionary *headers = task.result;
57+
58+
NSString *requestMethod = command.httpMethod;
59+
NSDictionary *requestParameters = nil;
60+
if (command.parameters) {
61+
NSDictionary *parameters = nil;
62+
63+
// The request URI may be too long to include parameters in the URI.
64+
// To avoid this problem we send the parameters in a POST request json-encoded body
65+
// and add a custom parameter that overrides the method in a request.
66+
if ([requestMethod isEqualToString:PFHTTPRequestMethodGET] ||
67+
[requestMethod isEqualToString:PFHTTPRequestMethodHEAD] ||
68+
[requestMethod isEqualToString:PFHTTPRequestMethodDELETE]) {
69+
NSMutableDictionary *mutableParameters = [command.parameters mutableCopy];
70+
mutableParameters[PFCommandParameterNameMethodOverride] = command.httpMethod;
71+
72+
requestMethod = PFHTTPRequestMethodPOST;
73+
parameters = [mutableParameters copy];
74+
} else {
75+
parameters = command.parameters;
76+
}
77+
requestParameters = [[PFPointerObjectEncoder objectEncoder] encodeObject:parameters];
7478
}
75-
requestParameters = [[PFPointerObjectEncoder objectEncoder] encodeObject:parameters];
76-
}
7779

78-
return [PFHTTPURLRequestConstructor urlRequestWithURL:url
79-
httpMethod:requestMethod
80-
httpHeaders:headers
81-
parameters:requestParameters];
80+
return [PFHTTPURLRequestConstructor urlRequestWithURL:url
81+
httpMethod:requestMethod
82+
httpHeaders:headers
83+
parameters:requestParameters];
84+
}];
8285
}
8386

8487
///--------------------------------------
8588
#pragma mark - File
8689
///--------------------------------------
8790

88-
- (NSURLRequest *)fileUploadURLRequestForCommand:(PFRESTCommand *)command
89-
withContentType:(NSString *)contentType
90-
contentSourceFilePath:(NSString *)contentFilePath {
91-
NSMutableURLRequest *request = [[self dataURLRequestForCommand:command] mutableCopy];
91+
- (BFTask PF_GENERIC(NSURLRequest *)*)getFileUploadURLRequestAsyncForCommand:(PFRESTCommand *)command
92+
withContentType:(NSString *)contentType
93+
contentSourceFilePath:(NSString *)contentFilePath {
94+
return [[self getDataURLRequestAsyncForCommand:command] continueWithSuccessBlock:^id(BFTask PF_GENERIC(NSURLRequest *)*task) {
95+
NSMutableURLRequest *request = [task.result mutableCopy];
9296

93-
if (contentType) {
94-
[request setValue:contentType forHTTPHeaderField:PFHTTPRequestHeaderNameContentType];
95-
}
97+
if (contentType) {
98+
[request setValue:contentType forHTTPHeaderField:PFHTTPRequestHeaderNameContentType];
99+
}
96100

97-
//TODO (nlutsenko): Check for error here.
98-
NSNumber *fileSize = [PFInternalUtils fileSizeOfFileAtPath:contentFilePath error:nil];
99-
[request setValue:[fileSize stringValue] forHTTPHeaderField:PFHTTPRequestHeaderNameContentLength];
101+
//TODO (nlutsenko): Check for error here.
102+
NSNumber *fileSize = [PFInternalUtils fileSizeOfFileAtPath:contentFilePath error:nil];
103+
[request setValue:[fileSize stringValue] forHTTPHeaderField:PFHTTPRequestHeaderNameContentLength];
100104

101-
return request;
105+
return request;
106+
}];
102107
}
103108

104109
///--------------------------------------
@@ -135,15 +140,18 @@ + (NSDictionary *)defaultURLRequestHeadersForApplicationId:(NSString *)applicati
135140
return [mutableHeaders copy];
136141
}
137142

138-
- (NSDictionary *)_URLRequestHeadersForCommand:(PFRESTCommand *)command {
139-
NSMutableDictionary *headers = [NSMutableDictionary dictionary];
140-
[headers addEntriesFromDictionary:command.additionalRequestHeaders];
141-
PFInstallationIdentifierStore *installationIdentifierStore = self.dataSource.installationIdentifierStore;
142-
headers[PFCommandHeaderNameInstallationId] = installationIdentifierStore.installationIdentifier;
143-
if (command.sessionToken) {
144-
headers[PFCommandHeaderNameSessionToken] = command.sessionToken;
145-
}
146-
return [headers copy];
143+
- (BFTask PF_GENERIC(NSDictionary *)*)_getURLRequestHeadersAsyncForCommand:(PFRESTCommand *)command {
144+
return [BFTask taskFromExecutor:[BFExecutor defaultExecutor] withBlock:^id {
145+
NSMutableDictionary *headers = [NSMutableDictionary dictionary];
146+
[headers addEntriesFromDictionary:command.additionalRequestHeaders];
147+
if (command.sessionToken) {
148+
headers[PFCommandHeaderNameSessionToken] = command.sessionToken;
149+
}
150+
return [[self.dataSource.installationIdentifierStore getInstallationIdentifierAsync] continueWithSuccessBlock:^id(BFTask PF_GENERIC(NSString *)*task) {
151+
headers[PFCommandHeaderNameInstallationId] = task.result;
152+
return [headers copy];
153+
}];
154+
}];
147155
}
148156

149157
@end

Parse/Internal/Commands/CommandRunner/URLSession/PFURLSessionCommandRunner.m

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,9 @@ - (void)dealloc {
121121
cancellationToken:(BFCancellationToken *)cancellationToken {
122122
return [self _performCommandRunningBlock:^id {
123123
[command resolveLocalIds];
124-
NSURLRequest *request = [self.requestConstructor dataURLRequestForCommand:command];
125-
return [_session performDataURLRequestAsync:request forCommand:command cancellationToken:cancellationToken];
124+
return [[self.requestConstructor getDataURLRequestAsyncForCommand:command] continueWithSuccessBlock:^id(BFTask PF_GENERIC(NSURLRequest *)*task) {
125+
return [_session performDataURLRequestAsync:task.result forCommand:command cancellationToken:cancellationToken];
126+
}];
126127
} withOptions:options cancellationToken:cancellationToken];
127128
}
128129

@@ -141,15 +142,15 @@ - (void)dealloc {
141142
@strongify(self);
142143

143144
[command resolveLocalIds];
144-
NSURLRequest *request = [self.requestConstructor fileUploadURLRequestForCommand:command
145-
withContentType:contentType
146-
contentSourceFilePath:sourceFilePath];
147-
return [_session performFileUploadURLRequestAsync:request
148-
forCommand:command
149-
withContentSourceFilePath:sourceFilePath
150-
cancellationToken:cancellationToken
151-
progressBlock:progressBlock];
152-
145+
return [[self.requestConstructor getFileUploadURLRequestAsyncForCommand:command
146+
withContentType:contentType
147+
contentSourceFilePath:sourceFilePath] continueWithSuccessBlock:^id(BFTask PF_GENERIC(NSURLRequest *)*task) {
148+
return [_session performFileUploadURLRequestAsync:task.result
149+
forCommand:command
150+
withContentSourceFilePath:sourceFilePath
151+
cancellationToken:cancellationToken
152+
progressBlock:progressBlock];
153+
}];
153154
} withOptions:options cancellationToken:cancellationToken];
154155
}
155156

Parse/Internal/Installation/CurrentInstallationController/PFCurrentInstallationController.m

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ - (BFTask *)getCurrentObjectAsync {
106106
}
107107

108108
PFInstallation *installation = task.result;
109-
NSString *installationId = self.installationIdentifierStore.installationIdentifier;
109+
//TODO: (nlutsenko) Make it not terrible aka actually use task chaining here.
110+
NSString *installationId = [[self.installationIdentifierStore getInstallationIdentifierAsync] waitForResult:nil];
110111
installationId = [installationId lowercaseString];
111112
if (!installation || ![installationId isEqualToString:installation.installationId]) {
112113
// If there's no installation object, or the object's installation

Parse/Internal/Installation/InstallationIdentifierStore/PFInstallationIdentifierStore.h

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,31 @@
99

1010
#import <Foundation/Foundation.h>
1111

12-
@class PFFileManager;
12+
#import "PFDataProvider.h"
1313

14-
@interface PFInstallationIdentifierStore : NSObject
14+
#import <Parse/PFConstants.h>
1515

16-
/*!
17-
Returns a cached installationId or creates a new one, saves it to disk and returns it.
16+
@class BFTask PF_GENERIC(BFGenericType);
1817

19-
@returns `NSString` representation of current installationId.
20-
*/
21-
@property (nonatomic, copy, readonly) NSString *installationIdentifier;
18+
@interface PFInstallationIdentifierStore : NSObject
19+
20+
@property (nonatomic, weak, readonly) id<PFPersistenceControllerProvider> dataSource;
2221

2322
///--------------------------------------
2423
/// @name Init
2524
///--------------------------------------
2625

2726
- (instancetype)init NS_UNAVAILABLE;
28-
- (instancetype)initWithFileManager:(PFFileManager *)fileManager NS_DESIGNATED_INITIALIZER;
27+
- (instancetype)initWithDataSource:(id<PFPersistenceControllerProvider>)dataSource NS_DESIGNATED_INITIALIZER;
28+
29+
///--------------------------------------
30+
/// @name Accessors
31+
///--------------------------------------
32+
33+
/*!
34+
Returns a cached installationId or creates a new one, saves it to disk and returns it.
35+
*/
36+
- (BFTask PF_GENERIC(NSString *)*)getInstallationIdentifierAsync;
2937

3038
///--------------------------------------
3139
/// @name Clear
@@ -34,6 +42,6 @@
3442
/*!
3543
Clears installation identifier on disk and in-memory.
3644
*/
37-
- (void)clearInstallationIdentifier;
45+
- (BFTask *)clearInstallationIdentifierAsync;
3846

3947
@end

0 commit comments

Comments
 (0)