summaryrefslogtreecommitdiff
path: root/SmartDeviceLink/private/SDLSequentialRPCRequestOperation.m
blob: 9fb3489868429d126dbd2cad4b8c832dfcaef40f (plain)
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
125
126
127
128
129
130
//
//  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) {
        if (completionHandler != nil) {
            completionHandler(NO);
        }
        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];
    if (self.isCancelled) { return; }

    [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:(__kindof SDLRPCRequest *)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