각 단말기에는 해당 단말기를 식별하는 유일값인 UDID가 존재합니다. iOS 플랫폼의 경우 SDK 상에서 쉽게 이 UDID 값을 추출할 수 있었습니다. 이 UDID는 사용자의 직접적인 개인정보를 이용하지 않고 사용자의 패턴 분석에서부터 타겟광고 소스 등 여러 부분에서 이용하고 있었습니다만 현재 베타테스트가 진행 중인 iOS5에서는 이 UDID 의 이용은 제한될(deprecated) 예정입니다. 이에 따라 애플에서는 UDID보다는 UUID를 생성하여 이용하라고 권고하고 있습니다. UUID는 단말기의 고유값이 아닌 어플리케이션에서 생성한 유일값으로 생성할 때마다 변경되는 랜덤값입니다. 따라서 개발자분들은 이에 대한 대응을 미리 하시는 것이 좋을 것 같아서 정리해보았습니다.
uniqueIdentifier 메소드가 사라질 예정
UDID는 단말기를 식별하기 위해 고유하게 할당된 40개의 숫자와 문자열입니다. 이런 고유값은 개인정보이다. 아니다 기기 식별값이므로 개인정보는 아니다라는 논란으로 잠시 인터넷이 뜨거웠던 적이 있습니다. (2011/05/10 서울경제 기사, http://economy.hankooki.com/lpage/it/201105/e20110510173640117700.htm)
이 UDID는 구글, 오픈페인트를 비롯한 여러 광고 및 트래픽 분석툴에 사용되고 있는 상황에서 애플이 드디어 칼질을 가하기 시작했습니다. iOS5 beta 6에서는 UDID를 가져올 때 사용하는 메소드를 없애겠다는 의지로 해당 메소드를 deprecated시키고 대신 Core 레벨에서 랜덤한 UUID를 생성하는 메소드를 이용하라는 권고를 내렸습니다. (Apple Sneaks A Big Change Into iOS 5: Phasing Out Developer Access To The UDID :http://techcrunch.com/2011/08/19/apple-ios-5-phasing-out-udid/).
실제로 iOS5 beta 6에서 [[UIDevice currentDevice] uniqueIdentifier]가 포함된 프로젝트를 빌드하면 아래와 같은 경고가 나타납니다.
UDID가 아닌 UUID를 이용하라는 권고
애플에서는 UDID값이 아닌 UUID(Universally Unique Identifiers)를 이용하라는 권고를 내렸습니다. CFUUID Documentation을 참조하면 이 UUID는 128-bit 값으로 생성된 유일값이며 이는 시간과 공간값으로 생성된 유일값이므로 중복될 염려가 없다고 합니다.
이렇게 생성된 UUID를 NSUserDefaults 등을 이용하여 값을 유지시켜줌으로 UDID와 동일한 역할을 하도록 개발자들의 추가 구현이 필요하다라고 문서에는 나와있습니다. 어느 부분에서는 한 줄이면 가능한 유일값 추출을 이제는 개발자가 직접 신경을 써서 관리하라고하니 한숨이 나오는 건 사실입니다.
이렇게 생성된 관리를 위한 방법으로는 NSUserDefaults를 이용하여 앱 내부에서 관리하는 방법, 별도의 서버에 이 값을 저장하여 관리하는 방법, 또는 iOS5 이상의 iCloud를 이용하는 앱이라면 iCloud의 Key-Value Data Storage를 이용하는 방법을 생각해 볼 수 있습니다. 이도 문제가 된다면 Mac Address를 추출하고 이를 해쉬값을 이용(MD5)하는 방법도 최근 iOS 개발자분들이 관심을 가지고 있는 것 같습니다. (GitHub : http://github.com/gekitz/UIDevice-with-UniqueIdentifier-for-iOS-5).
UDID vs. UUID
UDID는 Unique Device Identifier로 기기의 고유값입니다. 하지만 UUID는 앱 자체에서 생성되는 고유값으로 사용자가 사용하는 앱의 고유값으로 볼 수 있습니다. 즉, UUID를 사용하도록 권고하는 것은 단말기의 고유값을 사용하지 말고 앱마다 각자의 고유값을 이용하라는 풀이로 볼 수 있습니다.
이 두 유일값의 장단점을 간략히 살펴보면 아래 표와 같습니다.
당장은 고려하지 않아도 된다?
Deprecated 된 메소드는 아시다시피 현재 사용하지 못한다는 의미는 아니지만 앱스토어에 앱을 등록할 때 리젝 사유가 될 수 있습니다. 위에서 설명드린대로 경고가 항상 나타난다면 당장 대안을 찾아야하는 상황이지만 프로젝트의 Deployment Target을 5.0 이하. 즉, 4.x나 3.x로 한다면 메소드를 사용이 가능합니다. 물론 개발 상에서 사용가능하다는 것이며 정책상으로 어떻게 될지는 모르는 상황입니다.
UDID를 활용하는 서비스나 앱이 많을 것으로 예상됩니다. iOS5가 정식으로 릴리즈되더라도 당장에 사용못하게 하지는 않을 것으로 예상되지만 미리 준비를 해두시는 것이 좋을 것 같습니다.
아래는 Deployment Target을 4.0으로 설정하는 화면과 설정 이후 빌드한 결과 uniqueIdentifier에 경고가 나타나지 않는 화면입니다.
UUID가 아닌 다른 유일값 사용에 대해서
UUID가 아닌 유일값에 대해서는 애플에서는 아직 언급하고 있지 않습니다만 Ethernet의 MAC Address, Bundle identifier 등 여러 대안을 생각해볼 수 있습니다. MAC Address의 경우 Cocoa API에는 추출 메소드가 없어 직접 Core에 접근하여 추출을 해야하며, 해당값을 그대로 사용하는 것이 아닌 MD5나 SHA-1 등의 해쉬를 이용하여 보안이슈가 발생되지 않게 해야합니다. 이로 인해 작업 공수가 더 추가된다는 것, 또한 이후에 애플에서 해당값의 사용을 금지할 수도 있다는 잠재적인 위험요소가 있으므로 되도록이면 애플에서 권장하는 UUID를 이용하는 방법으로 문제를 해결하는 것을 추천해드립니다.
결론
- UDID를 얻어오는 메소드는 iOS5부터 사용할 수 없는, 삭제 예정인 메소드입니다. - 프로젝트의 Deploy Target을 5.0이 아닌 그 이하 버전으로 설정하는 경우에는 UDID 추출 메소드 사용이 가능합니다. - 정책상 결정된 부분은 아니지만 애플의 권고는 UUID를 이용하는 것입니다. - 또한, iOS5가 정식으로 발표된 이후에는 반드시 고려되어야하는 이슈이므로, 미리 이에 대한 대비가 마련되어야 합니다. - UUID도 단말기의 고유값이 아니므로 서비스의 특성에 따라서는 UDID가 아닌 단말기의 고유값으로 간주할 수 있는 MAC Address를 이용하는 방법 등을 고려할 수 있습니다. - UDID를 사용하지 못하는 것과 동일하게 MAC Address도 사용이 불가할 수도 있다는 점은 고려하여 대책 마련을 하시는 것이 좋습니다. - MAC Address를 해쉬처리한 문자열이 단말기의 고유값으로 보는 방안은 애플의 정책에 위배되지 않는다는 가정하에서 현재 단말기의 유일값으로 지정할 수 있는 최상의 방안으로 고려됩니다. (iOS5 정식출시가 되어봐야 알 것 같습니다.)
ASIHTTPRequest을 사용하는 간단한 방법.그것이 완료되면 startSynchronous 메시지 (성공 또는 기타) 컨트롤을 동일한 스레드에서 요청을 실행 및 반환 보내기.
오류 속성을 검사하여 문제가 있는지 확인합니다.
문자열로 응답을 얻으려면 responseString의 메서드를 호출합니다.이진 데이터를 위해 이것을 사용하지 마십시오 - NSData 객체를 얻을 responseData를 사용하거나, 큰 파일의 경우 downloadDestinationPath 재산과 파일 다운로드 요청을 설정합니다.
우리가 요청을 선언할 때 __ 블록 자격을 갖춘 사람의 사용을 참고 이것은 중요하다!이것은 요청이 항상 블록을 유지하기 때문에, 유지 사이클을 방지하는 것이 중요 요청을 유지하지 블록을 알려줍니다.
대기열을 사용하여
이 예제는 다시 똑같은 일을하지만, 우리는 우리의 요청에 대한 NSOperationQueue를 만들었습니다.
사용자가 만든 NSOperationQueue (또는 ASINetworkQueue, 아래 참조)를 사용하여 자신에게 비동기 요청을보다 효율적으로 관리할 수 있습니다.대기열을 사용할 때, 요청에만 특정 숫자가 동시에 실행할 수 있습니다.당신이 대기열의 maxConcurrentOperationCount 재산보다 더 많은 요청을 추가하는 경우 요청들이 시작하기 전에 끝내고 다른 사람을 기다릴 것입니다.
우리는 요청이 성공하거나 실패할 때 호출됩니다 정의 선택자을 설치하고.당신이 이것을 설정하지 않으면 기본값 (requestFinished :와 requestFailed가 :) 이전 예제와 같이 사용됩니다.
대의원 방법에 여러 요청에 대한 성공과 실패 처리
당신이 요청의 여러 유형에 대한 성공과 실패를 제어해야하는 경우, 당신은 몇 가지 옵션이 있습니다 :
귀하의 요청은 같은 광범위한 유형의 모든지만, 당신이 그들을 구별하려는 경우, 당신은 귀하의 완성된 / 실패 대의원 방법으로 읽을 수있는 사용자 정의 데이터로 각 요청의 userInfo NSDictionary 속성을 설정할 수 있습니다.간단한 경우는, 대신 요청의 태그 속성을 설정할 수 있습니다.이러한 속성은 모두 자신 사용할 수 있으며, 서버로 전송되지 않습니다.
당신은 각 요청에 대해 완전히 다른 방식으로 성공과 실패를 처리할 필요가있다면, 각 요청에 대해 다른 setDidFinishSelector / setDidFailSelector를 설정
당신이 백그라운드에서 응답을 구문 분석하려면 좀 더 복잡한 상황, 또는 어디 들면, 요청의 각 유형에 대한 ASIHTTPRequest의 최소한의 하위 클래스를 만들고 requestFinished 무시 :와 failWithError :.
ASINetworkQueues 소개
ASINetworkQueue 몇 가지 추가 기능을 제공 NSOperationQueue의 하위 클래스입니다.
requestDidStartSelector 대기열에서 요청을 시작 때마다 호출됩니다.당신은 didStartSelector를 지정하고 대기열에 추가 요청에 대리인을 설정에 대한 대안으로 사용할 수 있습니다
requestDidReceiveResponseHeadersSelector 매번 호출 대기열에서 요청 서버에서 응답 헤더를받습니다.요청이 실제로 완료하기 전에 대용량 다운로드의 경우이 시간이 좀있을 수 있습니다.당신은 didReceiveResponseHeadersSelector를 지정하고 대기열에 추가 요청에 대리인을 설정에 대한 대안으로 사용할 수 있습니다
requestDidFinishSelector 대기열에서 요청이 성공적으로 완료할 때마다 호출됩니다.당신은 didFinishSelector를 지정하고 대기열에 추가 요청에 대리인을 설정에 대한 대안으로 사용할 수 있습니다
requestDidFailSelector 대기열에서 요청이 실패할 때마다 호출됩니다.당신은 didFailSelector를 지정하고 대기열에 추가 요청에 대리인을 설정에 대한 대안으로 사용할 수 있습니다
queueDidFinishSelector 전체 대기열이 완료되면 개별 요청이 실패 또는 성공에 상관없이 호출됩니다.
이들을 사용하려면 다음과 선택자 대표로 메서드를 구현 컨트롤러에 대기열 (대신 요청의 대의원 이상)의 대리인을 설정합니다.
ASINetworkQueues가 즉시 게재되지 않습니다 그들에 추가된 그 요청에 NSOperationQueues 약간 다르게 작동합니다.ASINetworkQueue를 사용할 때, 당신이 실행하려는 모든 작업을 추가한 후 [대기열 가게] 부릅니다.당신이 대기열을 시작할 때 정확한 진행이 켜져 , 그건 먼저 다운로드받을 수있는 데이터의 총 크기를 얻기 위해 대기열에있는 모든 해드 요청 HEAD 요청을 수행합니다.그것은 전체 크기가되면 그것은 정확하게 전체 진행 상황을 보여줄 수 있으며 실제 요청이 시작됩니다.
ASINetworkQueue의 요청이 실패하면, 대기열은 기본적으로 다른 모든 요청을 취소합니다.당신은 [NO 대기열 setShouldCancelAllRequestsOnFailure]와 함께이 동작을 비활성화할 수 있습니다.
ASINetworkQueues에만 ASIHTTPRequest 작업을 실행할 수 있습니다, 그들은 일반적인 작업에 사용할 수 없습니다.ASIHTTPRequest이 예외를 생성하지 않는 NSOperation를 추가하려고 시도.
비동기 요청을 취소
비동기식 요청 (중 [요청 startAsynchronous] 또는 사용자가 만든 대기열에서 실행 요청과 함께 시작되었습니다 요청) 호출을 취소하려면 [취소 요청].당신이 동기 요청을 취소할 수 없습니다.
당신이 요청을 취소하면 요청이 오류로 귀하의 대리인 및 / 또는 대기열의 실패 대리인 메소드를 호출한다는 처리됩니다.이 동작을하지 않으려면 취소를 호출하기 전에 전무로 대리인을 설정하거나 대신clearDelegatesAndCancel 방법을 사용합니다.
// Cancels an asynchronous request[ request cancel ]// Cancels an asynchronous request, clearing all delegates and blocks first[ request clearDelegatesAndCancel ] ;
대기열의 shouldCancelAllRequestsOnFailure이 아니오 (예 기본값)하지 않는 한 개별 요청을 취소했을 때 ASINetworkQueue을 사용할 때, 다른 모든 요청은 취소됩니다.
// When a request in this queue fails or is cancelled, other requests will continue to run[ queue setShouldCancelAllRequestsOnFailure :NO] ; // Cancel all requests in a queue[ queue cancelAllOperations ] ;
요청이 완료되기 전에 안전 대리인이 deallocated되고 처리
요청은 요청을 실행하는 동안 귀하의 대리인이 deallocated 수있는 기회가있다면, 그들의 대의원을 유지하지, 당신이 요청의 대의원 등록을 취소한 것이 중요합니다.당신의 대리인이 deallocated 될 경우 대부분의 경우에, 당신은 아마도 또한 요청을 취소하려면, 요청의 상태에 대한 당신은 더 이상 치료 이후.
아래 예제에서, 우리의 컨트롤러는 보관 인스턴스 변수에 저장된 ASIHTTPRequest 있습니다.우리는 우리의 요청에 대한 참조를 해제하기 직전, 그것의 dealloc 구현에 clearDelegatesAndCancel 메서드를 호출 :
웹 페이지 형태와 호환되는 방식으로 POST 데이터를 보내려면 포함된 사용 ASIFormDataRequest 하위 클래스를 .이진 데이터 또는 파일을 업로드하면 데이터가 '애플 리케이션 / X-WWW-폼 urlencode되고'형식으로, 또는 '다중 / 폼 데이터'형식으로 게시됩니다.파일의 데이터가 아니라 너무 큰 파일을 게시, 디스크에서 필요한 읽는 것은 당신의 웹 서버가이를 처리하는 설정이다만큼 괜찮습니다.
ASIFormDataRequest은 (IOS 3.0 이상 Mac에서) 파일의 MIME 형식을 자동 검색 setFile 통해 POST에 추가합니다 : forKey :, 서버에 전송 MIME 헤더에서이 포함됩니다.원하는 경우이를 무시하기 위해 더 이상 양식을 사용할 수 있습니다 :
요청이 진행되는 동안 downloadDestinationPath를 사용하여 파일 데이터를 다운로드할 때, 데이터는 임시 파일에 저장됩니다.이 파일의 경로가 temporaryFileDownloadPath에 저장됩니다.요청이 성공적으로 완료되면 두 가지 중 하나 일어날 :
데이터는 gzip을 압축 (볼 경우에는 gzip을 장치에 대한 정보 압축)를 압축된 파일 downloadDestinationPath로 압축되고, 임시 파일이 삭제됩니다
데이터가 압축되지 않은 경우 임시 파일은 이전 파일을 덮어 downloadDestinationPath로 이동합니다
가 도착하는대로 응답 데이터를 처리
didReceiveData : 당신이 (예를 들어, 당신이 그것이 여전히 다운로드되는 동안 응답을 구문 분석하는 스트리밍 파서를 사용하고자)에서 제공으로 응답을 처리할 필요가있다면, 귀하의 대리인이 요청을 구현해야 (참조ASIHTTPRequestDelegate.h을 ).이렇게하면 ASIHTTPRequest가 responseData를 채우기 또는 downloadDestinationPath에 대한 응답을 기록하지 않습니다 - 당신이 필요하다면 당신은 응답을 직접 저장해야합니다.
HTTP 상태 코드 읽기
그리고 적절하게 행동해야합니다 : ASIHTTPRequest 대부분의 HTTP 상태 코드 (리디렉션 및 인증 상태 코드를 제외하고, 자세한 내용은 아래 참조) 특별한 아무것도하지 않는, 그래서 그것은 (404 예) 문제를 잘 보살필 것인지는 당신에게 달렸습.
ASIHTTPRequest은 Content-Type 헤더로부터받은 데이터의 텍스트 인코딩을 읽을 시도합니다.그것이 텍스트 인코딩을 발견하면, 그것은 적절한로 responseEncoding 설정합니다 NSStringEncoding .그것이 머리글에 텍스트 인코딩을 찾지 못하는 경우 (이 기본값 NSISOLatin1StringEncoding까지) defaultResponseEncoding의 값을 사용합니다.
당신이 부를 때 [요청 responseString] ASIHTTPRequest는 소스 인코딩으로 responseEncoding을 사용하여, 그것이받은 데이터로부터 문자열을 만들려고합니다.
리디렉션을 처리
그것 Location 헤더가 보낸 가정, 다음 HTTP 상태 코드 중 하나가 생기면 ASIHTTPRequest는 자동으로 새 URL로 리디렉션됩니다 :
301 영구 이동
302 찾을 수 없음
303 기타 참조
리디렉션이 발생하면 응답 데이터의 값 (responseHeaders / responseCookies / responseData / responseString 등) 최종 위치에서받은 내용이 반영됩니다.
리디렉션주기 동안 발생한 URL 중 하나라도에 설정된 쿠키는 글로벌 쿠키 저장소에 저장되고 리디렉션된 요청했을 때 적절한에서 서버로 표시됩니다.
당신이 요청이 아니오로 재산을 shouldRedirect 없음의 설정에 의해 자동으로 리디렉션을 해제할 수 있습니다.
추적 진행
downloadProgressDelegate (다운로드)과 uploadProgressDelegate (업로드) - 각 ASIHTTPRequest 추적 진행에 사용할 수있는 두 명을 수용할 수 있습니다.
진행률 대표 NSProgressIndicators (맥 OS X) 또는 UIProgressViews (아이폰)이 될 수 있습니다.ASIHTTPRequest는 자동으로이 두 클래스의 동작의 차이를 만족 시켜줄 것입니다.당신이 원하는 경우에는 최대한 길게 setProgress에 응답으로 진행 대리인으로 사용자 정의 클래스를 사용할 수 있습니다.
하나의 요청을 수행하는 경우 해당 요청에 업로드 및 / 또는 다운로드 진행률 대리인을 설정
당신이 대기열에서 여러 요청을 수행하는, 그리고 대기열의 모든 요청에 대해 전반적인 진행 상황을 추적하려는 경우, ASINetworkQueue를 사용하여 대기열의 진행 대리인을 설정
당신 동시에 이들을 모두 수행하고 싶다면, 여기는 (v0.97 현재)도 가능하다
단일 요청에 대한 추적 다운로드 진행 중
이 예제에서는 myProgressIndicator는 NSProgressIndicator입니다.
ASIHTTPRequest이 표시 진전, 단순 진행 및 정확한 진행을위한 두 가지 접근 방법을 제공합니다.그들은 ASIHTTPRequests과 ASINetworkQueues의 showAccurateProgress를 사용하여 제어됩니다.당신이 요청 showAccurateProgress을 설정하면 해당 요청을 영향을 미칩니다.당신이 대기열에 설정하면 대기열의 모든 요청에 적용됩니다.
단순 진행
단순 진행을 사용할 때, 진보는 요청이 완료될 경우에만 업데이 트됩니다.전체 0퍼센트, 그리고 완전한 100 % - 단일 요청의 경우,이 두 개의 진행률 업데이 트를 의미합니다.네 요청과 함께 대기열 들어, 완료 요청을 나타내는 각각의 증가와 함께, 다섯 진행률 업데이트, 0 %, 25 %, 50 %, 75 % 및 100 %를 얻을 것이다.
단순 진행 (showAccurateProgress = NO)는 ASINetworkQueues에 대한 기본이고, 잘 소형 업로드 / 다운로드의 큰 숫자를 대기열에 적합합니다.
정확한 진행
바이트를 보내거나받은대로 정확하게 진행을 사용할 때, 진보가 업데이 트됩니다.그것은 데이터의 대량를 보내거나받을 요청에 대해 최선이며, 시간이 좀 걸릴 요청을 보내거나 접수되었으며 얼마나 많은 데이터를 더 잘 알려주지 않습니다.
진행 대의원은 (UIProgressViews 또는 NSProgressIndicators있을 가능성이있는) 훨씬 더 자주 다시 그려야하기 때문에 정확한 진행을 사용하여 약간, 업로드의 성능이 저하됩니다.
대기열 처음 있으므로 개시를 다운로드하기 전에 다운로드받을 수있는 데이터의 전체 크기를 결정할 수에 포함된 각 GET 요청에 대한 HEAD 요청을 수행하므로 정확한 진행을 사용하여 대기열을 사용하여 다운로드에 대한 성능에 훨씬 더 효과가 있습니다.정확한 진행을 사용하면 대기열에서 대용량 파일을 다운로드하는 경우 추천 있지만, 작은 다운로드 다수를 포함하는 대기열을 위해 피해야한다.
정확한 진행 (showAccurateProgress == YES)는 동기적으로 실행 ASIHTTPRequests에 대한 기본값입니다.
사용자 정의 진행률 추적
ASIProgressDelegate 프로토콜 대리인이 요청의 진행에 업데이 트를 얻을 수있는 모든 방법을 정의합니다.대부분의 상황에서 NSProgressIndicator 또는 UIProgressView로 uploadProgressDelegate 및 / 또는 downloadProgressDelegate을 설정하면 충분합니다.(IOS) 또는 setDoubleValue : / setMaxValue : 당신이 좀 더 복잡한 진행 추적을 수행하려는 경우에는 귀하의 진행 대의원은 다음 setProgress에 대한 선호의 메소드를 구현해야합니다 (Mac)을 선택합니다.이러한 방법은 오히려 0과 당신이 간단한 방법에 대해 얻을 1 사이의 숫자보다, 보내거나받은 바이트의 실제 수를 업데이 트를 얻을 수 있습니다.
downloadProgressDelegates하는 방법
요청 didReceiveBytes는 : 귀하의 downloadProgressDelegate에 요청 좀 더 많은 데이터를 다운로드 때마다 호출됩니다.(이것은 요청에서 별개임을주의 : didReceiveData : 방법 당신이 정규 대리인이 구현할 수 있습니다.)
요청 incrementDownloadSizeBy가 : 때 다운로드 변화의 크기는 다운로드의 크기를 증가해야되는 금액이 전달 매개 변수와 함께 호출됩니다.요청이 응답 헤더를 받고 다운로드의 크기를 알면 이것은 보통 발생합니다.
uploadProgressDelegates하는 방법
요청 didSendBytes는 : 귀하의 uploadProgressDelegate에 요청 좀 더 많은 데이터를 보낼 수있었습니다 때마다 호출됩니다 중요 사항 :. 그것이 보통 때 요청 (업로드 진행 상태를 제거해야 할 경우이 메서드는 0보다 적은 숫자로 호출됩니다 데이터를 업로드하지만, 인증 실패 또는 기타 이유로)를 다시 실행해야합니다.
요청 incrementUploadSizeBy가 : 호출되는시기 업로드 변화의 크기를 전달 크기는 자주 요청이 운영 체제에서 사용되는 내부 버퍼의 크기의 계정을 취할 업로드 크기를 이에 맞게 조정으로 영하 될 것이다..
HTTP 인증 처리
당신이 인증이 필요한 서버에 연결하는 경우 살펴봐야하는 것이 좋습니다 이 순서 ASIHTTPRequest 찾은 방법을 보여줍니다과 요청에 자격 증명을 적용합니다.
오히려 사전에 인증 자격 증명을 지정하는 것보다, 당신은 세션 인증 캐시 또는 열쇠 고리에 그들을 찾을 수없는 경우 각 요청이 자격 증명의 위임 물어 보죠하는 것을 선호 수도 있습니다.여러분이 인증 종류가 (있는 경우) 필요합니다 어떤 사전에 확실하지 않은 곳에 서버에 연결하려는 경우에 도움이 될 수 있습니다.
일시 정지 요청을 그것이 자격 증명을 사용해야할지 알려주 대리인을 기다리는 동안되며, ASIHTTPRequest : 귀하의 대리인이 authenticationNeededForRequest를 구현해야합니다.필요한 자격 증명이 경우 단순히 요청을 설정하고 통화 [요청 retryUsingSuppliedCredentials];.취소를 원할 경우 [요청 cancelAuthentication] 호출해야합니다.이것은 요청을 취소할 것입니다.
또는 proxyAuthenticationNeededForRequest : v1.0.8 기준으로, 요청 대의원은 하나의 authenticationNeededForRequest를 받게됩니다 한 번에.대리인이 첫 번째 요청을 처리하는 동안 다른 요청이 일시 중지 인증을 요구합니다.자격 증명을 제공하면 현재 진행중인 다른 요청들이 URL에 유효는 전제하에, 그들을 재사용하려고 시도합니다.대리인이 인증을 취소하고, 대기열의 shouldCancelAllRequestsOnFailure 예를있다면 다른 모든 요청은 자격 증명을 묻는 메시지를 시도하지 않고 취소됩니다.
내장된 인증 대화 상자를 사용하여 (현재는 단지 IOS)
v1.0.8에서 새로 ASIAuthenticationDialog 클래스입니다.이것은 주로 인증 프록시 (작업에 사용되는 아래 참조 ), 그러나 그것은 웹서버 인증에 대한 자격 증명을 사용자에게 물어보고 사용할 수 있습니다.
그들의 요청 대표단에, 또는 아예 위임 스타일의 인증의 사용을 피하 : 최상의 사용자 경험을 들어, 단일 서비스에 연결 대부분의 애플 리케이션 authenticationNeededForRequest을 구현해야합니다.정기적인 인증을위한 ASIHTTPRequest의 표준 인증 대화 상자의 사용이 유리있을 때 그러나 어떤 경우가있을 수 있습니다 :
당신은 자신의 로그인 양식을 작성하지 않으
그것이 인증을 요구하거나하지 않을 경우 외부 소스에서 데이터를 가져올 필요하고, 확실하지 수
당신의 대리인이 authenticationNeededForRequest를 구현하지 않는 경우 이런 경우, 사용자의 요청에 true로 shouldPresentAuthenticationDialog을 설정하고, 사용자는 대화 상자가 표시됩니다.
오직 한 대화 상자가 한꺼번에 나타날 수 있으며, 대화 상자가 표시되는 동안 인증을 필요로하는 다른 요청이 일시 중지됩니다.자격 증명을 제공하면 현재 진행중인 다른 요청들이 URL에 유효는 전제하에, 그들을 재사용하려고 시도합니다.대리인이 인증을 취소하고, 대기열의 shouldCancelAllRequestsOnFailure합니다 (기본값 당 등) 예 경우, 다른 모든 요청은 자격 증명을 묻는 메시지를 시도하지 않고 취소됩니다.
인증 대화 상자는 동기식 요청에 대해 표시되지 않습니다.
The dialog is partly modelled on the authentication dialog that Safari uses on the iPhone, and includes:
A message to indicate these credentials are for a webserver (as opposed to a proxy)
The hostname or IP of the server you are connecting to
The authentication realm (if one was supplied)
Fields to enter a username and password
When connecting to a server that uses the NTLM scheme, the dialog also includes a field for the domain
A note about whether the credentials are sent in plain text or not (ie: They are sent in plain text only when using Basic authentication without SSL)
If you want to change the look and feel, subclass ASIHTTPRequest, and override showAuthenticationDialog to show your custom dialog or ASIAuthenticationDialog subclass.
서버가 그것을 요구하기 전에 자격 증명을 제시
ASIHTTPRequest can present credentials to the server (if it has credentials to use) when it first makes a request, rather than waiting for the server to ask for credentials. This can result in better performance for applications using authentication, since it avoids an extra request.
To trigger this behaviour for requests using Basic authentication, you should manually set the request's authenticationScheme to use Basic:
For other authentication schemes, credentials can be presented before the server asks for them, but only after another request has successfully authenticated with the server.
You may wish to disable this feature if:
Your application may use multiple sets of credentials to talk to the same server at once
Security is paramount for your application. Using this feature is inherently less secure, since credentials are sent before you have a chance to validate that you are connecting to the server you thought you were connecting to.
ASIHTTPRequest allows you to use the global store shared by all Mac OS X applications that use the CFNetwork or NSURLRequest APIs. If useCookiePersistence is on (it is by default), cookies will be stored in the shared NSHTTPCookieStorage container, and reused on other requests automatically. It's worth noting that ASIHTTPRequest might present cookies created in other applications if they are valid for a particular request.
You can clear all cookies created during a session like so:
In this case, 'session cookies' refers to ALL cookies created during a session, rather cookies with no expiry date (often referred to as session cookies) that are removed when the application quits.
Alternatively, the convenience class method clearSession will clear all cookies created during the session, along with any cached authentication data.
쿠키를 직접 처리
If you prefer, you can turn off useCookiePersistence, and manage the set of cookies for a particular request manually:
Handling compressed responses, and compressing request bodies
압축된 응답 데이터를 처리하기 위해 gzip을 사용하여
As of v0.9, ASIHTTPRequest will notify the server that it can accept data compressed using gzip. If you are upgrading ASIHTTPRequest in an existing project, see the setup instructions for details of how to link with zlib.
Many webservers can compress data before sending it to the client - this results in faster downloads and lower bandwidth use, at the cost of additional CPU time on the server (to compress the data) and on the client (to decompress the data). Generally speaking, only certain types of data will be compressed - many binary formats like JPEG, GIF, PNG, SWF and PDF already compress their data, so gzip compression is normally not used to send them to a client. Text files like web pages and XML documents are perfect candidates for gzip compression, since they often contain a large amount of repeated information.
How to setup apache to gzip data using mod_deflate
Apache 2.x and above comes with the mod_deflate extension that allows it to transparently compress certain types of data. To turn it on, you need to enable mod_deflate in your apache configuration file, and add the mod_deflate directives to your virtual host config, or to your .htaccess file. More information is available here .
Using gzip in ASIHTTPRequest
- (IBAction) grabURL : (id) sender {NSURL* url = [NSURL URLWithString :@ "http://allseeing-i.com"] ; ASIHTTPRequest* request = [ASIHTTPRequest requestWithURL : url ] ; // YES is the default, you can turn off gzip compression by setting this to NO[ request setAllowCompressedResponse :YES] ; [ request startSynchronous ] ; BOOL* dataWasCompressed = [ request isResponseCompressed ] ; // Was the response gzip compressed?NSData* compressedResponse = [ request rawResponseData ] ; // Compressed dataNSData* uncompressedData = [ request responseData ] ; // Uncompressed dataNSString* response = [ request responseString ] ; // Uncompressed data as a string}
When allowCompressedResponse is true, ASIHTTPRequest will add a Accept-Encoding header to the request specifying we can accept gzipped response data. If the response headers contain a Content-Encoding header that specifies the data is compressed, calls to responseData or responseString will uncompress the data before returning it. You can get the original compressed data by calling rawResponseData .
온 - 더 - 플라이 gzip으로 압축 응답의 팽창
By default, ASIHTTPRequest will wait until a request finishes to inflate (uncompress) a gzipped response. By setting a request's shouldWaitToInflateCompressedResponses property to NO, you can tell ASIHTTPRequest to inflate the data as is comes in. In some circumstances, this may result in a small speed boost, as data can be processed while a request is waiting for more of the response.
This feature may be especially useful if you need to parse the response with a streaming parser (eg an XML or JSON parser). With this option enabled, you can feed inflated data directly to your parser as it comes in by implementingrequest:didReceiveData: in your delegate.
Note that when shouldWaitToInflateCompressedResponses is set to NO, the raw (compressed) data will be discarded. See the comments in ASIHTTPRequest.h for more info.
요청 기관을 압축하는 gzip을 사용하여
New in v1.0.3 is gzip compression for request bodies. Using this feature, your applications can compress the content of POST / PUT operations by setting shouldCompressRequestBody to YES. shouldCompressRequestBody is NO by default.
Apache's mod_deflate can automatically inflate (decompress) gzipped request bodies when configured withSetInputFilter DEFLATE ( More info ). This approach works for CGI content, but not when you are using an Apache module built as a RESOURCE filter (such as mod PHP). In these cases, you need to inflate the data yourself.
Resuming interrupted downloads
As of v0.94, ASIHTTPRequest can resume partial downloads.
- (IBAction) resumeInterruptedDownload : (id) sender {NSURL* url = [NSURL URLWithString :@ "http://allseeing-i.com/ASIHTTPRequest/Tests/the_great_american_novel.txt"] ; ASIHTTPRequest* request = [ASIHTTPRequest requestWithURL : url ] ; NSString* downloadPath =@ "/Users/ben/Desktop/my_work_in_progress.txt" ; // The full file will be moved here if and when the request completes successfully[ request setDownloadDestinationPath : downloadPath ] ; // This file has part of the download in it already[ request setTemporaryFileDownloadPath :@ "/Users/ben/Desktop/my_work_in_progress.txt.download"] ; [ request setAllowResumeForFileDownloads :YES] ; [ request startSynchronous ] ; //The whole file should be here now.NSString* theContent = [NSString stringWithContentsOfFile : downloadPath ] ; }
This only works for downloading data to a file, and you must set allowResumeForFileDownloads to YES for:
Any download you might want to resume in future (or ASIHTTPRequest will remove the temporary download file when it is cancelled or dealloced)
Any download you want to resume
Additionally, you must set a temporary download path yourself ( setTemporaryFileDownloadPath ), with the path of the partial data. New data will be appended to this file, and the file moved to downloadDestinationPath when the download completes successfully.
Resuming works by reading the size of the file at temporaryFileDownloadPath, and then requesting the rest of the file using a Range: bytes=x HTTP header.
Streaming request bodies directly from disk
As of v0.96, ASIHTTPRequest can use files on disk as the request body. This means that it is no longer necessary to hold the request body in memory, which should result in a drastic reduction in memory usage for large POST/PUT operations.
ASIFormDataRequests automatically use this feature when you use setFile:forKey:. The request will create a temporary file that will contain the full post body. Files are written a bit at a time to the relevant part of the body. The request is created using CFReadStreamCreateForStreamedHTTPRequest, using a read stream on the file as the source.
정기 ASIHTTPRequests
If you know your request is going to be large, turn on streaming from disk on the request:
[ request setShouldStreamPostDataFromDisk :YES] ;
In the example below, we add NSData objects to the post body one at a time. There are two methods for doing this - adding data from memory (appendPostData:), or appendPostDataFromFile: to add the contents of a file.
ASIHTTPRequest can automatically store downloaded data in a cache for use later. This can be helpful in many situations:
You want to have access to the data when there is no internet connection and you can't download it again
You want to download something only if it has changed since you last downloaded it
The content you are working with will never change, so you only want to download it once
In previous versions of ASIHTTPRequest, handling the above situations would have meant storing the data manually yourself. Using a download cache may eliminate the need for writing any local storage mechanism yourself in some situations.
ASIDownloadCache is a simple URL cache that can be used for caching the response of GET requests. To be eligible for response caching, requests must succeed (no error), and the server must have returned a 200 OK HTTP response code, or, as of v1.8.1, a 301, 302, 303 and 307 redirect status code.
After you've done this, all requests will use the cache automatically. If you prefer, you can set individual requests to use the shared cache on a case by case basis:
You aren't restricted to a single cache - you can create as many caches as you like. When you create a cache yourself, you must set the storage path for the cache - this should be a folder you have write access to:
Cache policies are the main way you control when information is stored in the cache, and when cached data will be used in preference to downloading the data again.
The cache policy of individual requests can be controlled using a request's cachePolicy property. Cache policies are defined using a bitmask, so you can combine multiple options to create the policy you want:
// Always ask the server if there is new content available, // If the request fails, use data from the cache even if it should have expired.[ request setCachePolicy : ASIAskServerIfModifiedCachePolicy|ASIFallbackToCacheIfLoadFailsCachePolicy ] ;
You can use the following options to define a request's cache policy:
ASIUseDefaultCachePolicy
The default cache policy. When you set a request to use this, it will use the cache's defaultCachePolicy. ASIDownloadCache's default cache policy is 'ASIAskServerIfModifiedWhenStaleCachePolicy'. You should not combine this with other options.
ASIDoNotReadFromCacheCachePolicy
Requests will not read from the cache when using this option.
ASIDoNotWriteToCacheCachePolicy
Requests will not save to the cache when using this option.
ASIAskServerIfModifiedWhenStaleCachePolicy
This is the default cache policy for ASIDownloadCaches. When using this, requests will first look to see if a cached response is available in the cache. If there is no cached data, the request will proceed as normal. If there is and the cached data has not expired, the request will use the cached data without contacting the server. If the cached data has expired, the request will perform a conditional GET to see if an updated version is available. If the server says the cached data is current, cached data will be used, and new data will not be downloaded. In this case, the cache's expiry time will be updated to match the new expiry date from the server. If the server provided updated content, it will be downloaded, and the new data and expiry written to the cache.
ASIAskServerIfModifiedCachePolicy
This is the same as ASIAskServerIfModifiedWhenStaleCachePolicy , except that requests will always ask the server if updated data is available.
ASIOnlyLoadIfNotCachedCachePolicy
When using this option, cached data will always be used if it exists, even if it should have expired.
ASIDontLoadCachePolicy
When using this option, requests will succeed only if a response is already cached. If no response for a request is cached, the request will stop, and no error will be set on the request.
ASIFallbackToCacheIfLoadFailsCachePolicy
When using this option, requests will fallback to cached data if the request fails. If cached data is used after a failure, the request will succeed without error. You would normally use this option in combination with others, as it is only useful for specifying the behaviour to use when something goes wrong.
When you set the defaultCachePolicy property of a cache, all requests that use that cache will use that cache policy unless they have a custom cache policy set on themselves.
소개 저장소 정책
Storage policies allow you to define how long a cache will store a particular response. ASIHTTPRequest currently supports two storage policies:
ASICacheForSessionDurationCacheStoragePolicy is the default. Responses will be stored only for the duration of the session, and will be removed the first time the cache is used, or when [ASIHTTPRequest clearSession] is called.
With ASICachePermanentlyCacheStoragePolicy , cached responses are stored permanently. To use this storage policy, set it on a request:
// When you turn shouldRespectCacheControlHeaders off, the cache will store responses even if the server // has explictly asked for them not be be cached (eg with a cache-control or pragma: no-cache header)[ [ASIDownloadCache sharedCache ] setShouldRespectCacheControlHeaders :NO] ; // Set secondsToCache on the request to override any expiry date for the content set by the server, and store // this response in the cache until secondsToCache seconds have elapsedASIHTTPRequest* request = [ASIHTTPRequest requestWithURL : url ] ; [ request setSecondsToCache :60*60*24*30] ; // Cache for 30 days // After a request has run, didUseCachedResponse will return YES if the response was returned from the cache[ request didUseCachedResponse ] ; // Ask the cache for a path to store the response. This is the most efficient way to use a download cache, // since data doesn't have to be copied into the cache when the request completes.[ request setDownloadDestinationPath : [ [ASIDownloadCache sharedCache ] pathToStoreCachedResponseDataForRequest : request ] ] ;
자신의 캐시 쓰기
If you already have a download cache and would like to plug it in to ASIHTTPRequest, or you prefer to write your own, have your cache implement the ASICacheDelegate protocol.
Throttling bandwidth
As of v1.0.7, ASIHTTPRequest can throttle the bandwidth used by all requests to prevent it going over a user-defined limit. This may help iPhone applications that send or receive large amounts of data to make it through the app store review process.
Throttling works by using a global limit (in bytes) for how much data can be received or transmitted in one second. All requests share this limit. As they send or receive data, ASIHTTPRequest keeps track of how much data has been sent or received in the last second. If one request exceeds the limit, any others running will also have to wait for the remainder of the current measurement period.
On iOS, you can tell ASIHTTPRequest to automatically turn throttling on when using a WWAN (GPRS/Edge/3G) connection, and it will automatically turn it off when switching to WiFi.
// Will limit bandwidth to the predefined default for mobile applications when WWAN is active. // Wi-Fi requests are not affected // This method is only available on iOS[ASIHTTPRequest setShouldThrottleBandwidthForWWAN :YES] ; // Will throttle bandwidth based on a user-defined limit when when WWAN (not Wi-Fi) is active // This method is only available on iOS[ASIHTTPRequest throttleBandwidthForWWANUsingLimit :14800] ; // Will prevent requests from using more than the predefined limit for mobile applications. // Will limit ALL requests, regardless of whether Wi-Fi is in use or not - USE WITH CAUTION[ASIHTTPRequest setMaxBandwidthPerSecond : ASIWWANBandwidthThrottleAmount ] ; // Log how many bytes have been received or sent per second (average from the last 5 seconds) NSLog (@ "%qi" , [ASIHTTPRequest averageBandwidthUsedPerSecond ] ) ;
Client certificates support
If your server requires the use of client certificates, as of v1.8 it is now possible to send them with your request.
// Will send the certificate attached to the identity (identity is a SecIdentityRef)[ request setClientCertificateIdentity : identity ] ; // Add an additional certificate (where cert is a SecCertificateRef)[ request setClientCertificates : [NSArray arrayWithObject : (id) cert ] ] ;
There is a helper function in ClientCertificateTests.m in the iPhone / iPad sample app that can create a SecIdentityRef from PKCS12 data (this function only works on iOS).
Working with Proxies
ASIHTTPRequest can detect system proxy settings and automatically apply them to requests. As of v1.0.6, it also supports PAC file proxy configuration, and authenticating proxies.
By default, ASIHTTPRequest will attempt to detect proxy settings automatically. However, should you wish, you can manually set proxy settings:
// Configure a proxy server manuallyNSURL* url = [NSURL URLWithString :@ "http://allseeing-i.com/ignore"] ; ASIHTTPRequest* request = [ASIHTTPRequest requestWithURL : url ] ; [ request setProxyHost :@ "192.168.0.1"] ; [ request setProxyPort :3128] ; // Alternatively, you can use a manually-specified Proxy Auto Config file (PAC) // (It's probably best if you use a local file)[ request setPACurl : [NSURL URLWithString :@ "file:///Users/ben/Desktop/test.pac"] ] ;
인증 프록시
On Mac OS, ASIHTTPRequest can auto-detect credentials used for authenticating proxies if they are specified in System Preferences. On iOS, ASIHTTPRequest cannot auto-detect the credentials used for authenticating proxies, so you either have to set them manually, use delegation to ask your controller / the user for appropriate credentials, or letASIAuthenticationDialog ask the user for them. Once valid proxy credentials have been obtained, they are stored in the keychain (when useKeychainPersistence is on) and are automatically reused.
프록시 수동으로 지정 자격 증명
NSURL* url = [NSURL URLWithString :@ "http://allseeing-i.com/ignore"] ; ASIHTTPRequest* request = [ASIHTTPRequest requestWithURL : url ] ; [ request setProxyHost :@ "192.168.0.1"] ; [ request setProxyPort :3128] ; // Set a username and password for authenticating proxies[ request setProxyUsername :@ "bencopsey"] ; [ request setProxyPassword :@ "password"] ; // For NTLM proxies, you can also set the domain (NTLM proxies are untested!)[ request setProxyDomain :@ "la.la.land"] ;
New in v1.0.8 is the ASIAuthenticationDialog class. This can be used to ask the user for credentials for authenticating webservers and proxies.
If your delegate does not respond to proxyAuthenticationNeededForRequest:, by default, ASIHTTPRequest will show a dialog prompting the user to supply credentials. It appears by default for proxy servers so that all apps using ASIHTTPRequest can work with authenticating proxies without any additional effort on the part of the developer.
The proxy authentication dialog will not appear for synchronous requests.
If you prefer not to use the proxy authentication dialog, either implement proxyAuthenticationNeededForRequest: in your proxy, or set shouldPresentProxyAuthenticationDialog to false (in which case your application will not be able to connect to authenticating proxies). If you want to change the look and feel, subclass ASIHTTPRequest, and override showProxyAuthenticationDialog to show your custom dialog or ASIAuthenticationDialog subclass.
// Log the average bandwidth used (in bytes) per second over the last 5 seconds NSLog (@ "%llu" , [ASIHTTPRequest averageBandwidthUsedPerSecond ] ) ; if( [ASIHTTPRequest isNetworkInUse ] ) {// ASIHTTPRequest has requests in progress that are using the network}
네트워크 활동 표시기 (IOS 전용)으로 자동 업데이 트를 비활성화
By default, ASIHTTPRequests will show the network activity indicator (in the status bar) on iOS devices when requests are using the network. If you prefer to manage this yourself, you can disable these updates:
Make requests retry a maximum of 2 times if they encounter a timeout:
[ request setNumberOfTimesToRetryOnTimeout :2] ;
영구적인 접속 설정하기
By default, ASIHTTPRequest will attempt to keep connections to a server open so that they can be reused by other requests to the same server (this generally results in significant speed boost, especially if you have many small requests). Persistent connections will be used automatically when connecting to an HTTP 1.1 server, or when the server sends a keep-alive header. Persistent connections are not used if the server explicitly sends a 'Connection: close' header. Additionally, ASIHTTPRequest will not use persistent connections for requests that include a body (eg POST/PUT) by default (as of v1.8.1). You can force the use of persistent connections for these request by manually setting the request method, then turning persistent connections back on:
Many servers do not provide any information in response headers on how long to keep a connection open, and may close the connection at any time after a request is finished. If the server does not send any information about how long the connection should be used, ASIHTTPRequest will keep connections to a server open for 60 seconds after any request has finished using them. Depending on your server configuration, this may be too long, or too short.
If this timeout is too long, the server may close the connection before the next request gets a chance to use it. When ASIHTTPRequest encounters an error that appears to be a closed connection, it will retry the request on a new connection.
If this timeout is too short, and the server may be happy to keep the connection open for longer, but ASIHTTPRequest will needlessly open a new connection, which will incur a performance penalty.
// Set the amount of time to hang on to a persistent connection before it should expire to 2 minutes[ request setPersistentConnectionTimeoutSeconds :120] ; // Disable persistent connections entirely[ request setShouldAttemptPersistentConnection :NO] ;
HTTP 1.0의 사용을 강제
[ request setUseHTTPVersionOne :YES] ;
보안 인증서 유효성 검사 해제
You may wish to use this for testing purposes if you have a self-signed secure certificate. I recommend purchasing a certificate from a trusted certificate authority and leaving certificate validation turned on for production applications.
[ request setValidatesSecureCertificate :NO] ;
Debugging options
ASIHTTPRequest provides a few flags that may be helpful in debugging request behaviour. These can be found inASIHTTPRequestConfig.h .
When you turn on one of these flags, requests will print out information about what they are doing to the console.
DEBUG_REQUEST_STATUS
Prints information on the overall request lifecyle - starting, finishing upload, finishing download etc.
DEBUG_THROTTLING
Prints information on (roughly) how much bandwidth requests are using, and if requests are being throttled, information about how this is happening. In conjunction with DEBUG_REQUEST_STATUS, this can be helpful for debugging timeouts, as you can see the point at which a request stopped sending or receiving data.
DEBUG_PERSISTENT_CONNECTIONS
Prints information on how requests are re-using persistent connections. If you are seeing output like:
Request attempted to use connection #1, but it has been closed - will retry with a new connection