summaryrefslogtreecommitdiff
path: root/SmartDeviceLink/SDLSequentialRPCRequestOperation.m
blob: 142812d404330c02cffab9f11b0bb236998740ab (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
//
//  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