iOS: jak wykonać żądanie HTTP POST?
Zbliżam się do rozwoju iOS i chciałbym mieć jedną z moich pierwszych aplikacji do wykonania żądania HTTP POST.
O ile rozumiem, powinienem zarządzać połączeniem, które obsługuje żądanie za pomocą obiektu NSURLConnection
, 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 za pomocą praktycznego przykładu?
Powinienem skontaktować się z punktem końcowym https wysyłając dane uwierzytelniające (nazwę użytkownika i hasło) i odzyskanie odpowiedzi tekstowej.
7 answers
Możesz użyć NSURLConnection w następujący sposób:
-
Ustaw swoje
NSURLRequest
: UżyjrequestWithURL:(NSURL *)theURL
, aby zainicjować żądanie.Jeśli chcesz 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
-
Wyślij zapytanie na 2 sposoby używając
NSURLConnection
:-
Synchronicznie:
(NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error
Zwraca zmienną {[9] } , którą można proces.
Ważne: pamiętaj, aby uruchomić synchroniczne żądanie w oddzielnym wątku, aby uniknąć blokowania interfejsu użytkownika.
Asynchronicznie:
(void)start
-
Nie zapomnij ustawić delegata NSURLConnection, aby obsługiwał połączenie 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];
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-23 01:01:26
EDIT: asihttprequest został porzucony przez dewelopera. Nadal jest naprawdę dobry IMO, ale powinieneś teraz poszukać gdzie indziej.
Gorąco polecam korzystanie z biblioteki asihttprequest jeśli obsługujesz HTTPS. Nawet bez https zapewnia naprawdę ładny wrapper dla takich rzeczy i chociaż nie jest trudno zrobić sobie przez zwykły http, po prostu myślę, że Biblioteka jest miła i świetny sposób, aby zacząć.
Komplikacje HTTPS są dalekie od trywialne w różnych scenariuszach, a jeśli chcesz być solidny w obsłudze wszystkich odmian, znajdziesz bibliotekę ASI prawdziwą pomoc.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-18 16:23:03
Po tym, jak udało mi się zmienić ten wpis, postanowiłem dodać, że wiele osób ze społeczności iOS przeniosło się do AFNetworking po tym, jak ASIHTTPRequest
zostało porzucone. Gorąco polecam. Jest to świetny wrapper wokół NSURLConnection
i pozwala na asynchroniczne połączenia, a w zasadzie wszystko, czego możesz potrzebować.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-15 00:12:26
Oto zaktualizowana odpowiedź dla iOS7+. Używa NSURLSession, nowej hotness. Zastrzeżenie, jest to nieprzetestowane i zostało napisane 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]);
}
Albo jeszcze lepiej, Użyj AFNetworking 2.0+. Zazwyczaj podklasowałbym AFHTTPSessionManager, ale umieszczam to wszystko w jednej metodzie, aby mieć 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 serializera odpowiedzi JSON, obiekt responseObject będzie obiektem odpowiedzi JSON (często NSDictionary lub NSArray).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-25 01:05:11
Uwaga: Pure Swift 3 (Xcode 8) przykład:
Wypróbuj poniższy przykładowy kod. Jest to prosty przykład dataTask
funkcji 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()
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-20 08:30:52
Xcode 8 i Swift 3.0
Using URLSession:
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()
Urlsession Delegate call:
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){
}
Użycie bloku 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()
Dla mnie działa dobrze.. wypróbuj 100% gwarancji wynikuWarning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-19 12:11:48
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 twoje następujące wymagania.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-19 12:25:13