iOS 에서 개발 한 NSURLProtocol 의 구 덩이 를 자세히 알 아 보 세 요.
6018 단어 iOSNSURLProtocol
NSURLProtocol 은 애플 의 URL 로 딩 시스템(URL Loading System)의 행동 을 새롭게 정의 할 수 있 습 니 다.URL Loading System 에는 URL 요청 을 처리 하 는 데 사용 되 는 여러 가지 종류 가 있 습 니 다.예 를 들 어 NSURL,NSURLRequest,NSURLConnection 과 NSURLSession 등 입 니 다.URL Loading System 이 NSURLRequest 를 사용 하여 자원 을 가 져 올 때 NSURLProtocol 하위 클래스 의 인 스 턴 스 를 만 듭 니 다.NSURLProtocol 을 직접 예화 해 서 는 안 됩 니 다.NSURLProtocol 은 프로 토 콜 처럼 보이 지만 사실은 이것 은 클래스 이 며,이러한 하위 클래스 를 사용 해 야 하 며,등록 되 어야 합 니 다.
필드 사용
UIWebView,NSURLConnection 또는 제3자 라 이브 러 리(AFNetworking,MKNetwork Kit 등)를 통 해 든 NSURLConnection 또는 NSURLSession 을 기반 으로 이 루어 지기 때문에 NSURLProtocol 을 통 해 사용자 정의 작업 을 할 수 있 습 니 다.
네트워크 요청
네트워크 요청 무시,로 컬 캐 시 사용사용자 정의 네트워크 요청 의 반환 결과전체 네트워크 요청 설정
iOS 시스템 에서 URL Loading System 을 접 한 적 이 있 습 니 다.NSURLProtocol 은 이렇게 강력 합 니 다.응용 프로그램 에 있 는 거의 모든 네트워크 요청 을 차단 할 수 있 고 요청 헤드 를 수정 할 수 있 으 며 client 가 임의로 사용자 정의 한 데 이 터 를 되 돌려 줄 수 있 습 니 다.많은 네트워크 저장 소 는 이런 종 류 를 이용 한 것 이 라 고 합 니 다.
그럼 우선 NSURLProtocol 을 어떻게 사용 하 는 지 설명해 주세요.
1.NSURLProtocol 의 하위 클래스 정의
NSURLProtocol 계승 에서 우 리 는 실현 해 야 한다.
+(BOOL)canInitWithRequest:(NSURLRequest*)request,요청 을 차단 하 는 URL 규칙 정의
-(void)startLoading,차단 요청 에 대해 시스템 이 NSURLProtocol 대상 을 만 들 고 startLoading 방법 을 실행 하여 로드 요청 을 시작 합 니 다.
-(void)stopLoading,차단 요청 에 대해 NSURLProtocol 대상 이 불 러 오 는 것 을 중지 할 때 이 방법 을 사용 합 니 다.
+(NSURLRequest*)canonicalRequestForRequest:(NSURLRequest*)request,선택 가능 한 방법,요청 헤더 수정 이 필요 한 요청 은 이 방법 에서 수정 합 니 다.
다음 코드 는 https 요청 을 차단 하 는 NSURLProtocol 하위 클래스 를 정의 하고 CFHttpMessage Ref 를 통 해 다시 요청 합 니 다.
@interface CFHttpMessageURLProtocol () <NSStreamDelegate> {
NSMutableURLRequest *curRequest;
NSRunLoop *curRunLoop;
NSInputStream *inputStream;
}
@end
@implementation CFHttpMessageURLProtocol
/**
*
*
* @param request
*
* @return YES , NO
*/
+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
/* , , , , , */
if ([NSURLProtocol propertyForKey:protocolKey inRequest:request]) {
return NO;
}
NSString *url = request.URL.absoluteString;
// url https , ,
if ([url hasPrefix:@"https"]) {
return YES;
}
return NO;
}
/**
* , ,
*/
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
return request;
}
/**
* , ,
*/
- (void)startLoading {
NSMutableURLRequest *request = [self.request mutableCopy];
// ,
[NSURLProtocol setProperty:@(YES) forKey:protocolKey inRequest:request];
curRequest = request;
[self startRequest];
}
/**
*
*/
- (void)stopLoading {
if (inputStream.streamStatus == NSStreamStatusOpen) {
[inputStream removeFromRunLoop:curRunLoop forMode:NSRunLoopCommonModes];
[inputStream setDelegate:nil];
[inputStream close];
}
[self.client URLProtocol:self didFailWithError:[[NSError alloc] initWithDomain:@"stop loading" code:-1 userInfo:nil]];
}
상기 코드 중의 startRequest 방법 은 원본 요청 헤 더 를 복사 하여 CFHttpMessage Ref 를 사용 하여 다시 요청 하 는 것 입 니 다.이 부분 에 관 한 코드 는 본 글 의 내용 과 관계 가 크 지 않 기 때문에 여기 서 놓 지 않 습 니 다.관심 이 있 는 분 들 은 제 다음 블 로 그 를 참고 하 실 수 있 습 니 다.2.네트워크 요청 전에 NSURLProtocol 등록
// NSURLProtocol
[NSURLProtocol registerClass:[CFHttpMessageURLProtocol class]];
NSURLSession 의 요청 에 대해 NSURLProtocol 을 등록 하 는 방식 은 조금 다 르 며 NSURLSession Configuration 을 통 해 등 록 됩 니 다.
// NSURLSession
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSArray *protocolArray = @[ [CFHttpMessageURLProtocol class] ];
configuration.protocolClasses = protocolArray;
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionTask *task = [session dataTaskWithRequest:_request];
[task resume];
3.NSURLProtocol 로그아웃 요청
[NSURLProtocol unregisterClass:[CFHttpMessageURLProtocol class]];
자,이제 NSURLProtocol 의 사용법 에 대해 알 아 보 셨 을 겁 니 다.다음은 NSURLProtocol 이 사용 하 는 과정 에서 만 날 수 있 는 구 덩이 를 설명 하고 자신 과 필요 한 친구 에 게 알림 을 남 깁 니 다.1.위 에서 처음부터 말 했 듯 이 WebView 의 요청 에 대해 NSURLProtocol 은 아직 WKWebView 의 요청 을 차단 할 수 없고 UIWebview 만 차단 할 수 있 지만 후 자 는 App Store 가 심 사 를 통과 시 키 지 못 하 게 한 것 같다(난감 한 얼굴).
2.NSURLProtocol 은 NSURLSession 의 POST 요청 을 차단 할 때 Request 에 있 는 HTTPBody 를 가 져 오지 못 하 는 것 으로 보 입 니 다.이 는 이미 해외 게시판 에 올 라 온 것 같 지만 국내 에 서 는 아직 알려 지지 않 은 것 같 습 니 다.애플 의 공식 설명 에 따 르 면 Body 는 NSData 유형,즉 바 이 너 리 콘 텐 츠 일 수 있 고 크기 제한 이 없 기 때문에 성능 을 고려 하여아예 차단 할 때 는 복사 하지 않 는 다.이 문 제 를 해결 하기 위해 서 우 리 는 바디 데 이 터 를 Header 에 넣 을 수 있 습 니 다.그러나 Header 의 크기 는 제한 이 있 는 것 같 습 니 다.저 는 2M 을 시험 해 보 았 지만 문제 가 없 었 습 니 다.10M 이 넘 으 면 바로 Request timeout 을 했 습 니 다.또한 Body 데이터 가 바 이 너 리 데이터 일 때 이 방법 은 어 쩔 수 없습니다.Header 에 텍스트 데이터 가 있 기 때문에 다른 방안 은 NSDictionary 나 NSCache 로 요청 하지 않 은 Body 데 이 터 를 저장 하고 URL 을 key 로 하 는 것 입 니 다.마지막 방법 은 NSURLSession 을 사용 하지 말고 오래된 NSURLConnection 을 성실 하 게 사용 하 는 것 입 니 다.
3.NSURLProtocol 을 사용 할 때 두 가지 방법 으로 동기 화 네트워크 요청 을 보 낼 수 있 습 니 다.예 를 들 어 startLoading 은 시간 이 초 과 될 때 까지 인 스 턴 스 방법 이 있 는 스 레 드 가 runloop 을 시작 하지 않 았 기 때 문 입 니 다.NSURLConnection 같은 네트워크 요청 은 runloop 에 의존 해 야 하기 때문에 이 요청 은 보 낼 수 없 기 때문에 비동기 요청 을 사용 해 야 합 니 다.NSURLConnection/NSURRLSession 의 비동기 요청 스 레 드 가 runloop 을 시작 하도록 보장 합 니 다.
이상 은 제 가 지금 발견 한 구덩이 입 니 다.여러분 의 보충 을 환영 합 니 다.여러분 의 개발 에 도 도움 이 되 었 으 면 좋 겠 습 니 다.다행히 NSURLProtocol 은 대량 합병 에 대한 지원 이 괜 찮 았 습 니 다.그렇지 않 으 면 버 려 야 합 니 다.여러분 의 학습 에 도움 이 되 었 으 면 좋 겠 습 니 다.여러분 의 많은 응원 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
View의 레이아웃 방법을 AutoLayout에서 따뜻한 손 계산으로 하면 성능이 9.26배로 된 이야기이 기사는 의 15 일째 기사입니다. 어제는 에서 이었습니다. 손 계산을 권하는 의도는 없고, 특수한 상황하에서 계측한 내용입니다 화면 높이의 10 배 정도의 contentView가있는 UIScrollView 레이아...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.