जिस तरह से मैंने इसे हल किया है, वह मेरे सभी अनुरोधों को एक कोड ब्लॉक से लपेटना है जो आवश्यक होने पर पहुंच टोकन को रीफ्रेश करेगा।
सफलता और विफलता के ब्लॉकों के लिए कुछ typedefs जोड़ें:
typedef void (^YFRailsSaasApiClientSuccess)(AFJSONRequestOperation *operation, id responseObject);
typedef void (^YFRailsSaasApiClientFailure)(AFJSONRequestOperation *operation, NSError *error);
फिर अनुरोध विधि है:
- (void)getProductsWithSuccess:(YFRailsSaasApiClientSuccess)success failure:(YFRailsSaasApiClientFailure)failure {
NSLog(@"getProductsWithSuccess");
success = ^(AFJSONRequestOperation *operation, id responseObject) {
[self getPath:@"api/1/products"
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"getProductsWithSuccess: success");
// TODO: handle response
if (success) {
success((AFJSONRequestOperation *)operation, responseObject);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"getProductsWithSuccess: failure");
if (failure) {
failure((AFJSONRequestOperation *)operation, error);
}
}];
};
[self refreshAccessTokenWithSuccess:success failure:failure];
}
और तरीका है जो टोकन समाप्ति के लिए जाँच करता है और यह ताज़ा करता है अगर जरूरत है:
- (void)refreshAccessTokenWithSuccess:(YFRailsSaasApiClientSuccess)success failure:(YFRailsSaasApiClientFailure)failure {
NSLog(@"refreshAccessTokenWithSuccess");
if (self.credential == nil) {
if (failure) {
NSMutableDictionary *errorDetail = [NSMutableDictionary dictionary];
[errorDetail setValue:@"Failed to get credentials" forKey:NSLocalizedDescriptionKey];
NSError *error = [NSError errorWithDomain:@"world" code:200 userInfo:errorDetail];
failure(nil, error);
}
return;
}
if (!self.credential.isExpired) {
NSLog(@"refreshAccessTokenWithSuccess: credential has not expired");
if (success) {
success(nil, nil);
}
return;
}
NSLog(@"refreshAccessTokenWithSuccess: refreshing credential");
[self authenticateUsingOAuthWithPath:@"oauth/token"
refreshToken:self.credential.refreshToken
success:^(AFOAuthCredential *newCredential) {
NSLog(@"Successfully refreshed OAuth credentials %@", newCredential.accessToken);
self.credential = newCredential;
[AFOAuthCredential storeCredential:newCredential
withIdentifier:self.serviceProviderIdentifier];
if (success) {
success(nil, nil);
}
}
failure:^(NSError *error) {
NSLog(@"An error occurred refreshing credential: %@", error);
if (failure) {
failure(nil, error);
}
}];
}
पूर्ण स्रोत कोड गिटहब पर है: https://github.com/yellowfeather/rails-saas-ios।
इसके अलावा, आप संपत्ति के सेटटर को प्रमाण पत्र के भंडारण को स्थानांतरित कर सकते हैं। – conradev
ऐसा प्रतीत होता है कि यह टोकन पर expires_in पर निर्भर करता है जो मानता है कि आपकी घड़ी नेटवर्क अंतराल के बाद भी सिंक्रनाइज़ेशन में काफी निकटता से है (जो कोई समस्या हो सकती है या नहीं) और यह कि आपका सर्वर वास्तव में expires_in मान सेट करता है अच्छी तरह। expires_in की सिफारिश की जाती है, लेकिन spec में आवश्यक नहीं है। यह इंगित करता है कि उन सर्वरों पर जो expires_in का समर्थन नहीं करते हैं, टोकन के अनुरोध पर त्रुटि प्राप्त होने के बाद रीफ्रेश किया जाना चाहिए। सामान्य रूप से रीफ्रेश ट्रिगर करने में त्रुटि एक 401 है। बस यह ध्यान रखना चाहता था कि यह समाधान काम कर सकता है, यह हमेशा काम नहीं कर सकता है। – ptoinson
@ptoinson आप सही हैं और मैं इस मुद्दे में भाग रहा हूं, क्या आपके पास साझा करने के लिए कोई कोड नमूना है जो रीफ्रेश करता है और फिर ताज़ा टोकन के साथ अनुरोध भेजता है? मैं AFNetworkingOperationDidFinishNotification का निरीक्षण करने की कोशिश कर रहा हूं लेकिन एक संतोषजनक समाधान के साथ नहीं आ सकता। – Newcode