/ / iOS: jak wykonać żądanie HTTP POST? - iphone, obiektyw-c, ios

iOS: jak wykonać żądanie HTTP POST? - iPhone, Object-C, iOS

Zbliżam się do rozwoju iOS i chciałbym mieć jedną z moich pierwszych aplikacji do wykonywania żądań HTTP POST.

O ile rozumiem, powinienem zarządzać połączeniem, które obsługuje żądanie za pośrednictwem pliku NSURLConnection obiekt, co zmusza mnie do posiadania obiektu delegata, który z kolei będzie obsługiwał zdarzenia danych.

Czy ktoś mógłby wyjaśnić zadanie na praktycznym przykładzie?

Powinienem skontaktować się z punktem końcowym https wysyłającym dane uwierzytelniające (nazwa użytkownika i hasło) i otrzymującym odpowiedź w postaci zwykłego tekstu.

Odpowiedzi:

167 dla odpowiedzi № 1

Możesz użyć NSURLConnection w następujący sposób:

  1. Ustaw swój NSURLRequest: Posługiwać się requestWithURL:(NSURL *)theURL aby zainicjować żądanie.

    Jeśli potrzebujesz określić żądanie POST i / lub nagłówki HTTP, użyj NSMutableURLRequest z

    • (void)setHTTPMethod:(NSString *)method
    • (void)setHTTPBody:(NSData *)data
    • (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field
  2. Wyślij zapytanie na 2 sposoby za pomocą NSURLConnection:

    • Synchronicznie: (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error

      Zwraca a NSData zmienną, którą możesz przetworzyć.

      WAŻNE: pamiętaj, aby rozpocząć synchroniczne żądanie w osobnym wątku, aby uniknąć blokowania interfejsu użytkownika.

    • Asynchronicznie: (void)start

Nie zapomnij ustawić delegata NSURLConnection do obsługi połączenia w następujący sposób:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[self.data setLength:0];
}

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

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[[[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", @"")
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:NSLocalizedString(@"OK", @"")
otherButtonTitles:nil] autorelease] show];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *responseText = [[NSString alloc] initWithData:self.data encoding:NSUTF8StringEncoding];

// Do anything you want with it

[responseText release];
}

// Handle basic authentication challenge if needed
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
NSString *username = @"username";
NSString *password = @"password";

NSURLCredential *credential = [NSURLCredential credentialWithUser:username
password:password
persistence:NSURLCredentialPersistenceForSession];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}

13 dla odpowiedzi nr 2

EDYCJA: ASIHTTPRequest został porzucony przez programistę. To wciąż naprawdę dobre IMO, ale prawdopodobnie powinieneś teraz poszukać gdzie indziej.

Bardzo polecam korzystanie z Biblioteka ASIHTTPRequest jeśli obsługujesz HTTPS.Nawet bez https zapewnia naprawdę fajne opakowanie dla takich rzeczy i chociaż nie jest trudno zrobić to samemu za pomocą zwykłego http, po prostu uważam, że biblioteka jest fajna i świetny sposób na rozpoczęcie.

W różnych scenariuszach komplikacje związane z protokołem HTTPS nie są trywialne, a jeśli chcesz być niezawodny w obsłudze wszystkich odmian, biblioteka ASI będzie naprawdę pomocna.


7 dla odpowiedzi nr 3

Pomyślałem, że zaktualizuję nieco ten post i powiem, że większość społeczności iOS przeniosła się do AFNetworking po ASIHTTPRequest Został porzucony. Gorąco polecam. To świetne opakowanie dookoła NSURLConnection i pozwala na wywołania asynchroniczne i w zasadzie wszystko, czego możesz potrzebować.


6 dla odpowiedzi № 4

Oto zaktualizowana odpowiedź na iOS7 +. Używa NSURLSession, nowej popularności. Zastrzeżenie, to nie zostało przetestowane i zostało zapisane w polu tekstowym:

- (void)post {
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://example.com/dontposthere"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
// Uncomment the following two lines if you"re using JSON like I imagine many people are (the person who is asking specified plain text)
// [request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
// [request addValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setHTTPMethod:@"POST"];
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}];
[postDataTask resume];
}

-(void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(    NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
}

Lub jeszcze lepiej, użyj AFNetworking 2.0+. Zwykle podklasa AFHTTPSessionManager jest podklasa, ale umieszczam to wszystko w jednej metodzie, aby uzyskać zwięzły przykład.

- (void)post {
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:@"https://example.com"]];
// Many people will probably want [AFJSONRequestSerializer serializer];
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
// Many people will probably want [AFJSONResponseSerializer serializer];
manager.responseSerializer = [AFHTTPRequestSerializer serializer];
manager.securityPolicy.allowInvalidCertificates = NO; // Some servers require this to be YES, but default is NO.
[manager.requestSerializer setAuthorizationHeaderFieldWithUsername:@"username" password:@"password"];
[[manager POST:@"dontposthere" parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
NSString *responseString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(@"darn it");
}] resume];
}

Jeśli używasz serializatora odpowiedzi JSON, responseObject będzie obiektem z odpowiedzi JSON (często NSDictionary lub NSArray).


1 dla odpowiedzi nr 5

UWAGA: Przykład Pure Swift 3 (Xcode 8): Wypróbuj poniższy przykładowy kod. To jest prosty przykład dataTask funkcja z URLSession.

func simpleDataRequest() {

//Get the url from url string
let url:URL = URL(string: "YOUR URL STRING")!

//Get the session instance
let session = URLSession.shared

//Create Mutable url request
var request = URLRequest(url: url as URL)

//Set the http method type
request.httpMethod = "POST"

//Set the cache policy
request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringCacheData

//Post parameter
let paramString = "key=value"

//Set the post param as the request body
request.httpBody = paramString.data(using: String.Encoding.utf8)

let task = session.dataTask(with: request as URLRequest) {
(data, response, error) in

guard let _:Data = data as Data?, let _:URLResponse = response  , error == nil else {

//Oops! Error occured.
print("error")
return
}

//Get the raw response string
let dataString = String(data: data!, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue))

//Print the response
print(dataString!)

}

//resume the task
task.resume()

}

0 dla odpowiedzi № 6

Xcode 8 i Swift 3.0

Korzystanie z sesji URL:

 let url = URL(string:"Download URL")!
let req = NSMutableURLRequest(url:url)
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main)

let task : URLSessionDownloadTask = session.downloadTask(with: req as URLRequest)
task.resume()

Połączenie delegata URLSession:

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {

}


func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask,
didWriteData bytesWritten: Int64, totalBytesWritten writ: Int64, totalBytesExpectedToWrite exp: Int64) {
print("downloaded (100*writ/exp)" as AnyObject)

}

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL){

}

Korzystanie z funkcji Block GET / POST / PUT / DELETE:

 let request = NSMutableURLRequest(url: URL(string: "Your API URL here" ,param: param))!,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval:"Your request timeout time in Seconds")
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers as? [String : String]

let session = URLSession.shared

let dataTask = session.dataTask(with: request as URLRequest) {data,response,error in
let httpResponse = response as? HTTPURLResponse

if (error != nil) {
print(error)
} else {
print(httpResponse)
}

DispatchQueue.main.async {
//Update your UI here
}

}
dataTask.resume()

Działa dobrze dla mnie ... spróbuj 100% gwarancji wyniku


0 dla odpowiedzi № 7

Oto jak działa żądanie POST HTTP dla iOS 8+ przy użyciu NSURLSession:

- (void)call_PostNetworkingAPI:(NSURL *)url withCompletionBlock:(void(^)(id object,NSError *error,NSURLResponse *response))completion
{
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
config.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
config.URLCache = nil;
config.timeoutIntervalForRequest = 5.0f;
config.timeoutIntervalForResource =10.0f;
NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:nil delegateQueue:nil];
NSMutableURLRequest *Req=[NSMutableURLRequest requestWithURL:url];
[Req setHTTPMethod:@"POST"];

NSURLSessionDataTask *task = [session dataTaskWithRequest:Req completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error == nil) {

NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
if (dict != nil) {
completion(dict,error,response);
}
}else
{
completion(nil,error,response);
}
}];
[task resume];

}

Mam nadzieję, że spełni to poniższe wymagania.