Skip to content

Commit

Permalink
Merge pull request #969 from stripe/csabol/IOS-773_memory_leaks
Browse files Browse the repository at this point in the history
Reduce NSURLSession memory footprint
  • Loading branch information
csabol-stripe authored Jun 19, 2018
2 parents 6dced23 + d61bb1e commit b17dd12
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 30 deletions.
4 changes: 3 additions & 1 deletion Stripe/STPAPIClient+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ NS_ASSUME_NONNULL_BEGIN


@property (nonatomic, strong, readwrite) NSURL *apiURL;
@property (nonatomic, strong, readwrite) NSURLSession *urlSession;
@property (nonatomic, strong, readonly) NSURLSession *urlSession;

- (NSMutableURLRequest *)configuredRequestForURL:(NSURL *)url;

@end

Expand Down
32 changes: 12 additions & 20 deletions Stripe/STPAPIClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -124,27 +124,26 @@ - (instancetype)initWithConfiguration:(STPPaymentConfiguration *)configuration {
_stripeAccount = configuration.stripeAccount;
_sourcePollers = [NSMutableDictionary dictionary];
_sourcePollersQueue = dispatch_queue_create("com.stripe.sourcepollers", DISPATCH_QUEUE_SERIAL);
_urlSession = [NSURLSession sessionWithConfiguration:[self sessionConfiguration]];
_urlSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
}
return self;
}

- (NSURLSessionConfiguration *)sessionConfiguration {
- (NSMutableURLRequest *)configuredRequestForURL:(NSURL *)url {
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[[self defaultHeaders] enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, __unused BOOL * _Nonnull stop) {
[request setValue:obj forHTTPHeaderField:key];
}];
return request;
}

- (NSDictionary<NSString *, NSString *> *)defaultHeaders {
NSMutableDictionary *additionalHeaders = [NSMutableDictionary new];
additionalHeaders[@"X-Stripe-User-Agent"] = [self.class stripeUserAgentDetails];
additionalHeaders[@"Stripe-Version"] = APIVersion;
additionalHeaders[@"Authorization"] = [@"Bearer " stringByAppendingString:self.apiKey ?: @""];
additionalHeaders[@"Stripe-Account"] = self.stripeAccount;
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfiguration.HTTPAdditionalHeaders = additionalHeaders;
return sessionConfiguration;
}

- (void)setApiKey:(NSString *)apiKey {
_apiKey = apiKey;

// Regenerate url session configuration
self.urlSession = [NSURLSession sessionWithConfiguration:[self sessionConfiguration]];
return [additionalHeaders copy];
}

- (void)setPublishableKey:(NSString *)publishableKey {
Expand All @@ -156,13 +155,6 @@ - (NSString *)publishableKey {
return self.configuration.publishableKey;
}

- (void)setStripeAccount:(NSString *)stripeAccount {
_stripeAccount = stripeAccount;

// Regenerate url session configuration
self.urlSession = [NSURLSession sessionWithConfiguration:[self sessionConfiguration]];
}

- (void)createTokenWithParameters:(NSDictionary *)parameters
completion:(STPTokenCompletionBlock)completion {
NSCAssert(parameters != nil, @"'parameters' is required to create a token");
Expand Down Expand Up @@ -342,7 +334,7 @@ - (void)uploadImage:(UIImage *)image
NSString *boundary = [STPMultipartFormDataEncoder generateBoundary];
NSData *data = [STPMultipartFormDataEncoder multipartFormDataForParts:@[purposePart, imagePart] boundary:boundary];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:FileUploadURL]];
NSMutableURLRequest *request = [self configuredRequestForURL:[NSURL URLWithString:FileUploadURL]];
[request setHTTPMethod:@"POST"];
[request stp_setMultipartFormData:data boundary:boundary];

Expand Down
6 changes: 3 additions & 3 deletions Stripe/STPAPIRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ + (NSURLSessionDataTask *)postWithAPIClient:(STPAPIClient *)apiClient
NSURL *url = [apiClient.apiURL URLByAppendingPathComponent:endpoint];

// Setup request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
NSMutableURLRequest *request = [apiClient configuredRequestForURL:url];
request.HTTPMethod = HTTPMethodPOST;
[request stp_setFormPayload:parameters];

Expand All @@ -66,7 +66,7 @@ + (NSURLSessionDataTask *)getWithAPIClient:(STPAPIClient *)apiClient
NSURL *url = [apiClient.apiURL URLByAppendingPathComponent:endpoint];

// Setup request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
NSMutableURLRequest *request = [apiClient configuredRequestForURL:url];
[request stp_addParametersToURL:parameters];
request.HTTPMethod = HTTPMethodGET;

Expand Down Expand Up @@ -98,7 +98,7 @@ + (NSURLSessionDataTask *)deleteWithAPIClient:(STPAPIClient *)apiClient
NSURL *url = [apiClient.apiURL URLByAppendingPathComponent:endpoint];

// Setup request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
NSMutableURLRequest *request = [apiClient configuredRequestForURL:url];
[request stp_addParametersToURL:parameters];
request.HTTPMethod = HTTPMethodDELETE;

Expand Down
12 changes: 6 additions & 6 deletions Tests/Tests/STPAPIClientTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,25 +34,25 @@ - (void)testSetDefaultPublishableKey {

- (void)testInitWithPublishableKey {
STPAPIClient *sut = [[STPAPIClient alloc] initWithPublishableKey:@"pk_foo"];
NSString *authHeader = sut.urlSession.configuration.HTTPAdditionalHeaders[@"Authorization"];
NSString *authHeader = [sut configuredRequestForURL:[NSURL URLWithString:@"https://www.stripe.com"]].allHTTPHeaderFields[@"Authorization"];
XCTAssertEqualObjects(authHeader, @"Bearer pk_foo");
}

- (void)testSetPublishableKey {
STPAPIClient *sut = [[STPAPIClient alloc] initWithPublishableKey:@"pk_foo"];
NSString *authHeader = sut.urlSession.configuration.HTTPAdditionalHeaders[@"Authorization"];
NSString *authHeader = [sut configuredRequestForURL:[NSURL URLWithString:@"https://www.stripe.com"]].allHTTPHeaderFields[@"Authorization"];
XCTAssertEqualObjects(authHeader, @"Bearer pk_foo");
sut.publishableKey = @"pk_bar";
authHeader = sut.urlSession.configuration.HTTPAdditionalHeaders[@"Authorization"];
authHeader = [sut configuredRequestForURL:[NSURL URLWithString:@"https://www.stripe.com"]].allHTTPHeaderFields[@"Authorization"];
XCTAssertEqualObjects(authHeader, @"Bearer pk_bar");
}

- (void)testSetStripeAccount {
STPAPIClient *sut = [[STPAPIClient alloc] initWithPublishableKey:@"pk_foo"];
NSString *accountHeader = sut.urlSession.configuration.HTTPAdditionalHeaders[@"Stripe-Account"];
NSString *accountHeader = [sut configuredRequestForURL:[NSURL URLWithString:@"https://www.stripe.com"]].allHTTPHeaderFields[@"Stripe-Account"];
XCTAssertNil(accountHeader);
sut.stripeAccount = @"acct_123";
accountHeader = sut.urlSession.configuration.HTTPAdditionalHeaders[@"Stripe-Account"];
accountHeader = [sut configuredRequestForURL:[NSURL URLWithString:@"https://www.stripe.com"]].allHTTPHeaderFields[@"Stripe-Account"];
XCTAssertEqualObjects(accountHeader, @"acct_123");
}

Expand All @@ -63,7 +63,7 @@ - (void)testInitWithConfiguration {
STPAPIClient *sut = [[STPAPIClient alloc] initWithConfiguration:config];
XCTAssertEqualObjects(sut.publishableKey, config.publishableKey);
XCTAssertEqualObjects(sut.stripeAccount, config.stripeAccount);
NSString *accountHeader = sut.urlSession.configuration.HTTPAdditionalHeaders[@"Stripe-Account"];
NSString *accountHeader = [sut configuredRequestForURL:[NSURL URLWithString:@"https://www.stripe.com"]].allHTTPHeaderFields[@"Stripe-Account"];
XCTAssertEqualObjects(accountHeader, @"acct_123");
}

Expand Down
24 changes: 24 additions & 0 deletions Tests/Tests/STPAPIRequestTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ - (void)testPostWithAPIClient {
STPAPIClient *apiClientMock = OCMClassMock([STPAPIClient class]);
OCMStub([apiClientMock apiURL]).andReturn([NSURL URLWithString:@"https://api.stripe.com"]);
OCMStub([apiClientMock urlSession]).andReturn(urlSessionMock);
OCMStub([apiClientMock configuredRequestForURL:[OCMArg isKindOfClass:[NSURL class]]]).andDo(^(NSInvocation *invocation)
{
NSURL *urlArg;
[invocation getArgument:&urlArg atIndex:2];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:urlArg];
[invocation setReturnValue:&request];
[invocation retainArguments];
});

id apiRequestMock = OCMClassMock([STPAPIRequest class]);
OCMStub([apiRequestMock parseResponse:[OCMArg any]
Expand Down Expand Up @@ -117,6 +125,14 @@ - (void)testGetWithAPIClient {
STPAPIClient *apiClientMock = OCMClassMock([STPAPIClient class]);
OCMStub([apiClientMock apiURL]).andReturn([NSURL URLWithString:@"https://api.stripe.com"]);
OCMStub([apiClientMock urlSession]).andReturn(urlSessionMock);
OCMStub([apiClientMock configuredRequestForURL:[OCMArg isKindOfClass:[NSURL class]]]).andDo(^(NSInvocation *invocation)
{
NSURL *urlArg;
[invocation getArgument:&urlArg atIndex:2];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:urlArg];
[invocation setReturnValue:&request];
[invocation retainArguments];
});

id apiRequestMock = OCMClassMock([STPAPIRequest class]);
OCMStub([apiRequestMock parseResponse:[OCMArg any]
Expand Down Expand Up @@ -185,6 +201,14 @@ - (void)testDeleteWithAPIClient {
STPAPIClient *apiClientMock = OCMClassMock([STPAPIClient class]);
OCMStub([apiClientMock apiURL]).andReturn([NSURL URLWithString:@"https://api.stripe.com"]);
OCMStub([apiClientMock urlSession]).andReturn(urlSessionMock);
OCMStub([apiClientMock configuredRequestForURL:[OCMArg isKindOfClass:[NSURL class]]]).andDo(^(NSInvocation *invocation)
{
NSURL *urlArg;
[invocation getArgument:&urlArg atIndex:2];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:urlArg];
[invocation setReturnValue:&request];
[invocation retainArguments];
});

id apiRequestMock = OCMClassMock([STPAPIRequest class]);
OCMStub([apiRequestMock parseResponse:[OCMArg any]
Expand Down

0 comments on commit b17dd12

Please sign in to comment.