2016.06.29

At present, some companies use UINavigationController+WebView or NavigationController+UITabbarVC+WebView to quickly create an app. In this way, it is inevitable to use cookies to interact with Html5. Here are some ways to add cookies in common situations:

A UIWebView. :

// The method to store cookies in the factory class
+ (void)saveCookies {
    // Create a mutable dictionary to store cookies
    NSMutableDictionary *fromappDict = [NSMutableDictionary dictionary];
    [fromappDict setObject:@"fromapp" forKey:NSHTTPCookieName];
    [fromappDict setObject:@"ios" forKey:NSHTTPCookieValue];
    // kDomain is the company app url
    [fromappDict setObject:kDomain forKey:NSHTTPCookieDomain];
    [fromappDict setObject:kDomain forKey:NSHTTPCookieOriginURL];
    [fromappDict setObject:@ "/" forKey:NSHTTPCookiePath];
    [fromappDict setObject:@ "0" forKey:NSHTTPCookieVersion];

    // Convert mutable dictionaries to cookies
    NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:fromappDict];

    / / get cookieStorage
    NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]
 
    / / store cookies
    [cookieStorage setCookie:cookie];
}
Copy the code
  • UIWebView is used for a long time, as long as the corresponding cookie is set in cookieStorage, it will be automatically added each time;
  • However, such a disadvantage is that with the increase of interaction with H5, cookies occupy more and more space. Each interaction carries a large number of cookies, which not only increases the pressure on the server, but also wastes user traffic. For example, each interaction carries 5KB of cookie content, but only two or three hundred bytes are really used.

2. WKWebView

  • WKWebView compared to UIWebView:

    • Twice as fast, but with half as much memory;
    • Cookies are no longer carried automatically and need to be set manually;
    • For example, the four tabbars at the bottom of the APP are also web pages. If you click under UIWebView, the whole H5 page will flash white. However, if you click under WKWebView, the effect of the four Tabbars is more similar to the effect of the original app without the phenomenon of flash white.
    • Some proxy methods have been added or subtracted to facilitate protocol interception and progress bar display
  • 1. Store cookies in WKUserScript during creation

    WKWebViewConfiguration *webConfig = [[WKWebViewConfiguration alloc] init];
    // Set preferences
    webConfig.preferences = [[WKPreferences alloc] init];
    // Default is 0
    webConfig.preferences.minimumFontSize = 10;
    // The default is YES
    webConfig.preferences.javaScriptEnabled = YES;
    // On iOS, the default value is NO, indicating that the window cannot be opened automatically
    webConfig.preferences.javaScriptCanOpenWindowsAutomatically = NO;

    // Web content processing pool
    webConfig.processPool = [[WKProcessPool alloc] init];
    // Set all cookies to document.cookie = 'key=value'; Form splicing
    #warning #warning #warning #warning #warning # Warning # Warning
    NSString *cookieValue = @"document.cookie = 'fromapp=ios'; document.cookie = 'channel=appstore';";
    
    // Add cookies to H5 for recognition, indicating that the address is opened on ios
    WKUserContentController* userContentController = WKUserContentController.new;
    WKUserScript * cookieScript = [[WKUserScript alloc]
                                   initWithSource: cookieValue
                                   injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
    [userContentController addUserScript:cookieScript];
    webConfig.userContentController = userContentController;

    WKWebView *wkWebView = [[WKWebView alloc] initWithFrame:frame configuration:webConfig];

    wkWebView.UIDelegate = wkWebView;
    wkWebView.navigationDelegate = wkWebView;
Copy the code
  • 2. Add cookies when loading a URL

If WKWebView needs to add cookies when loading the URL, you need to manually fetch all the cookies in the current NSHTTPCookieStorage and place the cookies in the NSMutableURLRequest header

- (void)loadRequestWithUrlString:(NSString *)urlString {
    
    // Get the returned cookie here
    NSMutableDictionary *cookieDic = [NSMutableDictionary dictionary];
    
    NSMutableString *cookieValue = [NSMutableString stringWithFormat:@ ""];
    NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    
    for (NSHTTPCookie *cookie in [cookieJar cookies]) {
        [cookieDic setObject:cookie.value forKey:cookie.name];
    }
    
    // The cookie is repeated
    for (NSString *key in cookieDic) {
        NSString *appendString = [NSString stringWithFormat:@ % @ = % @; "", key, [cookieDic valueForKey:key]];
        [cookieValue appendString:appendString];
    }

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
    [request addValue:cookieValue forHTTPHeaderField:@"Cookie"];

    [self loadRequest:request];
}
Copy the code

3.AFNetworking

AFNetworking Is a common way to access cookies. It’s all in the code

    / / get AFHTTPRequestOperationManager
    AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];
    
    // Create a mutable dictionary for storing cookies
    NSMutableDictionary *cookieDic = [NSMutableDictionary dictionary];
    
    // Store the newly added cookie
    #warning The single Cookie was fine, but the factory method was concatenated with a value containing six devices, and the semicolon was forgotten
    # Warning because it does not affect the function, but the cookie behind the automatic concatenation, H5 side also can not identify, risk caused a major accident (involving finance. (Give me a "thumbs up" for this pit)
    NSMutableString *cookieValue = [NSMutableString stringWithFormat:@"fromapp=ios;"];

    / / to get
    NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    
    for (NSHTTPCookie *cookie in [cookieJar cookies]) {
        [cookieDic setObject:cookie.value forKey:cookie.name];
    }
    
    // The cookie is repeated
    for (NSString *key in cookieDic) {
        NSString *appendString = [NSString stringWithFormat:@ % @ = % @; "", key, [cookieDic valueForKey:key]];
        [cookieValue appendString:appendString];
    }

    // Stores the cookie in the request header
    [operationManager.requestSerializer setValue:cookieValue forHTTPHeaderField:@"Cookie"];
    
    // Concatenate url addresses
    NSString *urlStr = [NSString stringWithFormat:@ % @ % @ "", kHostIP, kPath];
    
    // Set the parameter dictionary
    NSDictionary *paraDict = @{
                                  @"key" : value
                                  };
    // Send the request and process the result
    [operationManager POST:urlStr parameters:paraDict success:^(AFHTTPRequestOperation * _Nonnull operation, id  _Nonnull responseObject) {
        
         NSLog(@"responseObject-->%@", responseObject);
        
    } failure:^(AFHTTPRequestOperation * _Nullable operation, NSError * _Nonnull error) {

         NSLog(@"error-->%@", error);
    }];
Copy the code