1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
//
// SDLSequentialRPCRequestOperation.m
// SmartDeviceLink
//
// Created by Joel Fischer on 1/31/18.
// Copyright © 2018 smartdevicelink. All rights reserved.
//
#import "SDLSequentialRPCRequestOperation.h"
#import "SDLConnectionManagerType.h"
NS_ASSUME_NONNULL_BEGIN
@interface SDLSequentialRPCRequestOperation ()
@property (copy, nonatomic) NSArray<SDLRPCRequest *> *requests;
@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
@property (copy, nonatomic, nullable) SDLMultipleSequentialRequestProgressHandler progressHandler;
@property (copy, nonatomic, nullable) SDLMultipleRequestCompletionHandler completionHandler;
@property (strong, nonatomic) NSUUID *operationId;
@property (assign, nonatomic) NSUInteger requestsComplete;
@property (assign, nonatomic) NSUInteger currentRequestIndex;
@property (assign, nonatomic, readonly) float percentComplete;
@property (assign, nonatomic) BOOL requestFailed;
@end
@implementation SDLSequentialRPCRequestOperation {
BOOL executing;
BOOL finished;
}
- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager requests:(NSArray<SDLRPCRequest *> *)requests progressHandler:(nullable SDLMultipleSequentialRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler {
self = [super init];
if (!self) { return nil; }
executing = NO;
finished = NO;
_connectionManager = connectionManager;
_requests = requests;
_progressHandler = progressHandler;
_completionHandler = completionHandler;
_operationId = [NSUUID UUID];
_requestsComplete = 0;
_currentRequestIndex = 0;
_requestFailed = NO;
return self;
}
- (void)start {
[super start];
[self sdl_sendNextRequest];
}
- (void)sdl_sendNextRequest {
// The operation was canceled while in progress
if (self.cancelled) {
if (self.completionHandler != nil) {
self.completionHandler(NO);
}
[self finishOperation];
return;
}
// The operation is done, all requests have been sent and all responses received
if (self.currentRequestIndex >= self.requests.count) {
if (self.completionHandler != nil) {
self.completionHandler(!self.requestFailed);
}
[self finishOperation];
return;
}
// Send the next request
SDLRPCRequest *request = self.requests[self.currentRequestIndex];
[self.connectionManager sendConnectionRequest:request withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
self.requestsComplete++;
// If this request failed and no request has yet failed, set our internal request failed to YES
if (!self.requestFailed && error != nil) {
self.requestFailed = YES;
}
if (self.progressHandler != NULL) {
BOOL continueWithRemainingRequests = self.progressHandler(request, response, error, self.percentComplete);
// If the user decided to cancel, cancel for our next go around.
if (!continueWithRemainingRequests) {
[self cancel];
}
}
self.currentRequestIndex++;
[self sdl_sendNextRequest];
}];
}
#pragma mark - Getters
- (float)percentComplete {
return (float)self.requestsComplete / (float)self.requests.count;
}
#pragma mark - Property Overrides
- (nullable NSString *)name {
return [NSString stringWithFormat:@"%@ - %@", self.class, self.operationId];
}
- (NSOperationQueuePriority)queuePriority {
return NSOperationQueuePriorityNormal;
}
@end
NS_ASSUME_NONNULL_END
|