summaryrefslogtreecommitdiff
path: root/SmartDeviceLink-iOS/SmartDeviceLink/SDLURLRequestTask.m
blob: d1895ac10220cbad84569b30c74fecbf9dcb10da (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
//
//  SDLURLRequestTask.m
//  SmartDeviceLink-iOS
//
//  Created by Joel Fischer on 8/17/15.
//  Copyright (c) 2015 smartdevicelink. All rights reserved.
//

#import "SDLURLRequestTask.h"

#import "SDLURLSession.h"

NS_ASSUME_NONNULL_BEGIN

@interface SDLURLRequestTask () <NSURLConnectionDelegate, NSURLConnectionDataDelegate>

@property (strong, nonatomic) NSURLConnection *connection;
@property (strong, nonatomic, nullable) NSURLResponse *response;
@property (copy, nonatomic) SDLURLConnectionRequestCompletionHandler completionHandler;
@property (strong, nonatomic) NSMutableData *mutableData;

@end


@implementation SDLURLRequestTask

#pragma mark - Lifecycle

- (instancetype)init {
    NSAssert(NO, @"use initWithURLRequest:completionHandler instead");
    return nil;
}

- (instancetype)initWithURLRequest:(NSURLRequest *)request completionHandler:(SDLURLConnectionRequestCompletionHandler)completionHandler {
    self = [super init];
    if (!self) {
        return nil;
    }

    _connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
    [_connection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    [_connection start];

    _completionHandler = completionHandler;

    _mutableData = [NSMutableData data];
    _response = nil;
    _state = SDLURLRequestTaskStateRunning;

    return self;
}

+ (instancetype)taskWithURLRequest:(NSURLRequest *)request completionHandler:(SDLURLConnectionRequestCompletionHandler)completionHandler {
    return [[self alloc] initWithURLRequest:request completionHandler:completionHandler];
}

- (void)dealloc {
    [_connection cancel];
}


#pragma mark - Data Methods

- (void)sdl_addData:(NSData *)data {
    [self.mutableData appendData:data];
}


#pragma mark - Cancel

- (void)cancel {
    [self.connection cancel];
    [self connection:self.connection didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:kCFURLErrorCancelled userInfo:nil]];
}


#pragma mark - NSURLConnectionDelegate

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    dispatch_async(dispatch_get_main_queue(), ^{
        self.completionHandler(nil, self.response, error);

        self.state = SDLURLRequestTaskStateCompleted;
        [self.delegate taskDidFinish:self];
    });
}


#pragma mark - NSURLConnectionDataDelegate

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [self sdl_addData:data];
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    self.response = response;
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    dispatch_async(dispatch_get_main_queue(), ^{
        self.completionHandler([self.mutableData copy], self.response, nil);

        self.state = SDLURLRequestTaskStateCompleted;
        [self.delegate taskDidFinish:self];
    });
}

@end

NS_ASSUME_NONNULL_END