Open danielt1263 opened 8 years ago
Hmm... that's strange, the promise behaviour should be the same on device as on simulator. Could it be that the actual responseObject
is different on the device, thus causing the malfunction?
The response object is identical in both cases. I worked around the issue by rolling the first two success blocks into one, but I don't think I should have to do that.
Just tried with a hardcoded makeRequestWithURL:
that returns a dictionary containing the key path you are using, and on both simulator and device the promise behaved the same. Could you give some more context of the called code, i.e. the makeRequestWithURL:
method? I'm interested with the places in code you are resolving/rejecting the promise.
I'm using AFNetworking and calling into the YouTube v3 API.
Here is my makeRequestWithURL:
method:
- (CKPromise *)makeRequestWithURL:(NSURL *)url {
CKPromise *result = [[CKPromise alloc] init];
AFJSONRequestOperation *jsonRequest = [[AFJSONRequestOperation alloc] initWithRequest: [NSURLRequest requestWithURL: url]];
[self.requests addObject:jsonRequest];
[jsonRequest setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
[result resolve:responseObject];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[result reject:error];
}];
[jsonRequest start];
return result;
}
The initial URL:
NSString *urlString = [NSString stringWithFormat:@"https://www.googleapis.com/youtube/v3/channels?part=contentDetails&forUsername=%@&key=%@", channel, apiKey];
NSURL *url = [NSURL URLWithString:urlString];
The code looks legit, you should have no problems. Are you using the latest CKPromise version?
I'm installing v1.4.6 from cocoapods. CKPromise is working everywhere else I'm using it.... and the code below works so I'm good.
[self makeRequestWithURL:url].success(^(NSDictionary *responseObject){
NSString *playlistId = responseObject[@"items"][0][@"contentDetails"][@"relatedPlaylists"][@"uploads"];
NSString *urlString = [NSString stringWithFormat:@"%@playlistItems?part=snippet&maxResults=50&playlistId=%@&key=%@", youtubeAPI, playlistId, apiKey];
NSURL *url = [NSURL URLWithString:urlString];
return [self makeRequestWithURL:url];
}).success(^(NSDictionary *responseObject){
weakSelf.jsonEntries = [responseObject[@"items"] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [obj1[@"publishedAt"] compare:obj2[@"publishedAt"]] == NSOrderedDescending;
}];
[weakSelf.tableView reloadData];
[weakSelf.progressHUD hide];
}).failure(^(NSError *error){
UIAlertView* alert = [[UIAlertView alloc] initWithTitle: NSLocalizedString(@"Alert", @"AlertTitle") message: @"There was a server error. Please try again later." delegate: nil cancelButtonTitle: NSLocalizedString(@"OK", @"") otherButtonTitles: nil];
[alert show];
[weakSelf.progressHUD hide];
});
It's very strange that it doesn't work for you, I tried with the youtube API and got the behaviour as expected, even with the first implementation (no dictionary instead of string). However this problems inspired me to add a new feature: block signature check and exception throwing if the promise is resolved with another value than the block expects.
I have the following code:
Note the
NSLog(@"playlistId = %@", playlistId);
line...On the simulator, the playlistId is the correct value (an NSString,) but on the device it's an NSDictionary. Again, this code works on the simulator, but not the device. Any help?