使用 xCode 进行异步调用

用户2908751

我有另一个与 xCode 相关的初学者问题。我对 iOS 开发完全陌生,所以我感谢你们回复我。

我编写了以下类来访问 Restful API。如果我直接在调用方法中编写“makePostRequest”方法中的代码,它就可以正常工作。但是,我想让它异步,我不知道如何使这项工作异步。有人可以帮我把它写成异步调用吗?

#import <Foundation/Foundation.h>
#import "ServerRequest.h"
#import "NetworkHelper.h"

@implementation ServerRequest

@synthesize authorizationRequest=_authorizationRequest;
@synthesize responseContent=_responseContent;
@synthesize errorContent=_errorContent;
@synthesize url=_url;
@synthesize urlPart=_urlPart;
@synthesize token=_token;

- (void)makePostRequest : (NSString *) params   {
    NSString *urlString = [NSString stringWithFormat:@"%@%@", [self getUrl], [self getUrlPart]];

    NSURL *url = [NSURL URLWithString:urlString];
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];

    NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:nil delegateQueue:[NSOperationQueue mainQueue]];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request setHTTPMethod:@"POST"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];

    if([self isAuthorizationRequest])    {
        [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
        [request setValue:@"Basic" forHTTPHeaderField:@"Authorization"];
    }
    else    {
        NSString *authorizationValue = [NSString stringWithFormat:@"Bearer %@", [self getToken]];
        [request setValue:authorizationValue forHTTPHeaderField:@"Authorization"];
    }

    if(params.length > 0)
        [request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];

    @try {
        NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                                    completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)  {
                                                        if(error)   {
                                                            NSLog(@"Error: %@", error);
                                                        }
                                                        if([response isKindOfClass:[NSHTTPURLResponse class]])  {
                                                            NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
                                                            if(statusCode == [NetworkHelper HTTP_STATUS_CODE])  {
self.responseContent = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves
error:nil];
                                                            }
                                                            else    {
self.errorContent = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves
error:nil];
                                                            }
                                                        }
                                                    }];
        [dataTask resume];
    }

    @catch (NSException *exception) {
        NSLog(@"Exception while making request: %@", exception);
    } @finally {
        NSLog(@"finally block here");
    }
}

- (void)setAuthorization : (bool)value  {
    self.authorizationRequest = &value;
}

- (bool)isAuthorizationRequest  {
    return self.authorizationRequest;
}

- (NSDictionary *)getResponseContent    {
    return self.responseContent;
}

- (NSDictionary *)getErrorContent   {
    return self.errorContent;
}

- (void)setToken:(NSString *)token  {
    self.token = token;
}

- (NSString *)getToken  {
    return self.token;
}

- (void)setUrl:(NSString *)value  {
    //self.url = value;
    _url = value;
}

- (NSString *)getUrl    {
    return self.url;
}

- (void)setUrlPart:(NSString *)value  {
    self.urlPart = value;
}

- (NSString *)getUrlPart    {
    if(self.urlPart.length == 0)
        return @"";

    return self.urlPart;
}

@end
奈姆

我给你一个例子,你可以如何让你的方法在可用时为你提供数据。它是block基于。所以你不必在这里考虑异步任务。

首先在您的 中定义您的完成块ServerRequest.h

typedef void(^myCompletion)(NSDictionary*, NSError*);

并将您的方法的签名更改为:

- (void) makePostRequest:(NSString *)params completion: (myCompletion)completionBlock;

现在将您的方法的实现更改为这样的(我只是发布您的@try块,所以只需更改您的 try 块。其他保持不变)

@try {
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                                completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)  {
                                                    if(error) {
                                                        NSLog(@"Error: %@", error);
                                                        if (completionBlock) {
                                                            completionBlock(nil, error);
                                                        }
                                                    }
                                                    if([response isKindOfClass:[NSHTTPURLResponse class]]) {
                                                        NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
                                                        if(statusCode == [NetworkHelper HTTP_STATUS_CODE]) {
                                                            NSError *error;
                                                            self.responseContent = [NSJSONSerialization JSONObjectWithData:data
                                                                                                                   options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves
                                                                                                                     error:&error];
                                                            if (completionBlock) {
                                                                if (error == nil) {
                                                                    completionBlock(self.responseContent, nil);
                                                                } else {
                                                                    completionBlock(nil, error);
                                                                }
                                                            }
                                                        } else {
                                                            NSError *error;
                                                            self.errorContent = [NSJSONSerialization JSONObjectWithData:data
                                                                                                                options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves
                                                                                                                  error:&error];
                                                            if (completionBlock) {
                                                                if (error == nil) {
                                                                    completionBlock(self.errorContent, nil);
                                                                } else {
                                                                    completionBlock(nil, error);
                                                                }
                                                            }
                                                        }
                                                    }
                                                }];
    [dataTask resume];
}

最后,当您从其他地方调用此方法时,请将其用作:

[serverRequestObject makePostRequest:@"your string" completion:^(NSDictionary *dictionary, NSError *error) {
    // when your data is available after NSURLSessionDataTask's job, you will get your data here
    if (error != nil) {
        // Handle your error
    } else {
        // Use your dictionary here
    }
}];

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用Java线程进行异步调用

如何使用HtmlAgilityPack进行异步调用?

如何使用HtmlAgilityPack进行异步调用?

使用livedata进行Zip 4或更多异步调用

如何使用 $promise 在 angularJS 中进行异步调用?

React Actions 使用 RxJS 进行并行异步调用

如何使用AngularJs和Typescript进行异步调用

玩笑Vue-使用异步调用进行测试

使用 react native 和 redux 进行异步调用,thunk

使用cljs-ajax进行异步调用

如何使用Express和Node进行异步调用

在PCL中使用HttpClient进行异步调用

使用React.useMemo进行异步调用

使用Rx Java Observable一次进行多个异步调用(触发并忘记调用)

如何使用okhttp进行异步调用以将响应返回到主线程?

在 Typescript React 中使用相同的参数进行条件异步调用

可以使用useEffect对一个异步调用的完成顺序进行排序吗?

使用事件发射器和服务进行跨组件通信的角度异步调用

如何使用async和await关键字进行异步调用

RxSwift-使用两个可观察的对象进行异步调用

使用promise和defer在angularJS中进行同步和异步调用

使用Oracle.DataAccess(ODAC)在C#中进行异步调用

如何在axest中正确使用axios.get.mockResolvedValue进行异步调用

使用Boost.Process进行异步调用std :: future.get()后,程序挂起

如何使用async / await进行一对一的异步调用?

使用axios.CancelToken之后如何进行异步调用?

使用C#中的同步门面进行异步调用的代理

Flink 有状态函数,使用 python SDK 进行异步调用

Angular 异步调用 api 并使用结果