aby rozwinąć/aktualizacji @ odpowiedź Kasik użytkownika. Można utworzyć kategorię na AFNetworking jak tak wykorzystaniem semaforów:
@implementation AFHTTPSessionManager (AFNetworking)
- (id)sendSynchronousRequestWithBaseURLAsString:(NSString * _Nonnull)baseURL pathToData:(NSString * _Nonnull)path parameters:(NSDictionary * _Nullable)params {
__block id result = nil;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
AFHTTPSessionManager *session = [[AFHTTPSessionManager alloc]initWithBaseURL:[NSURL URLWithString:baseURL]];
[session GET:path parameters:params progress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
result = responseObject;
dispatch_semaphore_signal(semaphore);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
return result;
}
@end
Jeśli dzwonisz synchronizacji blok wewnątrz bloku realizacji innego wniosku AFNetwork, upewnij się zmienić właściwość completionQueue
. Jeśli go nie zmienisz, blok synchroniczny wywoła główną kolejkę po zakończeniu, gdy znajduje się już w głównej kolejce i zawiesi twoją aplikację.
+ (void)someRequest:(void (^)(id response))completion {
AFHTTPSessionManager *session = [[AFHTTPSessionManager alloc]initWithBaseURL:[NSURL URLWithString:@""] sessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
dispatch_queue_t queue = dispatch_queue_create("name", 0);
session.completionQueue = queue;
[session GET:@"path/to/resource" parameters:nil progress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
NSDictionary *data = [session sendSynchronousRequestWithBaseURLAsString:@"" pathToData:@"" parameters:nil ];
dispatch_async(dispatch_get_main_queue(), ^{
completion (myDict);
});
} failure:^(NSURLSessionDataTask *task, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
completion (error);
});
}];
Hej mat, dzięki za odpowiedź. Zwykle używam moich danych asynchronicznie, ale specjalnie w tym celu muszę zwrócić niektóre dane z API, więc naprawdę nie widzę innego sposobu, chyba że możesz polecić jakiś sposób działania? :) –
Zawsze można dodać parametr bloku do metody, np. '-someFunctionWithBlock:^(NSData * data) {...}'. – mattt
Jak powiedziałem, jestem całkiem początkującym z blokami, w jaki sposób to pomoże? (i co ważniejsze, co to znaczy mieć parametr blokowy w metodzie?) –