iOS 개발 - AFNetWorking 네트워크 연결 상세 설명
18364 단어 iOS 개발
처음에 AF 는 변수 baseURL 까지 알려 주 었 습 니 다. 이 변 수 는 더 봉인 할 때 baseURL 을 자신의 HTTP 요청 원본 주소 로 쓸 수 있 습 니 다. 예 를 들 어
+ (NSURL *)baseURL {
return [NSURL URLWithString:kBaseURLString];
}
baseURL 을 연결 할 때 도 요청 한 URL 에 문제 가 발생 하지 않도록 몇 가지 주의해 야 합 니 다.
NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"];
[NSURL URLWithString:@"foo" relativeToURL:baseURL]; // http://example.com/v1/foo
[NSURL URLWithString:@"foo?bar=baz" relativeToURL:baseURL]; // http://example.com/v1/foo?bar=baz
[NSURL URLWithString:@"/foo" relativeToURL:baseURL]; // http://example.com/foo
[NSURL URLWithString:@"foo/" relativeToURL:baseURL]; // http://example.com/v1/foo
[NSURL URLWithString:@"/foo/" relativeToURL:baseURL]; // http://example.com/foo/
[NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL]; // http://example2.com/
초기 화 하 는 방법 에서 우 리 는 이 방법 을 보 았 다.
- (instancetype)initWithBaseURL:(nullable NSURL *)url
sessionConfiguration:(nullable NSURLSessionConfiguration *)configuration NS_DESIGNATED_INITIALIZER;
NS_DESIGNATED_인 니 티 알 리 제 르. 이게 무슨 뜻 이 죠?이것 은 이러한 종류의 초기 화 방법 이 여러 가지 가 있 음 을 나타 내 는 것 입 니 다. 이 표 시 를 추가 한 후에 시스템 의 init 방법 에서 반드시 이 방법 을 사용 해 야 합 니 다.
- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
parameters:(nullable id)parameters
success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE;
DEPRECATED_ATTRIBUTE 는 여러분 이 많이 보 셨 을 거 라 고 믿 습 니 다. 즉, 이 API 는 개발 자 에 게 다시 사용 하 라 고 건의 하지 않 고 다시 사용 할 때 컴 파일 경고 가 나타 납 니 다.
아래 POST, GET, PUT, PATCH, DELETE 방법 전 삼 은 기본적으로 대동소이 하 다.
URLString 은 요청 한 URL 을 표시 합 니 다. parameters 는 클 라 이언 트 가 요청 한 내용 을 표시 하 는 메모리 입 니 다. progress 는 요청 의 진 도 를 표시 합 니 다. constructing Body With Block 에는 HTTP 요청 체 를 연결 하 는 formData 만 있 습 니 다. success 는 요청 이 성공 한 후의 block 리 셋 을 표시 합 니 다. failure 표 는 요청 이 실패 한 block 리 셋 을 표시 합 니 다.
그렇다면 이 몇 가지 요 구 는 어떤 차이 가 있 습 니까?1. POST 요청 은 서버 에 데 이 터 를 보 내 는 것 으로 자원 정 보 를 업데이트 하 는 데 사 용 됩 니 다. 데이터 의 종류 등 자원 을 변경 할 수 있 습 니 다. 2. GET 요청 은 서버 에 데 이 터 를 요청 하 는 것 으로 자원 정 보 를 얻 거나 조회 하 는 데 사 용 됩 니 다. 3. PUT 요청 과 POST 요청 은 모두 데 이 터 를 보 내 는 것 과 비슷 하지만 PUT 요청 은 데이터 의 종류 등 자원 을 변경 할 수 없습니다. 내용 만 수정 할 수 있 습 니 다. 4.DELETE 요청 은 어떤 자원 을 삭제 하 는 데 사용 되 는 5, PATCH 요청 은 PUT 요청 과 마찬가지 로 데이터 업데이트 에 도 사 용 됩 니 다. 이것 은 HTTP verb 가 업데이트 에 추천 하 는 것 입 니 다.
실제 개발 과정 에서 우 리 는 POST 와 GET 요청 을 가장 많이 사용 했다.
실현 을 요청 하 는 부분 에 서 는 모두 자신의 방법 을 호출 하 였 다.
- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(id)parameters
uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgress
downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgress
success:(void (^)(NSURLSessionDataTask *, id))success
failure:(void (^)(NSURLSessionDataTask *, NSError *))failure;
전 삼 의 내용 은 기본적으로 이전 방법 과 같 습 니 다. method 는 요청 하 는 유형 을 말 합 니 다.
NSError *serializationError = nil;
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];
if (serializationError) {
if (failure) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu"
dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
failure(nil, serializationError);
});
#pragma clang diagnostic pop
}
return nil;
}
__block NSURLSessionDataTask *dataTask = nil;
dataTask = [self dataTaskWithRequest:request
uploadProgress:uploadProgress
downloadProgress:downloadProgress
completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
if (error) {
if (failure) {
failure(dataTask, error);
}
} else {
if (success) {
success(dataTask, responseObject);
}
}
}];
return dataTask;
내부 구현 은 들 어 오 는 URLString 에 따라 request 대상 을 만 든 다음 부모 클래스 의 dataTask With Request 방법 으로 dataTask 작업 을 생 성 하 는 것 입 니 다. 주 는 이렇게 간단 합 니 다.
AFNetworkReachability Manager 는 네트워크 상 태 를 모니터링 하 는 클래스 로 상태 값 은 다음 과 같은 네 가지 가 있 습 니 다.
typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
AFNetworkReachabilityStatusUnknown = -1,//
AFNetworkReachabilityStatusNotReachable = 0,//
AFNetworkReachabilityStatusReachableViaWWAN = 1,//
AFNetworkReachabilityStatusReachableViaWiFi = 2,//WiFi
};
도 메 인 이름 이나 socket 주 소 를 통 해 대상 을 예화 할 수도 있 고, SCNetwork Reachability Ref 대상 을 만들어 대상 을 초기 화 할 수도 있 습 니 다.
+ (instancetype)managerForDomain:(NSString *)domain;
+ (instancetype)managerForAddress:(const void *)address;
- (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability NS_DESIGNATED_INITIALIZER;
그 다음 에 startMonitoring 과 stopMonitoring 을 호출 하여 모니터링 을 시작 하고 끝 냅 니 다. 중간 네트워크 상태 가 변화 하 는 과정 에서 setReachability Status Change Block 을 통 해 네트워크 상 태 를 얻 을 수 있 고 등록 알림 형식 으로 네트워크 상 태 를 받 을 수 있 습 니 다.
- (void)startMonitoring {
[self stopMonitoring];
if (!self.networkReachability) {
return;
}
__weak __typeof(self)weakSelf = self;
AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {
__strong __typeof(weakSelf)strongSelf = weakSelf;
strongSelf.networkReachabilityStatus = status;
if (strongSelf.networkReachabilityStatusBlock) {
strongSelf.networkReachabilityStatusBlock(status);
}
};
SCNetworkReachabilityContext context = {0, (__bridge void *)callback, AFNetworkReachabilityRetainCallback, AFNetworkReachabilityReleaseCallback, NULL};
SCNetworkReachabilitySetCallback(self.networkReachability, AFNetworkReachabilityCallback, &context);
SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{
SCNetworkReachabilityFlags flags;
if (SCNetworkReachabilityGetFlags(self.networkReachability, &flags)) {
AFPostReachabilityStatusChange(flags, callback);
}
});
}
네트워크 상 태 를 모니터링 할 때 먼저 자신의 네트워크 상태의 block 리 셋 을 설정 한 다음 에 SCNetworkReachability Context 구조 체 를 만 듭 니 다. 첫 번 째 매개 변 수 는 버 전 번호 이 고 값 은 0 이 며 두 번 째 매개 변 수 는 info 는 데이터 block 리 셋 을 가리 키 는 c 지침 입 니 다. 세 번 째 매개 변 수 는 retain 을 통 해 데 이 터 를 한 번 더 보존 합 니 다.이 값 은 null 일 수 있 습 니 다. 네 번 째 매개 변수 release 는 리 셋 을 통 해 제거 되 고 다섯 번 째 매개 변수 description 은 데 이 터 를 제공 하 는 설명 입 니 다.그 다음 에 리 셋 을 설정 하여 runloop 에 추가 하여 이 를 감 측 하고 배경 스 레 드 에서 변 화 를 발견 할 때 네트워크 상태 변 화 를 보 냅 니 다.
AFSecurity Policy 는 보안 정책 류 로 세 가지 SSL Pinning 모드 가 있 습 니 다.
typedef NS_ENUM(NSUInteger, AFSSLPinningMode) {
AFSSLPinningModeNone,//
AFSSLPinningModePublicKey,//
AFSSLPinningModeCertificate,//
};
@property (nonatomic, strong, nullable) NSSet *pinnedCertificates;
이것 은 인증서 집합 입 니 다. 범 형 에 서 는 집합 이 NSData 형식 임 을 표시 합 니 다. 이것 은 인증서 데 이 터 를 저장 하 는 집합 임 을 나타 냅 니 다. 이 인증 서 는 SSL Pinning 모드 에 따라 서버 와 검 사 를 합 니 다. 기본적으로 인증서 가 없습니다. certificates InBundle 을 호출 해 야 합 니 다. 방법 은 bundle 에 있 는 인증서 파일 을 data 형식의 집합 으로 변환 합 니 다.
+ (instancetype)defaultPolicy;
+ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode;
+ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode withPinnedCertificates:(NSSet *)pinnedCertificates;
세 가지 실례 화 방법 이 있 습 니 다. 하 나 는 기본 정책 입 니 다. AFSSLPinning ModeNone 입 니 다. 두 번 째 는 보안 정책 을 사용자 정의 한 다음 에 현재 종류의 bundle 을 가 져 와 cer 파일 생 성 집합 을 읽 고 세 번 째 는 인증서 집합 이 필요 합 니 다.
AFURLRequestSerialization 은 URL 요청 을 처리 하 는 데 사 용 됩 니 다.
URL 안의 특수 문 자 를 백분율 로 바 꿉 니 다:
FOUNDATION_EXPORT NSString * AFPercentEscapedStringFromString(NSString *string);
사전 의 key / value 값 을% @ =% @ 로 조립 하고 & 로 구분 하 는 형식:
FOUNDATION_EXPORT NSString * AFQueryStringFromParameters(NSDictionary *parameters);
AFHTTPRequestSerializer 에 헤더 정 보 를 설정 하 는 방법 이 있 습 니 다.
- (void)setValue:(nullable NSString *)value
forHTTPHeaderField:(NSString *)field;
이 value 가 비어 있 을 때 삭제 처리 로 사 용 됩 니 다. 존재 하 는 요청 헤 더 를 삭제 합 니 다. 비어 있 지 않 을 때 새로운 요청 헤 더 를 추가 하거나 존재 하 는 요청 헤 더 를 설정 합 니 다.
- (void)setAuthorizationHeaderFieldWithUsername:(NSString *)username
password:(NSString *)password;
사용자 이름, 비밀 번 호 를 정보 로 요청 헤더 로 설정 합 니 다. 그 안에 사용자 이름 비밀 번 호 를 data 로 맞 춘 다음 base 64 인 코딩 형식 으로 문자열 로 바 꾼 다음 요청 헤더 의 내용 으로 설정 합 니 다.
요청 을 만 드 는 방법 은 세 가지 가 있 습 니 다.
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(nullable id)parameters
error:(NSError * _Nullable __autoreleasing *)error;
- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(nullable NSDictionary *)parameters
constructingBodyWithBlock:(nullable void (^)(id formData))block
error:(NSError * _Nullable __autoreleasing *)error;
- (NSMutableURLRequest *)requestWithMultipartFormRequest:(NSURLRequest *)request
writingStreamContentsToFile:(NSURL *)fileURL
completionHandler:(nullable void (^)(NSError * _Nullable error))handler;
method 는 GET, POST 등 요청 하 는 방법 을 말 합 니 다. URLString 은 요청 URL 을 만 드 는 문자열 입 니 다. parameters 는 GET 가 요청 한 조회 필드 나 요청 한 HTTP 체 입 니 다. request 는 HTTP Body Stream 의 인 스 턴 스 변수 request 이 고 fileURL 은 파일 URL 입 니 다.
- (BOOL)appendPartWithFileURL:(NSURL *)fileURL
name:(NSString *)name
error:(NSError * _Nullable __autoreleasing *)error;
- (BOOL)appendPartWithFileURL:(NSURL *)fileURL
name:(NSString *)name
fileName:(NSString *)fileName
mimeType:(NSString *)mimeType
error:(NSError * _Nullable __autoreleasing *)error;
파일 데이터 에 따라 HTTP 헤드 를 연결 합 니 다. fileURL 은 파일 의 URL 입 니 다. name 은 데이터 의 이름 을 말 합 니 다. fileName 은 파일 의 이름 입 니 다. fileURL 에 따라 마지막 부분의 파일 이름 을 얻 을 수 있 습 니 다. mimeType 은 파일 데이터 의 mime 형식 입 니 다. 파일 의 접두사 에 따라 AFContentType ForPathExtension 방법 을 사용 하여 얻 을 수 있 습 니 다.
static inline NSString * AFContentTypeForPathExtension(NSString *extension) {
NSString *UTI = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)extension, NULL);
NSString *contentType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)UTI, kUTTagClassMIMEType);
if (!contentType) {
return @"application/octet-stream";
} else {
return contentType;
}
}
먼저 접미사 에 따라 유형 표 지 를 만 든 다음 에 유형 표 지 를 mime 형식 으로 바 꾸 고 해당 하 는 유형 이 있 으 면 application / ocket - stream 으로 돌아 갑 니 다. 그렇지 않 으 면 contentType 으로 돌아 갑 니 다.
- (void)throttleBandwidthWithPacketSize:(NSUInteger)numberOfBytes
delay:(NSTimeInterval)delay;
3G 또는 E 네트워크 환경 에서 스 트림 요청 시 업로드 에 실패 할 수 있 습 니 다. 따라서 저 희 는 요청 의 대역 폭 과 지연 시간 을 설정 하여 문 제 를 해결 할 수 있 습 니 다. numberOfBytes 는 바이트 크기 이 고 기본 값 은 16kb 이 며 delay 는 지연 시간 이 없습니다. 기본 값 은 지연 시간 이 없습니다.
실행 파일 에 여러 부분 으로 구 성 된 경계 부 호 를 만 드 는 방법 이 있 습 니 다.
static NSString * AFCreateMultipartFormBoundary() {
return [NSString stringWithFormat:@"Boundary+%08X%08X", arc4random(), arc4random()];
}
여기에 랜 덤 수 를 만 드 는 방법 인 arc4random () 을 사용 합 니 다. oc 에는 랜 덤 수 를 만 드 는 방법 인 random () 이 있 습 니 다. 이 두 가지 방법 은 어떤 차이 가 있 습 니까?우선 arc4random () 의 수치 범 위 는 0x 10000000 (4294967296) 이 고 random () 은 0x7ffffff f (2147483647) 이 며 전 자 는 후자 의 두 배 이 며 정밀도 에서 후자 보다 우수 하 며 random () 을 사용 할 때 자신의 선생 이 무 작위 피 드 가 되 어야 하지만 arc4random () 은 첫 번 째 호출 할 때 자동 으로 생 성 되 어 사용 하기에 도 비교적 편리 하 다.
AFURL Response Serialization 에서 프로 토 콜 을 정의 합 니 다.
- (nullable id)responseObjectForResponse:(nullable NSURLResponse *)response
data:(nullable NSData *)data
error:(NSError * _Nullable __autoreleasing *)error NS_SWIFT_NOTHROW;
서로 다른 유형의 응답 분석 을 처리 하 는 데 사 용 됩 니 다. 그 중에서 각 유형 이 이 협 의 를 실 현 했 습 니 다.
AFJSON Response Serializer 는 기본적으로 이 세 개의 MIME 형식 을 받 아들 입 니 다.
- `application/json`
- `text/json`
- `text/javascript`
AFXMLparser Response Serializer 는 기본적으로 이 두 개의 MIME 형식 을 받 아들 입 니 다.
- `application/xml`
- `text/xml`
AFProperty ListResponsesSerializer 는 기본적으로 이 MIME 형식 을 받 아들 입 니 다.
- `application/x-plist`
AFImageResponse Serializer 는 기본적으로 이 10 개의 MIME 형식 을 받 아들 입 니 다.
- `image/tiff`
- `image/jpeg`
- `image/gif`
- `image/png`
- `image/ico`
- `image/x-icon`
- `image/bmp`
- `image/x-bmp`
- `image/x-xbitmap`
- `image/x-win-bitmap`
AFHTTP Response Serializer 구현 파일 에서
- (BOOL)validateResponse:(NSHTTPURLResponse *)response
data:(NSData *)data
error:(NSError * __autoreleasing *)error
{
BOOL responseIsValid = YES;
NSError *validationError = nil;
if (response && [response isKindOfClass:[NSHTTPURLResponse class]]) {
if (self.acceptableContentTypes && ![self.acceptableContentTypes containsObject:[response MIMEType]]) {
if ([data length] > 0 && [response URL]) {
NSMutableDictionary *mutableUserInfo = [@{
NSLocalizedDescriptionKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Request failed: unacceptable content-type: %@", @"AFNetworking", nil), [response MIMEType]],
NSURLErrorFailingURLErrorKey:[response URL],
AFNetworkingOperationFailingURLResponseErrorKey: response,
} mutableCopy];
if (data) {
mutableUserInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] = data;
}
validationError = AFErrorWithUnderlyingError([NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:mutableUserInfo], validationError);
}
responseIsValid = NO;
}
if (self.acceptableStatusCodes && ![self.acceptableStatusCodes containsIndex:(NSUInteger)response.statusCode] && [response URL]) {
NSMutableDictionary *mutableUserInfo = [@{
NSLocalizedDescriptionKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Request failed: %@ (%ld)", @"AFNetworking", nil), [NSHTTPURLResponse localizedStringForStatusCode:response.statusCode], (long)response.statusCode],
NSURLErrorFailingURLErrorKey:[response URL],
AFNetworkingOperationFailingURLResponseErrorKey: response,
} mutableCopy];
if (data) {
mutableUserInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] = data;
}
validationError = AFErrorWithUnderlyingError([NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorBadServerResponse userInfo:mutableUserInfo], validationError);
responseIsValid = NO;
}
}
if (error && !responseIsValid) {
*error = validationError;
}
return responseIsValid;
}
response 를 검증 하 는 세 가지 절차 가 있 습 니 다. 첫 번 째 단 계 는 response 가 비어 있 는 지 확인 하고 response 가 NSHTTPURL Response 류 인지 판단 하 는 것 입 니 다. 상기 조건 에 부합 되 지 않 으 면 YES 가 유효 합 니 다. 이것 은 이해 가 되 지 않 습 니 다. 나중에 해답 을 찾 으 면 response MIME 형식 이 받 아들 이 는 유형 인지 확인 하 는 두 번 째 단 계 를 업데이트 하 겠 습 니 다.없 으 면 error 세 번 째 단계 에서 받 은 상태 코드 가 존재 하 는 지 확인 합 니 다. 없 으 면 잠재 적 인 error 가 발생 하여 error 의 userInfo 에 넣 습 니 다. key 는 NSUnderlying ErrorKey 입 니 다.
- (id)responseObjectForResponse:(NSURLResponse *)response
data:(NSData *)data
error:(NSError *__autoreleasing *)error
{
[self validateResponse:(NSHTTPURLResponse *)response data:data error:error];
return data;
}
여 기 는 vaidate Response: data: error: 방법 만 호출 되 었 습 니 다. 실제로 들 어 온 data 를 되 돌려 주 는 것 은 하위 클래스 가 response Object ForResponse: data: error: 하위 클래스 의 response Object ForResponse: data: error: 모두 response 의 유효성 을 먼저 검증 한 다음 에 data 를 해당 유형 으로 바 꾼 다음 에 되 돌려 주 는 것 입 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
iOS 아리운 대상 저장 OSS 파일 업로드/다운로드 실현이전 프로젝트에서 이미지 음성 등 자원 파일은 서버에 직접 데이터를 업로드하고 서버에 처리하고 저장했다.최근의 이 프로젝트는 서버가 직접 OSS를 열고 클라이언트가 아리운이 제공하는 업로드 다운로드 기능을 사용하여 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.