Swift/OC NSURLSession封装

oc

.h

#import 

NS_ASSUME_NONNULL_BEGIN

typedef void (^Success)(id result);
typedef void (^Failure)(id error);

@interface BaseRequest : NSObject

+ (instancetype)shared;
- (void)requestWithUrl:(NSString *)url
                   get:(BOOL)get
                 param:(NSDictionary *)param
                 token:(NSString *)token
               success:(Success)finshBlock
               failure:(Failure)failed;
@end

NS_ASSUME_NONNULL_END

.m

#import "BaseRequest.h"

@implementation BaseRequest

+ (instancetype)shared {
    static dispatch_once_t onceToken;
    static BaseRequest *instance = nil;
    dispatch_once(&onceToken,^{
        instance = [[super allocWithZone:NULL] init];
    });
    return instance;
}

+ (id)allocWithZone:(struct _NSZone *)zone{
    return [self shared];
}

- (void)requestWithUrl:(NSString *)urlStr
                   get:(BOOL)get
                 param:(NSDictionary *)param
                 token:(NSString *)token
               success:(Success)finshBlock
               failure:(Failure)failed {
    NSString *urlString = [NSString stringWithFormat:@"%@%@", BASE_URL, urlStr];
    NSURL *url = [NSURL URLWithString:urlString];
    url = NSURLByAppendingQueryParameters([NSURL URLWithString:urlString], param);
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    
    request.HTTPMethod = get?@"GET":@"POST";
    if (token) {
        [request addValue:token forHTTPHeaderField:@"Authorization"];
    }
    
    NSURLSession *session = [NSURLSession sharedSession];
    [[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        NSDictionary *result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
        NSLog(@"token:%@\n\n================ %@ %@ ================ \n参数:\n%@ \n", token, get?@"GET":@"POST", urlString, param);
        
        dispatch_async(dispatch_get_main_queue(), ^{
            NSInteger code = [result[@"code"] integerValue];
            if (200 == code) {
                NSDictionary *data = [result objectForKey:@"data"];
                NSLog(@"result:\n\n================result begin================\n%@\n================result end================\n", data);

                if (finshBlock) {
                    finshBlock(data);
                }
            } else {
                failed(result[@"message"]);
            }
        });
    }] resume];
    [session finishTasksAndInvalidate];
}

/**
 Creates a new URL by adding the given query parameters.
*/
static NSURL* NSURLByAppendingQueryParameters(NSURL* URL, NSDictionary* queryParameters) {
    NSString* URLString = [NSString stringWithFormat:@"%@?%@",
        [URL absoluteString],
        NSStringFromQueryParameters(queryParameters)
    ];
    return [NSURL URLWithString:URLString];
}

/**
 This creates a new query parameters string from the given NSDictionary.
*/
static NSString* NSStringFromQueryParameters(NSDictionary* queryParameters) {
    NSMutableArray* parts = [NSMutableArray array];
    [queryParameters enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
        NSString *part = [NSString stringWithFormat: @"%@=%@", [key stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]], [value stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];
        [parts addObject:part];
    }];
    return [parts componentsJoinedByString: @"&"];
}

@end

swift

//
//  BaseRequest.swift
//

import UIKit

let bsRequest = BaseRequest()

//typealias FinishBlock = (Any) -> ()

class BaseRequest {
    func requestWithUrl(_ urlStr: String,
                        param: [String: String],
                        get: Bool = true,
                        token: String = "",
                        success: @escaping (Any) -> (),
                        failure: @escaping (Any) -> ()) {
        
        let bsUrl = "https://abc.cn/"
        guard var url = URL(string: bsUrl+urlStr) else {
            failure("url错误")
            return
        }
        
        url = url.appendingQueryParameters(param)
        var request = URLRequest(url: url)
        request.httpMethod = get ? "GET" : "POST"
        request.addValue(token, forHTTPHeaderField: "Authorization")
        
        let sessionConfig = URLSessionConfiguration.default
        let session = URLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil)
        session.dataTask(with: request, completionHandler: { (data: Data?, response: URLResponse?, error: Error?) -> Void in
            if (error == nil) {
                // Success
                let statusCode = (response as! HTTPURLResponse).statusCode
                if 200 != statusCode {
                    failure("状态码\(statusCode)")
                    return
                }
                
                guard let rspData = data else { return }
                guard let dic = try? JSONSerialization.jsonObject(with: rspData, options: []) as? [String: Any] else {
                    failure("data错误")
                    return
                }
                
                guard let data = dic["data"] as? [String: Any] else {
                    failure("data错误")
                    return
                }
                
                success(data)
            }
            else {
                // Failure
                print("URL Session Task Failed: %@", error!.localizedDescription);
                failure(error ?? "a")
            }
        }).resume()
        session.finishTasksAndInvalidate()
    }
}

//
// MARK: - URLQueryParameterStringConvertible
//
protocol URLQueryParameterStringConvertible {
    var queryParameters: String {get}
}
extension Dictionary : URLQueryParameterStringConvertible {
    var queryParameters: String {
        var parts: [String] = []
        for (key, value) in self {
            let part = String(format: "%@=%@",
                String(describing: key).addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!,
                String(describing: value).addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!)
            parts.append(part as String)
        }
        return parts.joined(separator: "&")
    }
}
extension URL {
    func appendingQueryParameters(_ parametersDictionary : Dictionary) -> URL {
        let URLString : String = String(format: "%@?%@", self.absoluteString, parametersDictionary.queryParameters)
        return URL(string: URLString)!
    }
}

你可能感兴趣的:(Swift/OC NSURLSession封装)