2011-01-06 66 views
19

Bất cứ ai có thể cho tôi biết cách tôi có thể thực hiện cuộc gọi đồng bộ đến máy chủ https không? Tôi có thể thực hiện yêu cầu không đồng bộ trên máy chủ https bằng cách sử dụng các phương thức ủy nhiệm sau.Yêu cầu đồng bộ NSURLConnection trên https

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace 

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 

nhưng tôi cần phải làm đồng bộ.

Trả lời

13
+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error 

trong NSUrlConnection chỉ hoạt động tốt với https.

Nếu bạn muốn cung cấp bằng chứng xác thực, họ cần phải là một phần của url: (https://username:[email protected]/api/user.json).

Không có cách nào để cung cấp một đại biểu NSURLConnection, vì vậy nếu bạn cần một số xử lý xác thực không chuẩn, bạn sẽ cần phải làm điều đó một cách không đồng bộ.

+0

Anh ấy cần cuộc gọi hàm phụ thuộc thể hiện để cung cấp cho đại biểu phản hồi thử thách https – LolaRun

+0

Cảm ơn bạn :) Thật đơn giản. –

24

// Encoding yêu cầu

NSData *postData = [xmlText dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; 

**//Calculating length of request** 
NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]]; 

NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease]; 
[request setURL:[NSURL URLWithString:requestUrlString]]; 
[request setHTTPMethod:@"POST"]; 
[request setValue:postLength forHTTPHeaderField:@"Content-Length"]; 
[request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"]; 
[request setHTTPBody:postData]; 
NSURLResponse* response; 
NSError* error = nil; 

//Capturing server response 
NSData* result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; 
+2

Nên sử dụng NSUTF8StringEncoding nếu có dữ liệu cũng có hỗ trợ ký tự quốc tế, ví dụ: tiếng Đức, tiếng Ý, v.v. Khác phương pháp trên hoàn toàn hoàn hảo .. –

+0

Đừng quên biểu tượng cảm xúc, chúng cũng cần có UTF8;) –

+0

Người đó cần cuộc gọi hàm phụ thuộc thể hiện để cung cấp cho đại biểu phản hồi https thách thức – LolaRun

6

Đó là cách tôi đã làm nó: thay vì

[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error] 

tôi đã dụ cùng một phương pháp dựa trên lớp chứa, vì chúng ta sẽ cần một đại biểu. Và không làm cho nó trở nên đơn điệu, vì vậy mọi kết nối đều có các biến độc lập của nó, bởi vì, nếu chúng ta không, và hai kết nối xảy ra trước khi kết thúc khác, thì dữ liệu nhận được và xử lý các vòng lặp sẽ được đan xen với nhau .

[[ClassNameHere new] sendSynchronousRequest:request returningResponse:&response error:&error] 

Bằng cách này tôi có thể tạo kết nối NSUrl và xử lý nó (theo cách đồng bộ, chúng ta sẽ thấy cách) vì vậy tôi không phải thay đổi bất kỳ mã nào được viết trước đó.

- (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse *__strong*)response error:(NSError *__strong*)error 
{ 
    _finishedLoading=NO; 
    _receivedData=[NSMutableData new]; 
    _error=error; 
    _response=response; 

    NSURLConnection*con=[NSURLConnection connectionWithRequest:request delegate:self]; 
    [con start]; 
    CFRunLoopRun(); 

    return _receivedData; 
} 


- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace { 
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 
{ 
    //handle the challenge 
} 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{ 
    *_response=response; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{ 
    [_receivedData appendData:data]; 
} 

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
{ 
    *_error=error; 
    CFRunLoopStop(CFRunLoopGetCurrent()); 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    CFRunLoopStop(CFRunLoopGetCurrent()); 
} 

Bí quyết là ở CFRunLoopRun() và CFRunLoopStop (CFRunLoopGetCurrent()) Tôi hy vọng nó sẽ giúp người khác trong futur.

+2

Tôi sẽ không hỏi tại sao người ta trả lời câu hỏi 250 năm tuổi và đặc biệt là câu hỏi đó;) Nhưng quan trọng hơn, tôi muốn đề cập đến rằng mã của bạn không xác thực đúng cách và không an toàn. Vì vậy, nếu đây chỉ là mã thử nghiệm để loại bỏ các chứng chỉ, thì điều này là OK. Đối với sản xuất, đó là một nguy cơ bảo mật. – CouchDeveloper

+0

Ở đây tôi phải đối mặt với cùng một vấn đề như ông đã làm, tôi đã phải kết nối với một https sau này trong sự phát triển. Và tôi đã có lớp dữ liệu bằng cách sử dụng yêu cầu đồng bộ. Và để thích ứng với thử thách của máy chủ, chúng tôi phải làm cho nó không đồng bộ, và nó sẽ rất cồng kềnh để làm lại lớp dữ liệu thành đồng bộ. Mã này thực sự xử lý xác thực theo cách không đồng bộ :). Vì vậy, lớp dữ liệu (mô hình) vẫn còn nguyên vẹn hoàn hảo, không có sửa đổi gì cả. – LolaRun

+0

Bây giờ liên quan đến an ninh của việc xử lý thách thức. Tôi đọc tài liệu này: https://developer.apple.com/library/ios/#technotes/tn2232/_index.html#//apple_ref/doc/uid/DTS40012884-CH1-SECRESOLVINGFAILURES Và trường hợp của tôi không phải là nơi máy chủ của tôi có Chứng chỉ đã được xác minh, nó đã được tự ký, và nó sẽ vẫn như vậy. Và không có CA mẹ cho cert máy chủ. Vì vậy, hoặc là điều này, hoặc tải về chứng chỉ và so sánh dữ liệu. Và tôi nghĩ rằng cả hai cách tiếp cận, có cùng một lỗ hổng tấn công. Vì vậy, chúng tôi phải làm việc với máy chủ để đảm bảo an toàn hơn. – LolaRun

Các vấn đề liên quan