2012-11-05 12 views

risposta

32

Questo rientra nella facile, ma non ovvio classe di problemi di programmazione per iPhone. Degno di un post veloce:

Le intestazioni per una connessione HTTP sono incluse nella classe NSHTTPURLResponse. Se si dispone di una variabile NSHTTPURLResponse, è possibile ottenere facilmente le intestazioni come NSDictionary inviando il messaggio allHeaderFields.

Per richieste sincrone - non è raccomandato, perché bloccare - è facile per popolare un NSHTTPURLResponse:

NSURL *url = [NSURL URLWithString:@"http://www.mobileorchard.com"]; 
NSURLRequest *request = [NSURLRequest requestWithURL: url]; 
NSHTTPURLResponse *response; 
[NSURLConnection sendSynchronousRequest: request returningResponse: &response error: nil]; 
if ([response respondsToSelector:@selector(allHeaderFields)]) { 
NSDictionary *dictionary = [response allHeaderFields]; 
NSLog([dictionary description]); 
} 

Con una richiesta asincrona che devi fare un po 'di lavoro. Quando viene richiamata la richiamata connection:didReceiveResponse:, viene inviato un NSURLResponse come secondo parametro. Si può lanciare a un NSHTTPURLResponse in questo modo:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;  
if ([response respondsToSelector:@selector(allHeaderFields)]) { 
    NSDictionary *dictionary = [httpResponse allHeaderFields]; 
    NSLog([dictionary description]); 
} 
} 
+3

Se si desidera recuperare l'intestazione della risposta http, quindi inviare la richiesta HEAD. La richiesta HEAD non recupera il corpo della risposta. Esempio: imposta il tipo di metodo HTTP nella richiesta. NSMutableURLRequest * mutableRequest = [[NSMutableURLRequest alloc] initWithURL: url]; mutableRequest.HTTPMethod = @ "HEAD"; – Omkar

+0

Perché dovremmo trasmettere NSURLResponse a un NSHTTPURLResponse? – youssman

+0

Questo * non * registra tutte le intestazioni inviate nella richiesta! Se imposti intestazioni aggiuntive a NSURLSessionConfiguration, quelle non verranno registrate. Non ho ancora trovato il modo di recuperarli dalla risposta ... – Johanneke

2

YourViewController.h

@interface YourViewController : UIViewController <UIWebViewDelegate> 
    @property (weak, nonatomic) IBOutlet UIWebView *yourWebView; 
@end 

YourViewController.m

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    //Set the UIWebView delegate to your view controller 
    self.yourWebView.delegate = self; 

    //Request your URL 
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://website.com/your-page.php"]]; 

    [self.legalWebView loadRequest:request]; 
} 

//Implement the following method 
- (void)webViewDidFinishLoad:(UIWebView *)webView{ 
    NSLog(@"%@",[webView.request allHTTPHeaderFields]); 
} 
2

Dato NSURLConnection è deprecato da iOS 9, è possibile utilizzare un NSURLSession per ottenere informazioni di tipo MIME da un NSURL o NSURLRequest.

Si chiede alla sessione di recuperare l'URL, quindi quando si riceve il primo NSURLResponse (che contiene le informazioni sul tipo MIME) in una richiamata delegata si annulla la sessione per impedirne il download dell'intero URL.

Ecco alcune ossa nude codice Swift che lo fa:

/// Use an NSURLSession to request MIME type and HTTP header details from URL. 
/// 
/// Results extracted in delegate callback function URLSession(session:task:didCompleteWithError:). 
/// 
func requestMIMETypeAndHeaderTypeDetails() { 
    let url = NSURL.init(string: "https://google.com/") 
    let urlRequest = NSURLRequest.init(URL: url!) 

    let session = NSURLSession.init(configuration: NSURLSessionConfiguration.ephemeralSessionConfiguration(), delegate: self, delegateQueue: NSOperationQueue.mainQueue()) 

    let dataTask = session.dataTaskWithRequest(urlRequest) 
    dataTask.resume() 
} 

//MARK: NSURLSessionDelegate methods 

func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void) { 

    // Cancel the rest of the download - we only want the initial response to give us MIME type and header info. 
    completionHandler(NSURLSessionResponseDisposition.Cancel) 
} 

func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) 
{  
    var mimeType: String? = nil 
    var headers: [NSObject : AnyObject]? = nil 


    // Ignore NSURLErrorCancelled errors - these are a result of us cancelling the session in 
    // the delegate method URLSession(session:dataTask:response:completionHandler:). 
    if (error == nil || error?.code == NSURLErrorCancelled) { 

     mimeType = task.response?.MIMEType 

     if let httpStatusCode = (task.response as? NSHTTPURLResponse)?.statusCode { 
      headers = (task.response as? NSHTTPURLResponse)?.allHeaderFields 

      if httpStatusCode >= 200 && httpStatusCode < 300 { 
       // All good 

      } else { 
       // You may want to invalidate the mimeType/headers here as an http error 
       // occurred so the mimeType may actually be for a 404 page or 
       // other resource, rather than the URL you originally requested! 
       // mimeType = nil 
       // headers = nil 
      } 
     } 
    } 

    NSLog("mimeType = \(mimeType)") 
    NSLog("headers = \(headers)") 

    session.invalidateAndCancel() 
} 

ho confezionato una funzionalità simile nel progetto URLEnquiry a github che lo rende un po 'più facile per fare query in-line per i tipi MIME e Intestazioni HTTP URLEnquiry.swift è il file di interesse che potrebbe essere inserito nel tuo progetto.

1

Versione rapida con Alamofire per efficienza. Questo è ciò che ha funzionato per me:

Alamofire.request(YOUR_URL).responseJSON {(data) in 

if let val = data.response?.allHeaderFields as? [String: Any] { 
     print("\(val)") 
    } 
}