스마트기기개발관련/IOS 개발

IOS 개발 UIWebView, NSURLConnect 등등 쿠키공유 관련

AlrepondTech 2016. 11. 7. 14:12
반응형

 

 

 

=================================

=================================

=================================

 

 

 

 

출처: http://stackoverflow.com/questions/8929579/ios-uiwebview-auth-cookies

 

 

 

I have a UIWebView that loads a website that user Authentication. The site creates an Authentication cookie. When in the browser, unless you clear your cookies, you will always be logged in. When the xCODE loads it can see the cookie listed when looking at the cookie jar but it is not sent to the webView. I would like to know how to make the webView aware that the auth cookie is there so it does not continue to prompt the user for authentication every single time.

 

----------------------------------------------------------------------------------------------------------------

 

You can use the NSURLConnection class to perform a HTTP request to login the website, and retrieve the cookie. To perform a request, just create an instance of NSURLConnection and assign a delegate object to it.

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com/"]]; NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];

Then, implement a delegate method.

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {     NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *)response;     NSDictionary *fields = [HTTPResponse allHeaderFields];     NSString *cookie = [fields valueForKey:"Set-Cookie"]; // It is your cookie }

Retain or copy the cookie string. When you want to perform another request, add it to your HTTP header of your NSURLRequest instance.

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com/"]]; [request addValue:cookie forHTTPHeaderField:"Cookie"];

TO delete Cookie anytime you can call this method:

NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];     for (NSHTTPCookie *each in [[[cookieStorage cookiesForURL:YOUR_URL] copy] autorelease]) {         [cookieStorage deleteCookie:each];     }
shareimprove this answer

 

-------------------------------------------------------------------------------------------------------------------------

 

 
Ok, I'm new to xCODE and I have questions about this. Feel free to call me names if they are too simple. In the AppDelegate.m file I try to declare the NSURL and NSURLConnection and got a compiler error about those not beign constants. I implemented the delegate also in AppDelagate.m and that compiles. The NSMutable I have no idea in what method should that go. I'm sure this are simple questions but I really do not know. –
 
-----------------------------------------------------------------------------------------------------------------------
 
 
You can read the authentication cookie from all websites using the shared cookie storage.
NSHTTPCookie *cookie; NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage]; for (cookie in [cookieJar cookies]) { NSLog(@"%@", cookie); }
OR to get the .net aspxauth cookie for your website
NSArray *cookiesForURL = [cookieJar cookiesForURL: [NSURL URLWithString: **MYURL**]]; for (cookie in cookiesForURL) { if([cookie.name compare:@".ASPXAUTH"] == NSOrderedSame) { NSLog(@"%@", cookie); break; } }
shareimprove this answer

 

 

-------------------------------------------------------------------------------------------------------------------------

 

I solved the issue. The problem has to do with configuration as the UIWebView is not getting seen as a standard web browser. I'm authenticating user through .net and IIS. I added a generic.browser file in the App_Browser directory of my website. The content of the file is:

<browsers>   <browser refID="Mozilla" >     <capabilities>       <capability name="cookies"  value="true" />     </capabilities>   </browser>   <browser refID="Default">       <capabilities>         <capability name="cookies" value="true" />       </capabilities>     </browser> </browsers>

The line that corrects the issue is the capability allowing the cookies.

The reference to the solution I used was this

Problem with Asp.Net Forms Authentication when using iPhone UIWebView

shareimprove this answer

 

 

 

=================================

=================================

=================================

 

 

출처: http://kakadais.tistory.com/entry/NSURLConnection-Cookie-Control

 

꽤나 오래전에 URLConnection 을 위해 사용한 코드인데..

아직 모든 어플들이 정상 작동하는걸로 보아 아직 유효한거 같다;

 

http://stackoverflow.com/questions/2053568/managing-http-cookies-on-iphone

 

 

핵심 소스는 아래와 같이 발췌해본다.

NSURLRequest*request =[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com/"]];

 

NSURLConnection*connection =[NSURLConnection connectionWithRequest:request delegate:self];

Then, implement a delegate method.


-(void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response

{

    NSHTTPURLResponse*HTTPResponse=(NSHTTPURLResponse*)response;

    NSDictionary*fields =[HTTPResponse allHeaderFields];

  NSString*cookie =[fields valueForKey:"Set-Cookie"];// It is your cookie

}

Retain or copy the cookie string. When you want to perform another request, add it to your HTTP header of your NSURLRequest instance.

 

NSMutableURLRequest*request =[NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com/"]];

 

[request addValue:cookie forHTTPHeaderField:"Cookie"];

 

 

=================================

=================================

=================================

 

 

 

출처: http://egloos.zum.com/fmttm/v/4324991

 

/* 

 

아래 같은 방식으로 smsURL이라는 주소로 post 형식으로 데이터를 감싸 전송이 가능해진다.*/

 

 

- (void)connectToServer

{

NSString *smsURL = @"http://www.google.co.kr";

NSMutableURLRequest *request = [[[NSMutableURLRequest allocinitautorelease];

 

 

NSString *post = [NSString stringWithFormat:@"password=%@&id=%@",@"password",@"id"];

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

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

 

 

[request setURL:[NSURL URLWithString:smsURL]];

[request setHTTPMethod:@"POST"];

[request setValue:postLength forHTTPHeaderField:@"Content-Length"];

[request setValue:@"Mozilla/4.0 (compatible;)" forHTTPHeaderField:@"User-Agent"];

[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];

[request setHTTPBody:postData];

 

[NSURLConnection connectionWithRequest:request delegate:self ];

}

 


 

/*아래 Delegate에서는 HTML이 처리되고 난 후 받는 데이터를 얻을 수 있다.*/

 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

{

 

NSString *returnString = [[NSString allocinitWithData:data encoding:NSUTF8StringEncoding];

NSLog(returnString);

}

 


 

/* 아래 Delegate를 이용하면 post를 보낸 후 쿠키를 얻을 수 있다.*/

 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)aResponse

{

NSHTTPCookie *cookie;

int i=0;

for (cookie in [[NSHTTPCookieStorage sharedHTTPCookieStoragecookies])

{

NSLog([cookie description]);

}

}


트랙백

 

 

=================================

=================================

=================================

 

 

 

I have been working using openFrameworks, on a problem that is posted on the forum: www.openframeworks.cc/forum/viewtopic.php?f=8&t=4765

Essentially, I have used an an set of files, ofxHttpUtils, which uses poco to post to web forms. The example code I have used is at: github.com/arturoc/ofxHttpUtils/blob/gh-pages/example/src/testApp.cpp

I want to POST to a login page, a username and password, and then I am aiming to scrape text off the response... that's the aim, via an iPhone app.

The problem I am having is cookies. The ofxHttpUtils addon does not have any method for remembering the cookie from a POST, so the response I get back is just the login page. I have searched for methods to try and capture the cookie, and there seems to be something in Objective C here, from another post to Stack Overflow:

NSHTTPURLResponse   * response; NSError             * error; NSMutableURLRequest * request; request = [[[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://temp/gomh/authenticate.py?setCookie=1"]                                         cachePolicy:NSURLRequestReloadIgnoringCacheData                                      timeoutInterval:60] autorelease];  [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];     NSLog(@"RESPONSE HEADERS: \n%@", [response allHeaderFields]);  // If you want to get all of the cookies: NSArray * all = [NSHTTPCookie cookiesWithResponseHeaderFields:[response allHeaderFields] forURL:[NSURL URLWithString:@"http://temp"]]; NSLog(@"How many Cookies: %d", all.count); // Store the cookies: // NSHTTPCookieStorage is a Singleton. [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:all forURL:[NSURL URLWithString:@"http://temp"] mainDocumentURL:nil];  // Now we can print all of the cookies we have: for (NSHTTPCookie *cookie in all)     NSLog(@"Name: %@ : Value: %@, Expires: %@", cookie.name, cookie.value, cookie.expiresDate);    // Now lets go back the other way.  We want the server to know we have some cookies available: // this availableCookies array is going to be the same as the 'all' array above.  We could  // have just used the 'all' array, but this shows you how to get the cookies back from the singleton. NSArray * availableCookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:[NSURL URLWithString:@"http://temp"]]; NSDictionary * headers = [NSHTTPCookie requestHeaderFieldsWithCookies:availableCookies];  // we are just recycling the original request [request setAllHTTPHeaderFields:headers];  request.URL = [NSURL URLWithString:@"http://temp/gomh/authenticate.py"]; error       = nil; response    = nil;  NSData * data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; NSLog(@"The server saw:\n%@", [[[NSString alloc] initWithData:data encoding: NSASCIIStringEncoding] autorelease]);

I am not sure how/where to implement this, so that I can integrate with my my ofxHttpUtils code so that the cookie is remembered and served in calls to the password protected site. Can anyone help? I know this request is a little unspecific... I hope you can see what I'm trying to do...

-------------------------------------------------------------------------------------------------------------------------

 

Since you're already using OF, it would likely be simpler to stick with that. You're going to have to extend ofxHttpUtils to handle cookies, either by making it smarter so it handles cookies intelligently, or by leaving it dumb while letting you grab and set cookies as needed. Poco::Net, which ofxHttpUtils is based on, has no problem with cookies - it includes functions like HTTPResponse::getCookies().

The most straightforward approach is the dumb one:

  • add ofxHttpForm::setCookies() so you can pass cookies into the module and getCookies()so the module can access them
  • modify ofxHttpUtils::doPostForm() to pull cookies from the ofxHttpForm and set them on the Poco HTTPRequest
  • modify the ofxHttpRequest constructor to pull the cookies from the Poco HTTPResponse and provide a way for your code to get at them

Your code would then grab the cookies sent back after the log-in POST and set them on all future requests.

--------------------------------------------------------------------------------------------------------------------

 

Hi Jeremy thanks for the answer. That had been my thought- but I wasn't sure how to go about it. I think it would involve writing a function within the ofxHttpUtils as you say. But I'm not certain I have the knowledge to do that! But I do agree that mixing the two types of code above is probably not the right thing to do. Do you have any pointers to get me started? Thanks again – sacculi Oct 14 '10 at 21:32
    
@sacculi I've edited my original answer to provide an outline of the straightforward approach, which basically just routes the cookies back and forth through the ofxHttpUtils layer. – Jeremy W. Sherman Oct 15 '10 at 0:22
    
Thanks Jeremy. The steps are really useful, thanks so much. I have tried various ways of implementing them but struggle. Like, passing cookies into the new function (step 1), I guess I need to pass in the HTTPResponse from the postForm function, but I can't get that right. There are some conceptual gaps there, you see, on my part. I was also intrigued by stackoverflow.com/questions/1499086/… which seemed to have the same code as the ofxHttpUtils I have been working with. I wondered about using that somehow, like: – sacculi Oct 15 '10 at 12:56
    
std::vector<Poco::Net::HTTPCookie> cookies; res.getCookies( cookies ); – sacculi Oct 15 '10 at 12:56
    
and then after that, req.getCookies( cookies ); after the HTTPRequest for the URL (not the formpost function). But like I said above, I lack some conceptual stuff at this level- I mostly do simple media arts projects! But I shall keep you in touch with my progress, thanks SO much – sacculi Oct 15 '10 at 12:59

 

 

 

 

=================================

=================================

=================================

 

 

 

출처: http://www.hooni.net/xe/study/22881

 

[ios] UIWebView에서 NSURLRequest에 Cookie 실어 보내기

 

보통 UIWebView 에서 특정 URL로 이동할 때 아래와 같은 코드를 사용한다.

 

NSURLRequest를 이용한 URL 이동

 

1
2
3
4
5
6
7
8
UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.frame];
NSURL *url = [NSURL URLWithString:@"http://www.hooni.net"];
 
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
 
[webView setBackgroundColor:[UIColor clearColor]];
[self.view addSubview:webView];

 

 

쿠키(Cookie)와 같은 헤더에 값을 실어서 보낼 때는 Request에 값을 세팅해야 하므로,

아래 코드와 같이 NSMutableURLRequest를 사용한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.frame];
NSURL *url = [NSURL URLWithString:@"http://www.hooni.net"];
 
NSMutableURLRequest *mutableRequest =
    [NSMutableURLRequest requestWithURL:url];
 
NSLog(@"%@", @"PersisteWebCookie");
NSMutableString *cookieStringToSet = [[NSMutableString alloc] init];
 
[cookieStringToSet appendFormat:@"ENC=%@;", @"6EA4E3F7E03A9..."];
 
if (cookieStringToSet.length) {
    [mutableRequest setValue:cookieStringToSet
        forHTTPHeaderField:@"Cookie"];
 
    NSLog(@"Cookie : %@", cookieStringToSet);
}
NSLog(@"%@", @"PersisteWebCookie Restored");
 
[webView loadRequest:mutableRequest];
 
[webView setBackgroundColor:[UIColor clearColor]];
[self.view addSubview:webView];

 

 

기존에 저장된 쿠키를 읽어오는 코드와 섞으면 아래처럼 활용할 수 있다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.frame];
NSURL *url = [NSURL URLWithString:@"http://www.hooni.net"];
NSMutableURLRequest *mutableRequest =
    [NSMutableURLRequest requestWithURL:url];
 
NSLog(@"%@", @"PersisteWebCookie");
NSData *cookiesdata = [[NSUserDefaults standardUserDefaults]
    objectForKey:@"MySavedCookies"];
 
if([cookiesdata length]) {
    NSArray *cookies =
        [NSKeyedUnarchiver unarchiveObjectWithData:cookiesdata];
 
    for (cookie in cookies) {
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
        NSLog(@"cookiesdata ; %@", cookie);
    }
     
    NSMutableString *cookieStringToSet = [[NSMutableString alloc] init];
    for (NSHTTPCookie *cookie in cookies) {
        [cookieStringToSet appendFormat:@"%@=%@;",
            cookie.name, cookie.value];
    }
     
    if (cookieStringToSet.length) {
        [mutableRequest setValue:cookieStringToSet
            forHTTPHeaderField:@"Cookie"];
 
        NSLog(@"Cookie : %@", cookieStringToSet);
    }
}
NSLog(@"%@", @"PersisteWebCookie Restored");
     
[webView loadRequest:mutableRequest];
 
[webView setBackgroundColor:[UIColor clearColor]];
[self.view addSubview:webView];
 

 

 

 

 

=================================

=================================

=================================

 

 

출처: http://dogfeet.github.io/articles/2012/persist-cookie-of-uiwebview.html

 

UIWebView 쿠기 유지하기

애플리케이션에서 UIWebView를 사용할 때 쿠키를 저장하는 방법을 살펴본다. 쿠키를 저장하면 애플리케이션이 종료되더라도 로그인 상태 등을 유지할 수 있다. 서버가 특별히 쿠키의 지속 시간을 지정하지 않은 경우 쿠키는 애플리케이션이 종료되면(백그라운드에 남아있는 것과는 다르다) 쿠키 정보는 사라진다.

UIWebView can save and restore cookies. Although application has terminated, the cookies and the session can be restored.

 

 

애플리케이션 종료시 쿠키 저장

우선 애플리케이션이 종료되는 이벤트를 잡아야 한다. 현재 멀티태스킹이 지원되는 SDK를 사용하여 애플리케이션을 만든 경우 Application Delegate의 아래 메소드가 호출된다.

- (void)applicationDidEnterBackground:(UIApplication *)application 

멀티태스킹이 지원되기 이전 버전의 SDK나 멀티태스킹을 사용하지 않도록 설정한 애플리케이션은 다음고 같은 메소드에서 종료 이벤트를 잡을 수 있다.

- (void)applicationWillTerminate:(UIApplication *)application 

쿠키 정보를 저장할 때 UIWebView 인스턴스는 필요 없다 [NSHTTPCookieStorage sharedHTTPCookieStorage] 메소드를 호출하면 애플리케이션에게 할당된 쿠키 저장소를 반환받는다. 즉 시스템 브라우저인 Safari나 다른 애플리케이션과 공유하지 않는 애플리케이션만의 쿠키 저장소이다. (iOS는 쿠키를 공유하지 않지만 Mac OS는 쿠키를 공유한다)

{     NSLog(@"%@", @"PersisteWebCookie");     NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];     NSData *cookieData = [NSKeyedArchiver archivedDataWithRootObject:cookies];     [[NSUserDefaults standardUserDefaults] setObject:cookieData forKey:@"MySavedCookies"];     NSLog(@"%@", @"PersisteWebCookie Saved"); } 

저장소에 현재 저장된 쿠키를 배열로(NSArray) 받아와서 NSUserDefaults에 저장할 수 있도록 NSKeyedArchiver를 통해 NSData 인스턴스로 변환한다. 키 값은 MySavedCookies를 사용하여 NSUserDefaults에 저장해둔다.

일반적으로 쿠키는 브라우저나 애플리케이션이 종료되면(iOS의 경우 홈버튼을 더블탭 하여 마이너스 아이콘으로 종료시키면) 쿠키 정보가 삭제된다. 하지만 위와 같이 저장한 쿠키 정보는 애플리케이션을 다시 실행시켰을 때 복구할 수 있다.

애플리케이션으로 돌아왔을 때

애플리케이션이 백그라운드에서 돌아오거나 다시 실행되는 이벤트는 보통 다음 Application Delegate의 메소드에서 처리한다.

- (BOOL)application:(UIApplication *)application     didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 

쿠키를 다시 되살리는 방법은 저장하는 순서의 반대로 한다. 키 값을 MySavedCookies로 하여 NSUserDefaults로부터 데이터를 꺼내오고 배열로 만든 후 하나씩 다시 쿠키 저장소에 저장한다.

{     NSLog(@"%@", @"PersisteWebCookie");     NSData *cookiesdata = [[NSUserDefaults standardUserDefaults] objectForKey:@"MySavedCookies"];     if([cookiesdata length]) {         NSArray *cookies = [NSKeyedUnarchiver unarchiveObjectWithData:cookiesdata];         NSHTTPCookie *cookie;          for (cookie in cookies) {             [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];         }     }     NSLog(@"%@", @"PersisteWebCookie Restored"); }

 

 

 

=================================

=================================

=================================

 

 

출처: http://www.picomax.net/xe/study/22881

 

 

보통 UIWebView 에서 특정 URL로 이동할 때 아래와 같은 코드를 사용한다.

 

NSURLRequest를 이용한 URL 이동

 

1
2
3
4
5
6
7
8
UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.frame];
NSURL *url = [NSURL URLWithString:@"http://www.hooni.net"];
 
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
 
[webView setBackgroundColor:[UIColor clearColor]];
[self.view addSubview:webView];

 

 

쿠키(Cookie)와 같은 헤더에 값을 실어서 보낼 때는 Request에 값을 세팅해야 하므로,

아래 코드와 같이 NSMutableURLRequest를 사용한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.frame];
NSURL *url = [NSURL URLWithString:@"http://www.hooni.net"];
 
NSMutableURLRequest *mutableRequest =
    [NSMutableURLRequest requestWithURL:url];
 
NSLog(@"%@", @"PersisteWebCookie");
NSMutableString *cookieStringToSet = [[NSMutableString alloc] init];
 
[cookieStringToSet appendFormat:@"ENC=%@;", @"6EA4E3F7E03A9..."];
 
if (cookieStringToSet.length) {
    [mutableRequest setValue:cookieStringToSet
        forHTTPHeaderField:@"Cookie"];
 
    NSLog(@"Cookie : %@", cookieStringToSet);
}
NSLog(@"%@", @"PersisteWebCookie Restored");
 
[webView loadRequest:mutableRequest];
 
[webView setBackgroundColor:[UIColor clearColor]];
[self.view addSubview:webView];

 

 

기존에 저장된 쿠키를 읽어오는 코드와 섞으면 아래처럼 활용할 수 있다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.frame];
NSURL *url = [NSURL URLWithString:@"http://www.hooni.net"];
NSMutableURLRequest *mutableRequest =
    [NSMutableURLRequest requestWithURL:url];
 
NSLog(@"%@", @"PersisteWebCookie");
NSData *cookiesdata = [[NSUserDefaults standardUserDefaults]
    objectForKey:@"MySavedCookies"];
 
if([cookiesdata length]) {
    NSArray *cookies =
        [NSKeyedUnarchiver unarchiveObjectWithData:cookiesdata];
 
    for (cookie in cookies) {
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
        NSLog(@"cookiesdata ; %@", cookie);
    }
     
    NSMutableString *cookieStringToSet = [[NSMutableString alloc] init];
    for (NSHTTPCookie *cookie in cookies) {
        [cookieStringToSet appendFormat:@"%@=%@;",
            cookie.name, cookie.value];
    }
     
    if (cookieStringToSet.length) {
        [mutableRequest setValue:cookieStringToSet
            forHTTPHeaderField:@"Cookie"];
 
        NSLog(@"Cookie : %@", cookieStringToSet);
    }
}
NSLog(@"%@", @"PersisteWebCookie Restored");
     
[webView loadRequest:mutableRequest];
 
[webView setBackgroundColor:[UIColor clearColor]];
[self.view addSubview:webView];
 

 

 

=================================

=================================

=================================

 

 

 

 

출처: http://msdev.sakura.ne.jp/know-how/?p=62

 

 

 

UIWebViewとNSURLConnectionでセッションを共有する

UIWebViewとNSURLConnection間でセッションを共有するためのクラスをSwiftで作成しました。
Androidでは簡単に実装できましたが、iOSではうまくセッション共有されずなかなか苦労しました。

今回はNSURLSessionではなくNSURLConnectionを使用しましたが、NSMutableURLRequest#setAllHTTPHeaderFieldsにクッキーを設定するので、どちらも動作するはずです。
NSMutableURLRequest#setAllHTTPHeaderFieldsへクッキーヘッダを設定するには、
下記クラスのgetCookiesHeaderFromCookieStorage()または、getCookiesHeaderFromInappData()を使用してください。

また、POST送信後のレスポンスに含まれるクッキーは、getCookiesHeaderFromCookieStorage()でアプリ内データに保存できます。

下記サンプルではアプリ起動直後にPOST通信後、UIWebViewでページを開き、またそのページが読み込み完了してからPOST通信を実行します。
その後アプリを終了し、次回起動時にPOST通信をする際にクッキーが保持された状態になっています。

 

ダウンロードする場合はこちらからどうぞ:
SessionManager.swift
Post.swift

 

使い方

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
var sessionManager: SessionManager!
 
override func viewDidLoad() {
    // セッション共有クラスの初期化
    var sessionManager: SessionManager = SessionManager()
     
    // POST通信情報の準備
    var post: Post = Post()  // 簡易POST通信クラス(参照: 下記post.swift)
    var url: String = &quot;http://www.example.com/post.php&quot;    // データの送信先
    var postData: Dictionary&lt;String, AnyObject&gt; = [&quot;key&quot;: &quot;val&quot;]
     
    // POSTする前にアプリ内データに保存しているクッキーを、共有クッキーに設定する
    sessionManager.getSession(NSURL(string: url)!)
     
    // POST通信
    post.post(url, data: postData)
     
     
    // UIWebViewのアクセス情報を準備する
    var loadUrl: NSURL = NSURL(string: &quot;http://www.example.com/test.php&quot;)!
    var request: NSURLRequest = NSURLRequest(URL: loadUrl)
     
    // UIWebViewでPOST通信のセッションを保持したままアクセスする
    webView.loadRequest(request)
}
 
func webViewDidFinishLoad(webView: UIWebView) {
    if let url: String = webView.stringByEvaluatingJavaScriptFromString("document.URL") {
       sessionManager.getSession(NSURL(string: url)!)
     
       // POSTしてセッションを保存してからページを読み込む
       var post: PostClass = PostClass()
       var url: String = "http://www.example.com/post.php"
       var data: Dictionary<String, AnyObject> = ["data": "webViewDidFinishLoad", "now": NSDate().timeIntervalSince1970]
     
       // POST
       PostClass().post(url, data: data)
       // POST通信後に共有クッキーからクッキーを取得し、アプリ内データに保存する
       sessionMan.sessionManager(NSURL(string: url)!)
    }
}

 

セッション共有クラス: SessionManager.swift

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//
//  SessionManager.swift
//  TEST_session
//
//  Created by M.S. on 2015/04/26.
//  Copyright (c) 2015年 M.S. All rights reserved.
//
 
import Foundation
 
class SessionManager: NSObject {
    /**
    アプリ内データに保存されているクッキーを指定URLの共有クッキーにセットする
     
    :param: url String URL
    */
    internal func setSession(url: NSURL) -> Void {
        var prefs: NSUserDefaults = NSUserDefaults.standardUserDefaults()
         
        if let cookieData: NSData = prefs.dataForKey("cookies") {
            var cookiesArray: Array<NSHTTPCookie> = NSKeyedUnarchiver.unarchiveObjectWithData(cookieData) as! Array<NSHTTPCookie>
            var cookieStorage: NSHTTPCookieStorage = NSHTTPCookieStorage.sharedHTTPCookieStorage()
             
            cookieStorage.setCookies(cookiesArray, forURL: url, mainDocumentURL: nil)
        }
    }
     
    /**
    共有クッキーから指定URLのクッキーを取得する
     
    :param: url String URL
    */
    internal func getSession(url: NSURL) -> Void {
        var cookieStorage: NSHTTPCookieStorage = NSHTTPCookieStorage.sharedHTTPCookieStorage()
         
        if let cookiesArray: Array<NSHTTPCookie> = cookieStorage.cookiesForURL(url) as? Array<NSHTTPCookie> {
            var cookieData: NSData = NSKeyedArchiver.archivedDataWithRootObject(cookiesArray)
            var prefs: NSUserDefaults = NSUserDefaults.standardUserDefaults()
             
            prefs.setValue(cookieData, forKey: "cookies")
            prefs.synchronize()
        }
    }
     
    /**
    HTTPレスポンスヘッダからクッキーを取得し保存する
     
    :param: httpResponse NSHTTPURLResponse HTTPレスポンスヘッダ
    :param: url String URL
    */
    internal func getSessionFromResponseHeader(httpResponse: NSHTTPURLResponse, url: NSURL) -> Void {
        if let cookiesArray: Array<NSHTTPCookie> = NSHTTPCookie.cookiesWithResponseHeaderFields(httpResponse.allHeaderFields, forURL: url) as? Array<NSHTTPCookie> {
            var cookieData: NSData = NSKeyedArchiver.archivedDataWithRootObject(cookiesArray)
            var prefs: NSUserDefaults = NSUserDefaults.standardUserDefaults()
             
            prefs.setValue(cookieData, forKey: "cookies")
            prefs.synchronize()
        }
    }
  
    /**
    共有クッキーからリクエスト用クッキーヘッダを生成する
 
    :param: url String URL
     
    :returns: [NSObject, AnyObject]? リクエスト用クッキーヘッダ
    */
    internal func getCookiesHeaderFromCookieStorage(url: NSURL) -> Dictionary<NSObject, AnyObject>? {
        var cookieStorage: NSHTTPCookieStorage = NSHTTPCookieStorage.sharedHTTPCookieStorage()
         
        if let cookiesArray: Array<NSHTTPCookie> = cookieStorage.cookiesForURL(url) as? Array<NSHTTPCookie> {
            return NSHTTPCookie.requestHeaderFieldsWithCookies(cookiesArray)
        }
        
        return nil
    }
 
    /**
    アプリ内データに保存されているクッキーからリクエスト用クッキーヘッダを生成する
     
    :param: url String URL
 
    :returns: [NSObject, AnyObject]? リクエスト用クッキーヘッダ
    */
    internal func getCookiesHeaderFromInappData(url: NSURL) -> Dictionary<NSObject, AnyObject>? {
        setSession(url)
         
        return getCookiesHeaderFromCookieStorage(url)
    }
}

 

簡易POST通信クラス: Post.swift

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//
//  Post.swift
//  TEST_session
//
//  Created by M.S. on 2015/04/26.
//  Copyright (c) 2015年 M.S. All rights reserved.
//
 
import Foundation
 
class PostClass : NSObject, NSURLSessionDelegate {
    internal func post(url: String, data: Dictionary<String, AnyObject>) -> Void {
        var url: NSURL! = NSURL(string: "http://msdevapps.net/test/post.php")
        var paramsArray: Array<String> = Array()
        var body: String = ""
        var sessionMan: SessionManager = SessionManager()
        var sessionConfig: NSURLSessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
        var session: NSURLSession = NSURLSession(configuration: sessionConfig)
        var request: NSMutableURLRequest = NSMutableURLRequest(URL: url)
 
        for key: String in data.keys {
            if let val: AnyObject = data[key] {
                paramsArray.append(String("\(key)=\(val)"))
            } else {
                paramsArray.append(String("\(key)="))
            }
        }
        body = join("&", paramsArray)
 
        request.HTTPMethod = "POST"
        request.allHTTPHeaderFields = sessionMan.getCookiesHeaderFromCookieStorage(url)
        request.HTTPBody = body.dataUsingEncoding(NSUTF8StringEncoding)
 
        var httpResponse: NSHTTPURLResponse = NSHTTPURLResponse()
        var recvData: NSData = NSData()
        var rl: CFRunLoopRef = CFRunLoopGetCurrent()
 
        NSURLConnection.sendAsynchronousRequest(
            request, queue: NSOperationQueue.mainQueue(),
            completionHandler: { (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
                if (error == nil) {
                    httpResponse = response as! NSHTTPURLResponse
                    recvData = data
                }
 
                CFRunLoopStop(rl)
            }
        )
        CFRunLoopRun()
 
        sessionMan.getSessionFromResponseHeader(httpResponse, url: url)
    }
}
コメントはありません。

=================================

=================================

=================================

 

 

 

출처: http://cheju.tistory.com/entry/ios-webView%EC%97%90%EC%84%9C-%EC%BF%A0%ED%82%A4-%EA%B3%B5%EC%9C%A0%ED%95%98%EA%B8%B0

 

 

[ios] webView에서 쿠키 공유하기

 

    [NSHTTPCookieStorage sharedHTTPCookieStorage].cookieAcceptPolicy =

 

    NSHTTPCookieAcceptPolicyAlways;

 

 

// UIWebview delegate

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 


함수에 추가해서 사용하면된다. 

 

IOS7이상부터 가능함.

 

 

=================================

=================================

=================================

 

 

출처: http://iphone.a2big.com/_board/content.php?id=417&pass_id=16&secret=0&slug=resent_new

 

웹 사이트에 로그인 할때 NSURLConnection class의 인스터스를 생성하고 delegate로 설정 한 이후에 쿠키값을 설정 하면 될것 같네요. 

 

(예제) 

 

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@\"http://www.naver.com/\"]]; 

 

NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self]; // 딜리게이트 메소스 구현 

 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *)response; 

 

NSDictionary *fields = [HTTPResponse allHeaderFields]; NSString *cookie = [fields valueForKey:\"Set-Cookie\"]; // It is your cookie } //쿠키 문자열을 유지 하거나 복사 합니다. 

 

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@\"http://www.naver.com/\"]]; [request addValue:cookie forHTTPHeaderField:\"Cookie\"];

 

 

 

=================================

=================================

=================================

 

 

출처: http://xcode5.tistory.com/entry/NSURLRequest-%EC%84%9C%EB%B2%84%EC%97%90-POST-%EC%9A%94%EC%B2%AD

 

- (void)connectToServer

{

NSString *smsURL = @"ServerURL";
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];

 

NSString *post = [NSString stringWithFormat:@"userid=%@",@"testID"]; NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding

 

allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:
@"%lu",(unsigned long)

 

[postData length]];

 

[request setURL:[NSURL URLWithString:smsURL]];
[request setHTTPMethod:
@"POST"];
[request setValue:postLength forHTTPHeaderField:
@"Content-Length"]; [request setValue:@"Mozilla/4.0 (compatible;)" forHTTPHeaderField:@"User-

 

Agent"];
[request setValue:
@"application/x-www-form-urlencoded"

 

forHTTPHeaderField:@"Content-Type"]; [request setHTTPBody:postData];

 

[NSURLConnection connectionWithRequest:request delegate:self ]; 

}

 

/*
아래 Delegate에서는 HTML이 처리되고 난 후 받는 데이터를 얻을 수 있다. */

- (void)connection:(NSURLConnection *)connection didReceiveData(NSData *)data {

NSString *returnString = [[NSString alloc] initWithData:data encoding: NSUTF8StringEncoding];

 

NSLog(@"%@",returnString); 

}

/*
아래 Delegate를 이용하면 post를 보낸 후 쿠키를 얻을 수 있다. */

- (void)connection:(NSURLConnection *)connection didReceiveResponse:

(NSURLResponse *)aResponse

{
    NSHTTPCookie *cookie;
    for (cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage]     cookies]) {

NSLog(@"%@",[cookie description]);

}

} 

 

 

출처 http://fmttm.egloos.com/viewer/4324991

 

 

=================================

=================================

=================================

 

 

출처: http://developers.tistory.com/54

 

- (void)connectToServer

{

NSString *smsURL = @"http://www.google.co.kr";

NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];

 

 

NSString *post = [NSString stringWithFormat:@"password=%@&id=%@",@"password",@"id"];

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

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

 

 

[request setURL:[NSURL URLWithString:smsURL]];

[request setHTTPMethod:@"POST"];

[request setValue:postLength forHTTPHeaderField:@"Content-Length"];

[request setValue:@"Mozilla/4.0 (compatible;)" forHTTPHeaderField:@"User-Agent"];

[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];

[request setHTTPBody:postData];

 

[NSURLConnection connectionWithRequest:request delegate:self ];

}

/* 위와 같은 방식으로 smsURL이라는 주소로 post 형식으로 데이터를 감싸 전송이 가능해진다.*/

 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

{

 

NSString *returnString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

NSLog(returnString);

}

/* 위 Delegate에서는 HTML이 처리되고 난 후 받는 데이터를 얻을 수 있다.*/

 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)aResponse

{

NSHTTPCookie *cookie;

int i=0;

for (cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies])

{

NSLog([cookie description]);

}

}


/* 위 Delegate를 이용하면 post를 보낸 후 쿠키를 얻을 수 있다.*/

------------------------------아래는 동기식으로 바로 가져오기---------------

 

-(NSString *)getDetailInfo:(NSDictionary *)bodyObject targetURL:(NSString *)connectionURL

{

// URL Request 객체 생성

NSLog(@"상세 데이터 가져오기");

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURLURLWithString:connectionURL]

  cachePolicy:NSURLRequestUseProtocolCachePolicy

   timeoutInterval:1000];

// 통신방식 정의 (POST, GET)

 

[request setHTTPMethod:@"POST"];

// bodyObject의 객체가 존재할 경우 QueryString형태로 변환

if(bodyObject)

{

// 임시 변수 선언

NSMutableArray *parts = [NSMutableArray array];

NSString *part;

id key;

id value;

// 값을 하나하나 변환

for(key in bodyObject)

{

value = [bodyObject objectForKey:key];

part = [NSString stringWithFormat:@"%@=%@", [keystringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],

[value stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

[parts addObject:part];

}

// 값들을 &로 연결하여 Body에 사용

[request setHTTPBody:[[parts componentsJoinedByString:@"&"]dataUsingEncoding:NSUTF8StringEncoding]];

}

// Request를 사용하여 실제 연결을 시도하는 NSURLConnection 인스턴스 생성

NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nilerror:nil];

//NSString *str = [[NSString alloc] initWithData:returnData encoding:0x80000000 + kCFStringEncodingDOSKorean];

NSString *str = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];

 

 

return str;

//NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

//NSString *documentsDirectory = [paths objectAtIndex:0];

//NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"detailData.array"];

 

//[str writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];

 

//return filePath;

 

}

 

 

 

 

 

=================================

=================================

=================================

 

 

 

출처: http://soo84.tistory.com/252

 

문제. 별도의 로그인을 통해 받은 세션값을 웹뷰에 할당하고, 다른 계정으로 로그인 시 기존 쿠키값이 남아있는 문제가 발생. 이를 해결하기 위해 전체 쿠키 삭제.

 

 

// 모든 캐쉬 삭제

-(void)deleteAllCookie {

NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];

 

for (NSHTTPCookie *cookie in [storage cookies])

{

[storage deleteCookie:cookie];

}

 

}

 

 //특정 도메인만 삭제

-(void)deleteCookieDomain:(NSString *)domain {

 

NSHTTPCookieStorage *cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage];

NSArray *someCookies = [cookies cookiesForURL:[NSURL URLWithString:domain]];

 

for (NSHTTPCookie *cookie in someCookies){

[cookies deleteCookie:cookie];

}

 

}

 

//webview loadRequest를 호출 후 할당된 쿠키 제거

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {

[[NSURLCache sharedURLCache] removeCachedResponseForRequest:request];

 

[[NSURLCache sharedURLCache] removeAllCachedResponses];

}


//webview 초기화 및 쿠키 삭제

1
2
3
4
5
6
7
8
9
10
11
12
13
#pragma mark - WebView
-(void)initWebView
{
    // 모든 캐쉬 삭제
    NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    for (NSHTTPCookie *cookie in [storage cookies]) {
        [storage deleteCookie:cookie];
    }
    
    self.mWebView = [self.mWebView init];
    self.mWebView.delegate = self;
    self.mWebView.scrollView.bounces = NO;
}
cs

 

//쿠키 할당 받기 NSURLConnection 사용 시(로그인 후)

 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)aResponse

NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *) aResponse;

NSDictionary *cookieDictionary = [[NSMutableDictionary allocinitWithDictionary:[HTTPResponse allHeaderFields]];

 

//저장된 쿠키값 웹뷰에 할당하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    //webview set cookie
 
    NSString *parameter = [NSString stringWithFormat:@"id=id1111"];
 
 
    NSURL *url = [NSURL URLWithString:urlStr];
 
    NSMutableURLRequest *webRequest = [NSMutableURLRequest requestWithURL:url
                                                   cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                timeoutInterval:10.0f];
 
    [webRequest addValue:[cookieDictionary valueForKey:@"Set-Cookie"] forHTTPHeaderField:@"Cookie"];
 
    [webRequest setHTTPMethod:@"POST"];
    [webRequest setHTTPBody:[parameter dataUsingEncoding:NSUTF8StringEncoding]];
    
    [_mWebView loadRequest:webRequest];
cs

 

웹뷰에 쿠키를 할당하거나 또는 별도로 로그인 시 받은 고유 id값을 파라메터로 전달해 주는 방법도 있다. 이는 서버 개발자와 상의해서 쿠키로 처리할 것인지 파라메터로 처리할 것인지 협의 후 결정

 

고찰. 

상태 : 로그인 후 생성된 사용자 정보를 webview에 파라메터로 전달하여 세션 유지

문제 : 로그인 처리 후 webview에 세션을 유지하기 위한 파라메터를 던져서 호출할 경우 초기 loadRequest시 세션이 유지 되지 않아 0.6초 delay를 통해 다시 webView를 같은 url로 loadRequest하여 처리하였으나 네트워크나 서버 상태에 따라 연결되지 않는다.

원하는 방향 : webview 호출 시 한번에 세션을 유지하고 싶음.

테스트 내용 :

1. 로그인 시 NSURLConnection통해 얻은 쿠키값을 저장 후 webview에 전달하였으나, 다른 페이지를 호출하거나 뒤로가기 선택 시 세션 연동이 불안정한 상태로 유지 됨.

2. NSURLConnection를 통한 로그인 후 할당 받은 세션들을 지우고 webview에 파라메터를 던져서 호출 하였으나 세션이 할당되지 

 

 

=================================

=================================

=================================

 

 

*추가링크

- https://books.google.co.kr/books?id=xg-FAgAAQBAJ&pg=PT63&lpg=PT63&dq=NSURLConnection+%EC%BF%A0%ED%82%A4&source=bl&ots=vRYhKMEtlf&sig=0AyShFz6yMf4zpqlssYSFnKnqac&hl=ko&sa=X&ved=0ahUKEwjt58mL9JXQAhUIULwKHYH-DG0Q6AEIWTAI#v=onepage&q=NSURLConnection%20%EC%BF%A0%ED%82%A4&f=false

 

 

 

=================================

=================================

=================================

 

 

 

반응형