├── GGWkCookie ├── Assets │ ├── .gitkeep │ └── GGCookie.js └── Classes │ ├── .gitkeep │ ├── WKWebView+Swizzling.h │ ├── GGWkCookie.h │ ├── GGWkBundelManager.h │ ├── WKWebView+GGCookie.h │ ├── WKWebView+Attribute.h │ ├── WKWebView+Attribute.m │ ├── GGWkBundelManager.m │ ├── WKWebView+Swizzling.m │ └── WKWebView+GGCookie.m ├── _Pods.xcodeproj ├── Example ├── Tests │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── Tests-Prefix.pch │ ├── Tests-Info.plist │ └── Tests.m ├── GGWkCookie │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── Class │ │ ├── Controller │ │ │ ├── GGViewController.h │ │ │ ├── GGCookiesViewController.h │ │ │ ├── GGCookiesViewController.m │ │ │ ├── GGCookiesViewController.xib │ │ │ └── GGViewController.m │ │ └── View │ │ │ ├── GGCookieCell.h │ │ │ ├── GGAddCookieCell.h │ │ │ ├── GGCookieCell.m │ │ │ ├── GGAddCookieCell.m │ │ │ ├── GGCookieCell.xib │ │ │ └── GGAddCookieCell.xib │ ├── GGAppDelegate.h │ ├── GGWkCookie-Prefix.pch │ ├── main.m │ ├── GGWkCookie-Info.plist │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ └── GGAppDelegate.m ├── Podfile ├── GGWkCookie.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── GGWkCookie-Example.xcscheme │ └── project.pbxproj └── GGWkCookie.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── .travis.yml ├── .gitignore ├── LICENSE ├── GGWkCookie.podspec └── README.md /GGWkCookie/Assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /GGWkCookie/Classes/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj -------------------------------------------------------------------------------- /Example/Tests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/GGWkCookie/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/Tests/Tests-Prefix.pch: -------------------------------------------------------------------------------- 1 | // The contents of this file are implicitly included at the beginning of every test case source file. 2 | 3 | #ifdef __OBJC__ 4 | 5 | 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | 3 | target 'GGWkCookie_Example' do 4 | pod 'GGWkCookie', :path => '../' 5 | 6 | target 'GGWkCookie_Tests' do 7 | inherit! :search_paths 8 | 9 | 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /Example/GGWkCookie.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /GGWkCookie/Classes/WKWebView+Swizzling.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKWebView+Swizzling.h 3 | // GGWkCookie 4 | // 5 | // Created by GarrettGao on 2018/9/14. 6 | // 7 | 8 | #import 9 | 10 | @interface WKWebView (Swizzling) 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Example/GGWkCookie/Class/Controller/GGViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // GGViewController.h 3 | // GGWkCookie 4 | // 5 | // Created by gaoguohao on 09/14/2018. 6 | // Copyright (c) 2018 gaoguohao. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface GGViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/GGWkCookie.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/GGWkCookie.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /GGWkCookie/Classes/GGWkCookie.h: -------------------------------------------------------------------------------- 1 | // 2 | // GGWkCookie.h 3 | // Pods 4 | // 5 | // Created by GarrettGao on 2018/9/14. 6 | // 7 | 8 | #ifndef GGWkCookie_h 9 | #define GGWkCookie_h 10 | 11 | #import "WKWebView+GGCookie.h" 12 | #import "WKWebView+Attribute.h" 13 | #import "WKWebView+Swizzling.h" 14 | 15 | #endif /* GGWkCookie_h */ 16 | -------------------------------------------------------------------------------- /Example/GGWkCookie/GGAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // GGAppDelegate.h 3 | // GGWkCookie 4 | // 5 | // Created by gaoguohao on 09/14/2018. 6 | // Copyright (c) 2018 gaoguohao. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface GGAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Example/GGWkCookie/Class/View/GGCookieCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // GGCookieCell.h 3 | // GGWkCookie_Example 4 | // 5 | // Created by GarrettGao on 2018/9/17. 6 | // Copyright © 2018年 gaoguohao. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface GGCookieCell : UITableViewCell 12 | 13 | @property (nonatomic, strong) NSString *content; 14 | 15 | + (GGCookieCell *)loadXib; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Example/GGWkCookie/Class/Controller/GGCookiesViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // GGCookiesViewController.h 3 | // GGWkCookie_Example 4 | // 5 | // Created by GarrettGao on 2018/9/17. 6 | // Copyright © 2018年 gaoguohao. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface GGCookiesViewController : UIViewController 12 | 13 | @property (nonatomic, strong) NSMutableDictionary *cookieDic; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Example/GGWkCookie/GGWkCookie-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | @import UIKit; 15 | @import Foundation; 16 | #endif 17 | -------------------------------------------------------------------------------- /Example/GGWkCookie/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // GGWkCookie 4 | // 5 | // Created by gaoguohao on 09/14/2018. 6 | // Copyright (c) 2018 gaoguohao. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | #import "GGAppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) 13 | { 14 | @autoreleasepool { 15 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([GGAppDelegate class])); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /GGWkCookie/Classes/GGWkBundelManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // GGWkBundelManager.h 3 | // GGWkCookie 4 | // 5 | // Created by GarrettGao on 2018/9/14. 6 | // 7 | 8 | #import 9 | 10 | @interface GGWkBundelManager : NSObject 11 | 12 | /** 13 | 读取本地js文件 14 | 15 | @param name 文件名称 16 | @param type 文件类型 17 | @return 返回js代码 18 | */ 19 | + (NSString *)loadJsCodeWithFileName:(NSString *)name withType:(NSString *)type; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /GGWkCookie/Classes/WKWebView+GGCookie.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKWebView+GGCookie.h 3 | // GGWkCookie 4 | // 5 | // Created by GarrettGao on 2018/9/14. 6 | // 7 | 8 | #import 9 | 10 | 11 | @interface WKWebView (GGCookie) 12 | 13 | 14 | /// 开启自定义cookie,此方法需要放到 loadRequest之前 15 | - (void)startCustomCookie; 16 | 17 | /** 18 | 刷新 cookie 设置 19 | 代理方法: - (NSDictionary *)webviewGetCookieKeyValue 会重新回调 20 | */ 21 | - (void)reloadCookie; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /GGWkCookie/Classes/WKWebView+Attribute.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKWebView+Attribute.h 3 | // GGWkCookie 4 | // 5 | // Created by GarrettGao on 2018/9/17. 6 | // 7 | 8 | #import 9 | 10 | @protocol GGWkWebViewDelegate 11 | 12 | /// 获取传入cookie的字典 13 | - (NSDictionary *)webviewSetAppCookieKeyAndValue; 14 | 15 | @end 16 | 17 | @interface WKWebView (Attribute) 18 | 19 | /// cookie代理 20 | @property (nonatomic, weak) id cookieDelegate; 21 | 22 | /// 自定义 cookie 值 23 | @property (nonatomic, strong) NSDictionary *cookieKeyValue; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Example/GGWkCookie/Class/View/GGAddCookieCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // GGAddCookieCell.h 3 | // GGWkCookie_Example 4 | // 5 | // Created by GarrettGao on 2018/9/17. 6 | // Copyright © 2018年 gaoguohao. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @protocol GGAddCookieCellDelegate 13 | 14 | - (void)addCookieWithName:(NSString *)name withValue:(NSString *)value; 15 | 16 | @end 17 | 18 | @interface GGAddCookieCell : UITableViewCell 19 | 20 | @property (nonatomic, weak) id delegate; 21 | 22 | + (GGAddCookieCell *)loadXib; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * https://www.objc.io/issues/6-build-tools/travis-ci/ 3 | # * https://github.com/supermarin/xcpretty#usage 4 | 5 | osx_image: xcode7.3 6 | language: objective-c 7 | # cache: cocoapods 8 | # podfile: Example/Podfile 9 | # before_install: 10 | # - gem install cocoapods # Since Travis is not always on latest version 11 | # - pod install --project-directory=Example 12 | script: 13 | - set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Example/GGWkCookie.xcworkspace -scheme GGWkCookie-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty 14 | - pod lib lint 15 | -------------------------------------------------------------------------------- /Example/GGWkCookie/Class/View/GGCookieCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // GGCookieCell.m 3 | // GGWkCookie_Example 4 | // 5 | // Created by GarrettGao on 2018/9/17. 6 | // Copyright © 2018年 gaoguohao. All rights reserved. 7 | // 8 | 9 | #import "GGCookieCell.h" 10 | 11 | 12 | 13 | @implementation GGCookieCell 14 | 15 | + (GGCookieCell *)loadXib { 16 | return [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:nil options:nil].lastObject; 17 | } 18 | 19 | - (void)setContent:(NSString *)content { 20 | UILabel *label = [self viewWithTag:101]; 21 | label.text = content; 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Example/Tests/Tests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/Tests/Tests.m: -------------------------------------------------------------------------------- 1 | // 2 | // GGWkCookieTests.m 3 | // GGWkCookieTests 4 | // 5 | // Created by gaoguohao on 09/14/2018. 6 | // Copyright (c) 2018 gaoguohao. All rights reserved. 7 | // 8 | 9 | @import XCTest; 10 | 11 | @interface Tests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation Tests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata/ 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 26 | # Carthage/Checkouts 27 | 28 | Carthage/Build 29 | 30 | # We recommend against adding the Pods directory to your .gitignore. However 31 | # you should judge for yourself, the pros and cons are mentioned at: 32 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 33 | # 34 | # Note: if you ignore the Pods directory, make sure to uncomment 35 | # `pod install` in .travis.yml 36 | # 37 | Podfile.lock 38 | Pods/ 39 | -------------------------------------------------------------------------------- /Example/GGWkCookie/Class/View/GGAddCookieCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // GGAddCookieCell.m 3 | // GGWkCookie_Example 4 | // 5 | // Created by GarrettGao on 2018/9/17. 6 | // Copyright © 2018年 gaoguohao. All rights reserved. 7 | // 8 | 9 | #import "GGAddCookieCell.h" 10 | @interface GGAddCookieCell() { 11 | 12 | __weak IBOutlet UITextField *_nameTextField; 13 | __weak IBOutlet UITextField *_valueTextField; 14 | 15 | } 16 | @end 17 | 18 | @implementation GGAddCookieCell 19 | 20 | + (GGAddCookieCell *)loadXib { 21 | return [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:nil options:nil].lastObject; 22 | } 23 | 24 | #pragma mark - OnClicked 25 | 26 | - (IBAction)onAddClicked:(id)sender { 27 | if (self.delegate && [self.delegate respondsToSelector:@selector(addCookieWithName:withValue:)]) { 28 | [self.delegate addCookieWithName:_nameTextField.text 29 | withValue:_valueTextField.text]; 30 | } 31 | _valueTextField.text = _nameTextField.text = @""; 32 | } 33 | 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 gaoguohao 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /GGWkCookie.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint GGWkCookie.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'GGWkCookie' 11 | s.version = '1.0.0' 12 | s.summary = '解决 WKWebView cookie 设置难题' 13 | 14 | #s.description = <<-DESC 15 | # 解决 WKWebView cookie 设置难题。 16 | # DESC 17 | 18 | s.homepage = 'https://github.com/gaoguohao/GGWkCookie' 19 | s.license = { :type => 'MIT', :file => 'LICENSE' } 20 | s.author = { 'gaoguohao' => 'guohaoggh@163.com' } 21 | s.source = { :git => 'https://github.com/gaoguohao/GGWkCookie.git', :tag => s.version.to_s } 22 | # s.social_media_url = 'https://twitter.com/' 23 | 24 | s.ios.deployment_target = '8.0' 25 | 26 | s.source_files = 'GGWkCookie/Classes/**/*' 27 | 28 | s.resource_bundles = { 29 | 'GGWkCookie' => ['GGWkCookie/Assets/*'] 30 | } 31 | 32 | # s.public_header_files = 'GGWkCookie/Classes/GGWkCookie.h' 33 | s.frameworks = 'WebKit' 34 | end 35 | -------------------------------------------------------------------------------- /GGWkCookie/Classes/WKWebView+Attribute.m: -------------------------------------------------------------------------------- 1 | // 2 | // WKWebView+Attribute.m 3 | // GGWkCookie 4 | // 5 | // Created by GarrettGao on 2018/9/17. 6 | // 7 | 8 | #import "WKWebView+Attribute.h" 9 | #import 10 | 11 | @interface WeakObjectContainer : NSObject 12 | @property (nonatomic, readonly, weak) id object; 13 | @end 14 | 15 | @implementation WeakObjectContainer 16 | - (instancetype) initWithObject:(id)object 17 | { 18 | if (!(self = [super init])) {return nil;} 19 | _object = object; 20 | return self; 21 | } 22 | 23 | @end 24 | 25 | @implementation WKWebView (Attribute) 26 | 27 | static NSString *delegatePointer; 28 | 29 | - (void)setCookieDelegate:(id)cookieDelegate { 30 | objc_setAssociatedObject(self, &delegatePointer, [[WeakObjectContainer alloc] initWithObject:cookieDelegate], 31 | OBJC_ASSOCIATION_RETAIN_NONATOMIC); 32 | } 33 | 34 | - (id)cookieDelegate { 35 | WeakObjectContainer *container = objc_getAssociatedObject(self, &delegatePointer); 36 | return container.object; 37 | } 38 | 39 | 40 | static NSString *cookieKeyValuePointer; 41 | 42 | - (void)setCookieKeyValue:(NSDictionary *)cookieKeyValue { 43 | objc_setAssociatedObject(self, &cookieKeyValuePointer, cookieKeyValue, OBJC_ASSOCIATION_COPY_NONATOMIC); 44 | } 45 | 46 | - (NSDictionary *)cookieKeyValue { 47 | return objc_getAssociatedObject(self, &cookieKeyValuePointer); 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /GGWkCookie/Assets/GGCookie.js: -------------------------------------------------------------------------------- 1 | 2 | // 获取cookie对象 3 | var app_cookieNames = document.cookie.split('; ').map( 4 | 5 | function(cookie) { 6 | return cookie.split('=')[0]; 7 | } 8 | ) 9 | 10 | // 此代码片段主要用于获取网页的根域名 11 | var app_rootDomain = ( 12 | 13 | function() { 14 | 15 | var rootDomain = document.domain; 16 | 17 | ds = {'com':'1','cn':'1','net':'1','org':'1', 'cc':'1', 'co':'1', 'top':'1', 'vip':'1', 'club':'1', 'info':'1', 'tech': '1', 'gov': '1', 'edu': '1', 'mil': '1'}; 18 | 19 | arr = rootDomain.split('.'); 20 | 21 | for(var i = arr.length - 1; i >= 0; i--) { 22 | 23 | if (isNaN(arr[i]) && !ds[arr[i]]) { 24 | break; 25 | } 26 | } 27 | if (i > 0) { 28 | rootDomain = '.' + arr.slice(i).join('.'); 29 | } 30 | 31 | return rootDomain; 32 | } () 33 | ) 34 | 35 | 36 | // 添加cookie,且直接添加在根域名 37 | function app_setCookie(name, value) { 38 | 39 | // 检测cookie如果没有的话,再进行添加 40 | // if (app_cookieNames.indexOf(name) == -1) { 41 | // 直接将cookie中到根域名 42 | document.cookie = name + '=' + value + ';domain=' + app_rootDomain + ';path=/'; 43 | // } 44 | } 45 | 46 | 47 | // 删除某个cookie,且直接从根域名删除 48 | function app_deleteCookie(name) { 49 | 50 | var date = new Date(); 51 | 52 | date.setTime(date.getTime() -1); 53 | 54 | document.cookie = name + '=;domain=' + app_rootDomain + ';expires=' + date.toGMTString() + ';path=/'; 55 | } 56 | -------------------------------------------------------------------------------- /GGWkCookie/Classes/GGWkBundelManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // GGWkBundelManager.m 3 | // GGWkCookie 4 | // 5 | // Created by GarrettGao on 2018/9/14. 6 | // 7 | 8 | #import "GGWkBundelManager.h" 9 | 10 | #define GG_BUNDLE_FRAMEWORK_NAME_WK @"Frameworks/GGWkCookie.framework/GGWkCookie.bundle" 11 | #define GG_BUNDLE_LIB_NAME_WK @"GGWkCookie.bundle" 12 | 13 | @implementation GGWkBundelManager 14 | 15 | /** 16 | 读取本地js文件 17 | 18 | @param name 文件名称 19 | @param type 文件类型 20 | @return 返回js代码 21 | */ 22 | + (NSString *)loadJsCodeWithFileName:(NSString *)name withType:(NSString *)type { 23 | 24 | NSString *filePath = [[self mainBundleWithPath:GG_BUNDLE_FRAMEWORK_NAME_WK] pathForResource:name ofType:type]; 25 | NSString *jsCode = [NSString stringWithContentsOfFile:filePath 26 | encoding:NSUTF8StringEncoding 27 | error:nil]; 28 | if (!jsCode) { 29 | filePath = [[self mainBundleWithPath:GG_BUNDLE_LIB_NAME_WK] pathForResource:name ofType:type]; 30 | jsCode = [NSString stringWithContentsOfFile:filePath 31 | encoding:NSUTF8StringEncoding 32 | error:nil]; 33 | } 34 | return jsCode; 35 | } 36 | 37 | /// 当前组件的Bundle 38 | + (NSBundle *)mainBundleWithPath:(NSString *)path { 39 | NSString *bundelPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: path]; 40 | return [NSBundle bundleWithPath: bundelPath]; 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /GGWkCookie/Classes/WKWebView+Swizzling.m: -------------------------------------------------------------------------------- 1 | // 2 | // WKWebView+Swizzling.m 3 | // GGWkCookie 4 | // 5 | // Created by GarrettGao on 2018/9/14. 6 | // 7 | 8 | #import "WKWebView+Swizzling.h" 9 | #import "WKWebView+Attribute.h" 10 | #import 11 | 12 | @implementation WKWebView (Swizzling) 13 | 14 | + (void)load { 15 | 16 | // 交换系统的 reload方法 处理请求头中的cookie 17 | Method o_mt_reload = class_getInstanceMethod([self class], @selector(loadRequest:)); 18 | Method n_mt_reload = class_getInstanceMethod([self class], @selector(e_loadRequest:)); 19 | method_exchangeImplementations(o_mt_reload, n_mt_reload); 20 | } 21 | 22 | /// 拦截 系统的 loadRequest方法,插入我们自定义的cookie到请求头中 23 | - (nullable WKNavigation *)e_loadRequest:(NSURLRequest *)request { 24 | 25 | NSMutableURLRequest *newRequeset = [request mutableCopy]; 26 | 27 | if([self.cookieKeyValue isKindOfClass:[NSDictionary class]] || 28 | [self.cookieKeyValue isKindOfClass:[NSMutableDictionary class]]){ 29 | 30 | NSString *cookie = [request valueForHTTPHeaderField:@"Cookie"]; 31 | if (!cookie || [cookie isKindOfClass:[NSNull class]]) { 32 | cookie = @""; 33 | } 34 | for (NSString *key in self.cookieKeyValue.allKeys) { 35 | NSString *keyValue = [NSString stringWithFormat:@"%@=%@;",key,[self.cookieKeyValue objectForKey:key]]; 36 | cookie = [cookie stringByAppendingString:keyValue]; 37 | } 38 | [newRequeset setValue:cookie forHTTPHeaderField:@"Cookie"]; 39 | } 40 | 41 | return [self e_loadRequest:newRequeset]; 42 | } 43 | @end 44 | -------------------------------------------------------------------------------- /Example/GGWkCookie/GGWkCookie-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | UISupportedInterfaceOrientations~ipad 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationPortraitUpsideDown 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Example/GGWkCookie/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /Example/GGWkCookie/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GGWkCookie 2 | 3 | [![CI Status](https://img.shields.io/travis/gaoguohao/GGWkCookie.svg?style=flat)](https://travis-ci.org/gaoguohao/GGWkCookie) 4 | [![Version](https://img.shields.io/cocoapods/v/GGWkCookie.svg?style=flat)](https://cocoapods.org/pods/GGWkCookie) 5 | [![License](https://img.shields.io/cocoapods/l/GGWkCookie.svg?style=flat)](https://cocoapods.org/pods/GGWkCookie) 6 | [![Platform](https://img.shields.io/cocoapods/p/GGWkCookie.svg?style=flat)](https://cocoapods.org/pods/GGWkCookie) 7 | 8 | ## Example 9 | 10 | To run the example project, clone the repo, and run `pod install` from the Example directory first. 11 | 12 | ## Requirements 13 | WKWebView管理cookie是很麻烦事,经常出现 App自定义cookie的值丢失 或 更新不及时 的情况。 14 | 通过长期踩坑,总结出WKWebview管理cookie的一种方案。 15 | 16 | 原理: WKWebview支持的插入脚本的方式,在每次页面渲染前,通过插入的Js脚本检测Cookie是否存在,如不存在,将cookie重新种入的思路。 17 | 18 | 注意:因为考虑避免子域名和根域名cookie重复出现,该方法所有的Cookie值将种在 根域名上。 19 | 20 | ## Installation 21 | 22 | GGWkCookie is available through [CocoaPods](https://cocoapods.org). To install 23 | it, simply add the following line to your Podfile: 24 | 25 | ```ruby 26 | pod 'GGWkCookie' 27 | ``` 28 | 29 | ## Use 30 | 1.导入 引用头文件: 31 | ```objc 32 | #import "GGWkCookie.h" 33 | ``` 34 | 或 35 | ```objc 36 | #import 37 | ``` 38 | 39 | 2.实现 `````` 协议 ,开启cookie开关 ```startCustomCookie()```: 40 | ```objc 41 | // 设置cookie代理 42 | webView.cookieDelegate = self; 43 | 44 | // 开启自定义cookie(在loadRequest前开启) 45 | [webView startCustomCookie]; 46 | 47 | /// 代理方法中设置 app自定义的cookie 48 | - (NSDictionary *)webviewSetAppCookieKeyAndValue { 49 | 50 | return @{ 51 | @"cookieName":@"value", 52 | }; 53 | } 54 | ``` 55 | 56 | 3.如果代理中的cookie发生改变,调用 ```reloadCookie()``` 更新cookie, 57 | ```- (NSDictionary *)webviewSetAppCookieKeyAndValue```代理方法将获取最新的cookie值。 58 | 59 | 60 | 总结: 61 | 所以,我们只需要维护好代理方法```- (NSDictionary *)webviewSetAppCookieKeyAndValue```的返回值, 62 | 在需要更新的时调用 ```reloadCookie()``` 方法即可。 63 | 64 | 博客地址:https://www.jianshu.com/p/43a1e87a91d5 65 | 66 | ## Author 67 | 68 | gaoguohao, guohaoggh@163.com 69 | 70 | ## License 71 | 72 | GGWkCookie is available under the MIT license. See the LICENSE file for more info. 73 | -------------------------------------------------------------------------------- /Example/GGWkCookie/GGAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // GGAppDelegate.m 3 | // GGWkCookie 4 | // 5 | // Created by gaoguohao on 09/14/2018. 6 | // Copyright (c) 2018 gaoguohao. All rights reserved. 7 | // 8 | 9 | #import "GGAppDelegate.h" 10 | 11 | 12 | @implementation GGAppDelegate 13 | 14 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 15 | { 16 | // Override point for customization after application launch. 17 | return YES; 18 | } 19 | 20 | - (void)applicationWillResignActive:(UIApplication *)application 21 | { 22 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 23 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 24 | } 25 | 26 | - (void)applicationDidEnterBackground:(UIApplication *)application 27 | { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | - (void)applicationWillEnterForeground:(UIApplication *)application 33 | { 34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application 38 | { 39 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 40 | } 41 | 42 | - (void)applicationWillTerminate:(UIApplication *)application 43 | { 44 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /Example/GGWkCookie/Class/Controller/GGCookiesViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // GGCookiesViewController.m 3 | // GGWkCookie_Example 4 | // 5 | // Created by GarrettGao on 2018/9/17. 6 | // Copyright © 2018年 gaoguohao. All rights reserved. 7 | // 8 | 9 | #import "GGCookiesViewController.h" 10 | #import "GGCookieCell.h" 11 | #import "GGAddCookieCell.h" 12 | 13 | 14 | @interface GGCookiesViewController () { 15 | 16 | __weak IBOutlet UITableView *_tableView; 17 | } 18 | 19 | @end 20 | 21 | @implementation GGCookiesViewController 22 | 23 | - (void)viewDidLoad { 24 | self.title = @"App自定义Cookie"; 25 | [super viewDidLoad]; 26 | } 27 | 28 | #pragma mark - Delegate 29 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 30 | return self.cookieDic.allKeys.count + 1; 31 | } 32 | 33 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 34 | 35 | if (indexPath.row == _cookieDic.allKeys.count) { 36 | GGAddCookieCell * cell = [tableView dequeueReusableCellWithIdentifier:@"GGAddCookieCell"]; 37 | if (!cell) { cell = [GGAddCookieCell loadXib]; } 38 | cell.delegate = self; 39 | return cell; 40 | } 41 | 42 | NSString *cookieName = [_cookieDic.allKeys objectAtIndex:indexPath.row]; 43 | NSString *cookieValue = [_cookieDic objectForKey:cookieName]; 44 | NSString *content = [NSString stringWithFormat:@"%ld.\n name = %@\n value = %@", 45 | (long)indexPath.row + 1,cookieName,cookieValue]; 46 | 47 | GGCookieCell * cell = [tableView dequeueReusableCellWithIdentifier:@"GGCookieCell"]; 48 | if (!cell) { cell = [GGCookieCell loadXib]; } 49 | cell.content = content; 50 | return cell; 51 | } 52 | 53 | - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{ 54 | 55 | return UITableViewCellEditingStyleDelete; 56 | 57 | } 58 | 59 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{ 60 | 61 | if (editingStyle == UITableViewCellEditingStyleDelete) { 62 | NSString *key = [_cookieDic.allKeys objectAtIndex:indexPath.row]; 63 | [_cookieDic removeObjectForKey:key]; 64 | } 65 | [tableView reloadData]; 66 | 67 | } 68 | 69 | #pragma mark - GGAddCookieCellDelegate 70 | - (void)addCookieWithName:(NSString *)name withValue:(NSString *)value { 71 | [_cookieDic setValue:value forKey:name]; 72 | [_tableView reloadData]; 73 | } 74 | 75 | - (void)didReceiveMemoryWarning { 76 | [super didReceiveMemoryWarning]; 77 | } 78 | 79 | @end 80 | -------------------------------------------------------------------------------- /Example/GGWkCookie/Class/Controller/GGCookiesViewController.xib: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /Example/GGWkCookie/Class/View/GGCookieCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Example/GGWkCookie/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /Example/GGWkCookie/Class/Controller/GGViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // GGViewController.m 3 | // GGWkCookie 4 | // 5 | // Created by gaoguohao on 09/14/2018. 6 | // Copyright (c) 2018 gaoguohao. All rights reserved. 7 | // 8 | 9 | #import "GGViewController.h" 10 | #import "GGCookiesViewController.h" 11 | //#import 12 | #import "GGWkCookie.h" 13 | 14 | 15 | @interface GGViewController () 16 | { 17 | NSMutableDictionary *_cookieDic; 18 | } 19 | @end 20 | 21 | @implementation GGViewController 22 | 23 | - (void)viewDidLoad 24 | { 25 | [super viewDidLoad]; 26 | // Do any additional setup after loading the view, typically from a nib. 27 | self.title = @"Cookie自定义"; 28 | 29 | 30 | // 设置一个测试cookie的字典 31 | _cookieDic = [NSMutableDictionary dictionaryWithDictionary:@{ 32 | @"11111": @"GarrettGao", 33 | @"22222": @"GGWkCookie", 34 | }]; 35 | 36 | [self initWebView]; 37 | } 38 | 39 | 40 | - (void)initWebView { 41 | 42 | WKWebViewConfiguration* configuration = [[WKWebViewConfiguration alloc] init]; 43 | configuration.userContentController = [WKUserContentController new]; 44 | 45 | WKPreferences* preferences = [WKPreferences new]; 46 | preferences.javaScriptCanOpenWindowsAutomatically = YES; 47 | configuration.preferences = preferences; 48 | 49 | WKWebView* webView = [[WKWebView alloc] initWithFrame:CGRectZero 50 | configuration:configuration]; 51 | webView.tag = 101; 52 | webView.UIDelegate = self; 53 | webView.navigationDelegate = self; 54 | webView.cookieDelegate = self; //设置cookie代理 55 | 56 | [self.view addSubview:webView]; 57 | 58 | webView.translatesAutoresizingMaskIntoConstraints = NO; 59 | [webView.leftAnchor constraintEqualToAnchor:self.view.leftAnchor].active = YES; 60 | [webView.topAnchor constraintEqualToAnchor:self.view.topAnchor].active = YES; 61 | [webView.rightAnchor constraintEqualToAnchor:self.view.rightAnchor].active = YES; 62 | [webView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor].active = YES; 63 | 64 | // 开启自定义cookie 65 | [webView startCustomCookie]; 66 | 67 | [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.baidu.com"]]]; 68 | } 69 | 70 | #pragma mark - WKNavigationDelegate 71 | 72 | - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { 73 | self.title = @"加载中..."; 74 | } 75 | 76 | - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation { 77 | self.title = @""; 78 | [webView evaluateJavaScript:@"document.cookie" completionHandler:^(NSString *result, NSError * _Nullable error) { 79 | NSLog(@"网页中的cookie为:\n%@",[result componentsSeparatedByString:@"; "]); 80 | }]; 81 | } 82 | 83 | - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { 84 | } 85 | 86 | - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error { 87 | self.title = @""; 88 | NSLog(@"%@", error); 89 | } 90 | 91 | #pragma mark - GGWkWebViewDelegate 92 | /// 代理方法中设置 app自定义的cookie 93 | - (NSDictionary *)webviewSetAppCookieKeyAndValue { 94 | return _cookieDic; 95 | } 96 | 97 | #pragma mark - OnClicked 98 | 99 | // 刷新 100 | - (IBAction)onReloadClicked:(UIBarButtonItem *)sender { 101 | WKWebView *webview = [self.view viewWithTag:101]; 102 | [webview reloadCookie]; 103 | [webview reload]; 104 | } 105 | 106 | // 操作 107 | - (IBAction)onMakeCookieClicked:(UIBarButtonItem *)sender { 108 | 109 | GGCookiesViewController *viewController = [[GGCookiesViewController alloc] init]; 110 | viewController.cookieDic = _cookieDic; 111 | [self.navigationController pushViewController:viewController animated:YES]; 112 | } 113 | - (void)didReceiveMemoryWarning 114 | { 115 | [super didReceiveMemoryWarning]; 116 | } 117 | 118 | @end 119 | -------------------------------------------------------------------------------- /Example/GGWkCookie.xcodeproj/xcshareddata/xcschemes/GGWkCookie-Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /GGWkCookie/Classes/WKWebView+GGCookie.m: -------------------------------------------------------------------------------- 1 | // 2 | // WKWebView+GGCookie.m 3 | // GGWkCookie 4 | // 5 | // Created by GarrettGao on 2018/9/14. 6 | // 7 | 8 | #import "WKWebView+GGCookie.h" 9 | #import "GGWkBundelManager.h" 10 | #import "WKWebView+Attribute.h" 11 | 12 | @implementation WKWebView (GGCookie) 13 | 14 | #define kJhuCookieJsCodeTag @"// 这是一个代码片段标示,用于删除某个WKUserScript代码片段的标记" 15 | 16 | - (void)startCustomCookie { 17 | [self addAppJsCode]; 18 | [self reloadCookie]; 19 | } 20 | 21 | /** 22 | 设置 App 基本支持的JS代码 23 | */ 24 | - (void)addAppJsCode { 25 | 26 | NSString *jsCode = [GGWkBundelManager loadJsCodeWithFileName:@"GGCookie" withType:@"js"]; 27 | if (jsCode) { 28 | WKUserScript *cookieInScript = [[WKUserScript alloc] 29 | initWithSource:jsCode 30 | injectionTime:WKUserScriptInjectionTimeAtDocumentStart 31 | forMainFrameOnly:NO]; 32 | [self.configuration.userContentController addUserScript:cookieInScript]; 33 | } 34 | } 35 | 36 | /** 37 | 刷新设置cookie 38 | */ 39 | - (void)reloadCookie { 40 | 41 | // 删除所有自定义cookie 42 | [self removeAllTagCookie]; 43 | 44 | // 代理获取最新的cookie值 45 | if (self.cookieDelegate && [self.cookieDelegate respondsToSelector:@selector(webviewSetAppCookieKeyAndValue)]) { 46 | self.cookieKeyValue = [self.cookieDelegate webviewSetAppCookieKeyAndValue]; 47 | } 48 | 49 | //重新添加cookie 50 | if (self.cookieKeyValue) { 51 | for (NSString *name in self.cookieKeyValue.allKeys) { 52 | [self addCookieWithKey:name withValue:[self.cookieKeyValue objectForKey:name]]; 53 | } 54 | } 55 | } 56 | 57 | 58 | /** 59 | 添加某个cookie 60 | */ 61 | - (void)addCookieWithKey:(NSString *)key withValue:(NSString *)value { 62 | 63 | NSString *jsCode = [NSString stringWithFormat:@"app_setCookie('%@','%@')",key,value]; 64 | [self evaluateJavaScript:jsCode completionHandler:nil]; 65 | 66 | // 代码片段标签 67 | NSString *tag = [self getCustomJsCodeTagWithKey:key]; 68 | 69 | // 先删除原来的代码片段 70 | [self deleteUserSciptWithTag:tag]; 71 | 72 | // 再添加新的 73 | [self addUserScriptWithJsCode:jsCode WithTag:tag]; 74 | } 75 | 76 | /** 77 | 删除某个cookie 78 | */ 79 | - (void)removeCookieWithKey:(NSString *)key { 80 | 81 | // 删除浏览器的某个cookie 82 | NSString *jsCode = [NSString stringWithFormat:@"app_deleteCookie('%@')",key]; 83 | [self evaluateJavaScript:jsCode completionHandler:nil]; 84 | 85 | // 删除添加cookie的脚本代码 86 | NSString *tag = [self getCustomJsCodeTagWithKey:key]; 87 | [self deleteUserSciptWithTag:tag]; 88 | } 89 | 90 | /** 91 | 删除所有的标签(app自定义)cookie 92 | */ 93 | - (void)removeAllTagCookie { 94 | 95 | // 删除所有的cookie 96 | if (self.cookieKeyValue) { 97 | for (NSString *key in self.cookieKeyValue.allKeys) { 98 | NSString *jsCode = [NSString stringWithFormat:@"app_deleteCookie('%@')",key]; 99 | [self evaluateJavaScript:jsCode completionHandler:nil]; 100 | } 101 | } 102 | 103 | // 删除所有的本地自定义js 设置cookie的脚本 104 | [self deleteUserSciptWithTag:[self getCustomJsCodeTagWithKey:nil]]; 105 | 106 | // 属性置空 107 | self.cookieKeyValue = @{}; 108 | } 109 | 110 | 111 | /** 112 | 添加某个代码片段 113 | 114 | @param jsCode 插入的js代码 115 | @param tag tag 片段标示 116 | */ 117 | - (void)addUserScriptWithJsCode:(NSString *)jsCode WithTag:(NSString *)tag { 118 | 119 | if (jsCode) { 120 | WKUserScript *cookieInScript = [[WKUserScript alloc] initWithSource:[NSString stringWithFormat:@"%@ \n%@",jsCode,tag] 121 | injectionTime:WKUserScriptInjectionTimeAtDocumentStart 122 | forMainFrameOnly:NO]; 123 | [self.configuration.userContentController addUserScript:cookieInScript]; 124 | } 125 | } 126 | 127 | /** 128 | 删除某个代码片段 129 | 130 | @param tag 片段标示, (敲黑板)注意:当 tag == 宏定义 kJhuCookieJsCodeTag时,将删除所有的自定义cookie 131 | */ 132 | - (void)deleteUserSciptWithTag:(NSString *)tag { 133 | 134 | if (tag) { 135 | WKUserContentController *userContentController = self.configuration.userContentController; 136 | NSMutableArray *array = [userContentController.userScripts mutableCopy]; 137 | int i = 0; 138 | BOOL isHave = NO; 139 | for (WKUserScript* wkUScript in userContentController.userScripts) { 140 | if ([wkUScript.source containsString:tag]) { 141 | [array removeObjectAtIndex:i]; 142 | isHave = YES; 143 | continue; 144 | } 145 | i ++; 146 | } 147 | 148 | // 如果原来的代码片段中存在 149 | if (isHave) { 150 | ///没法修改数组 只能移除全部 再重新添加 151 | [userContentController removeAllUserScripts]; 152 | for (WKUserScript* wkUScript in array) { 153 | [userContentController addUserScript:wkUScript]; 154 | } 155 | } 156 | } 157 | } 158 | 159 | /** 160 | 自定义js脚本片段的一个标示,用于删除某段代码片段 161 | 162 | @param key cookie name 163 | @return 拼接后的代码片段标示 164 | */ 165 | - (NSString *)getCustomJsCodeTagWithKey:(NSString *)key { 166 | if (!key) key = @""; 167 | return [kJhuCookieJsCodeTag stringByAppendingString:key]; 168 | } 169 | 170 | @end 171 | -------------------------------------------------------------------------------- /Example/GGWkCookie/Class/View/GGAddCookieCell.xib: -------------------------------------------------------------------------------- 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 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /Example/GGWkCookie.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; }; 11 | 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58F195388D20070C39A /* CoreGraphics.framework */; }; 12 | 6003F592195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; }; 13 | 6003F598195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F596195388D20070C39A /* InfoPlist.strings */; }; 14 | 6003F59A195388D20070C39A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F599195388D20070C39A /* main.m */; }; 15 | 6003F59E195388D20070C39A /* GGAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F59D195388D20070C39A /* GGAppDelegate.m */; }; 16 | 6003F5A9195388D20070C39A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5A8195388D20070C39A /* Images.xcassets */; }; 17 | 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F5AF195388D20070C39A /* XCTest.framework */; }; 18 | 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; }; 19 | 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; }; 20 | 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5B8195388D20070C39A /* InfoPlist.strings */; }; 21 | 6003F5BC195388D20070C39A /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5BB195388D20070C39A /* Tests.m */; }; 22 | 71719F9F1E33DC2100824A3D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */; }; 23 | 797A39A1CCE020DE5672855B /* Pods_GGWkCookie_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20485FF61662D5F444DE1A22 /* Pods_GGWkCookie_Example.framework */; }; 24 | 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; }; 25 | 99811388214F762400B9D176 /* GGCookiesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9981137F214F762400B9D176 /* GGCookiesViewController.m */; }; 26 | 99811389214F762400B9D176 /* GGViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 99811380214F762400B9D176 /* GGViewController.m */; }; 27 | 9981138A214F762400B9D176 /* GGCookiesViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 99811381214F762400B9D176 /* GGCookiesViewController.xib */; }; 28 | 9981138B214F762400B9D176 /* GGCookieCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 99811386214F762400B9D176 /* GGCookieCell.xib */; }; 29 | 9981138C214F762400B9D176 /* GGCookieCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 99811387214F762400B9D176 /* GGCookieCell.m */; }; 30 | 99811390214F764100B9D176 /* GGAddCookieCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 9981138E214F764100B9D176 /* GGAddCookieCell.m */; }; 31 | 99811391214F764100B9D176 /* GGAddCookieCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9981138F214F764100B9D176 /* GGAddCookieCell.xib */; }; 32 | EE6AAB1B1D1F98AAC0C8D95A /* Pods_GGWkCookie_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2A500B20CC5FAD09AE8E02A /* Pods_GGWkCookie_Tests.framework */; }; 33 | /* End PBXBuildFile section */ 34 | 35 | /* Begin PBXContainerItemProxy section */ 36 | 6003F5B3195388D20070C39A /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = 6003F582195388D10070C39A /* Project object */; 39 | proxyType = 1; 40 | remoteGlobalIDString = 6003F589195388D20070C39A; 41 | remoteInfo = GGWkCookie; 42 | }; 43 | /* End PBXContainerItemProxy section */ 44 | 45 | /* Begin PBXFileReference section */ 46 | 18174485BFD271371A951591 /* GGWkCookie.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = GGWkCookie.podspec; path = ../GGWkCookie.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 47 | 20485FF61662D5F444DE1A22 /* Pods_GGWkCookie_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GGWkCookie_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 48 | 515AF27DFFDEA809C4446D85 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 49 | 6003F58A195388D20070C39A /* GGWkCookie_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GGWkCookie_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | 6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 51 | 6003F58F195388D20070C39A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 52 | 6003F591195388D20070C39A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 53 | 6003F595195388D20070C39A /* GGWkCookie-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GGWkCookie-Info.plist"; sourceTree = ""; }; 54 | 6003F597195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 55 | 6003F599195388D20070C39A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 56 | 6003F59B195388D20070C39A /* GGWkCookie-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "GGWkCookie-Prefix.pch"; sourceTree = ""; }; 57 | 6003F59C195388D20070C39A /* GGAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GGAppDelegate.h; sourceTree = ""; }; 58 | 6003F59D195388D20070C39A /* GGAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GGAppDelegate.m; sourceTree = ""; }; 59 | 6003F5A8195388D20070C39A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 60 | 6003F5AE195388D20070C39A /* GGWkCookie_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GGWkCookie_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 61 | 6003F5AF195388D20070C39A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 62 | 6003F5B7195388D20070C39A /* Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Tests-Info.plist"; sourceTree = ""; }; 63 | 6003F5B9195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 64 | 6003F5BB195388D20070C39A /* Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Tests.m; sourceTree = ""; }; 65 | 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = ""; }; 66 | 63D7043306CF0355F6256875 /* Pods-GGWkCookie_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GGWkCookie_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-GGWkCookie_Tests/Pods-GGWkCookie_Tests.debug.xcconfig"; sourceTree = ""; }; 67 | 71719F9E1E33DC2100824A3D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 68 | 78E060A4ACAAC8F8D5C5EF23 /* Pods-GGWkCookie_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GGWkCookie_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-GGWkCookie_Example/Pods-GGWkCookie_Example.release.xcconfig"; sourceTree = ""; }; 69 | 8083B02F655BE7B16C9D6DD3 /* Pods-GGWkCookie_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GGWkCookie_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-GGWkCookie_Tests/Pods-GGWkCookie_Tests.release.xcconfig"; sourceTree = ""; }; 70 | 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Main.storyboard; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 71 | 913505BC7586A38C7ED964ED /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 72 | 9981137F214F762400B9D176 /* GGCookiesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GGCookiesViewController.m; sourceTree = ""; }; 73 | 99811380214F762400B9D176 /* GGViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GGViewController.m; sourceTree = ""; }; 74 | 99811381214F762400B9D176 /* GGCookiesViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GGCookiesViewController.xib; sourceTree = ""; }; 75 | 99811382214F762400B9D176 /* GGCookiesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GGCookiesViewController.h; sourceTree = ""; }; 76 | 99811383214F762400B9D176 /* GGViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GGViewController.h; sourceTree = ""; }; 77 | 99811385214F762400B9D176 /* GGCookieCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GGCookieCell.h; sourceTree = ""; }; 78 | 99811386214F762400B9D176 /* GGCookieCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GGCookieCell.xib; sourceTree = ""; }; 79 | 99811387214F762400B9D176 /* GGCookieCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GGCookieCell.m; sourceTree = ""; }; 80 | 9981138D214F764100B9D176 /* GGAddCookieCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GGAddCookieCell.h; sourceTree = ""; }; 81 | 9981138E214F764100B9D176 /* GGAddCookieCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GGAddCookieCell.m; sourceTree = ""; }; 82 | 9981138F214F764100B9D176 /* GGAddCookieCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GGAddCookieCell.xib; sourceTree = ""; }; 83 | D2A500B20CC5FAD09AE8E02A /* Pods_GGWkCookie_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GGWkCookie_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 84 | F13A652655D60513E74B3B26 /* Pods-GGWkCookie_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GGWkCookie_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-GGWkCookie_Example/Pods-GGWkCookie_Example.debug.xcconfig"; sourceTree = ""; }; 85 | /* End PBXFileReference section */ 86 | 87 | /* Begin PBXFrameworksBuildPhase section */ 88 | 6003F587195388D20070C39A /* Frameworks */ = { 89 | isa = PBXFrameworksBuildPhase; 90 | buildActionMask = 2147483647; 91 | files = ( 92 | 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */, 93 | 6003F592195388D20070C39A /* UIKit.framework in Frameworks */, 94 | 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */, 95 | 797A39A1CCE020DE5672855B /* Pods_GGWkCookie_Example.framework in Frameworks */, 96 | ); 97 | runOnlyForDeploymentPostprocessing = 0; 98 | }; 99 | 6003F5AB195388D20070C39A /* Frameworks */ = { 100 | isa = PBXFrameworksBuildPhase; 101 | buildActionMask = 2147483647; 102 | files = ( 103 | 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */, 104 | 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */, 105 | 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */, 106 | EE6AAB1B1D1F98AAC0C8D95A /* Pods_GGWkCookie_Tests.framework in Frameworks */, 107 | ); 108 | runOnlyForDeploymentPostprocessing = 0; 109 | }; 110 | /* End PBXFrameworksBuildPhase section */ 111 | 112 | /* Begin PBXGroup section */ 113 | 6003F581195388D10070C39A = { 114 | isa = PBXGroup; 115 | children = ( 116 | 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */, 117 | 6003F593195388D20070C39A /* Example for GGWkCookie */, 118 | 6003F5B5195388D20070C39A /* Tests */, 119 | 6003F58C195388D20070C39A /* Frameworks */, 120 | 6003F58B195388D20070C39A /* Products */, 121 | 96BFD28CEAAC2079E1A655BB /* Pods */, 122 | ); 123 | sourceTree = ""; 124 | }; 125 | 6003F58B195388D20070C39A /* Products */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | 6003F58A195388D20070C39A /* GGWkCookie_Example.app */, 129 | 6003F5AE195388D20070C39A /* GGWkCookie_Tests.xctest */, 130 | ); 131 | name = Products; 132 | sourceTree = ""; 133 | }; 134 | 6003F58C195388D20070C39A /* Frameworks */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | 6003F58D195388D20070C39A /* Foundation.framework */, 138 | 6003F58F195388D20070C39A /* CoreGraphics.framework */, 139 | 6003F591195388D20070C39A /* UIKit.framework */, 140 | 6003F5AF195388D20070C39A /* XCTest.framework */, 141 | 20485FF61662D5F444DE1A22 /* Pods_GGWkCookie_Example.framework */, 142 | D2A500B20CC5FAD09AE8E02A /* Pods_GGWkCookie_Tests.framework */, 143 | ); 144 | name = Frameworks; 145 | sourceTree = ""; 146 | }; 147 | 6003F593195388D20070C39A /* Example for GGWkCookie */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | 6003F59C195388D20070C39A /* GGAppDelegate.h */, 151 | 6003F59D195388D20070C39A /* GGAppDelegate.m */, 152 | 9981137D214F762400B9D176 /* Class */, 153 | 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */, 154 | 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */, 155 | 6003F5A8195388D20070C39A /* Images.xcassets */, 156 | 6003F594195388D20070C39A /* Supporting Files */, 157 | ); 158 | name = "Example for GGWkCookie"; 159 | path = GGWkCookie; 160 | sourceTree = ""; 161 | }; 162 | 6003F594195388D20070C39A /* Supporting Files */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | 6003F595195388D20070C39A /* GGWkCookie-Info.plist */, 166 | 6003F596195388D20070C39A /* InfoPlist.strings */, 167 | 6003F599195388D20070C39A /* main.m */, 168 | 6003F59B195388D20070C39A /* GGWkCookie-Prefix.pch */, 169 | ); 170 | name = "Supporting Files"; 171 | sourceTree = ""; 172 | }; 173 | 6003F5B5195388D20070C39A /* Tests */ = { 174 | isa = PBXGroup; 175 | children = ( 176 | 6003F5BB195388D20070C39A /* Tests.m */, 177 | 6003F5B6195388D20070C39A /* Supporting Files */, 178 | ); 179 | path = Tests; 180 | sourceTree = ""; 181 | }; 182 | 6003F5B6195388D20070C39A /* Supporting Files */ = { 183 | isa = PBXGroup; 184 | children = ( 185 | 6003F5B7195388D20070C39A /* Tests-Info.plist */, 186 | 6003F5B8195388D20070C39A /* InfoPlist.strings */, 187 | 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */, 188 | ); 189 | name = "Supporting Files"; 190 | sourceTree = ""; 191 | }; 192 | 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */ = { 193 | isa = PBXGroup; 194 | children = ( 195 | 18174485BFD271371A951591 /* GGWkCookie.podspec */, 196 | 913505BC7586A38C7ED964ED /* README.md */, 197 | 515AF27DFFDEA809C4446D85 /* LICENSE */, 198 | ); 199 | name = "Podspec Metadata"; 200 | sourceTree = ""; 201 | }; 202 | 96BFD28CEAAC2079E1A655BB /* Pods */ = { 203 | isa = PBXGroup; 204 | children = ( 205 | F13A652655D60513E74B3B26 /* Pods-GGWkCookie_Example.debug.xcconfig */, 206 | 78E060A4ACAAC8F8D5C5EF23 /* Pods-GGWkCookie_Example.release.xcconfig */, 207 | 63D7043306CF0355F6256875 /* Pods-GGWkCookie_Tests.debug.xcconfig */, 208 | 8083B02F655BE7B16C9D6DD3 /* Pods-GGWkCookie_Tests.release.xcconfig */, 209 | ); 210 | name = Pods; 211 | sourceTree = ""; 212 | }; 213 | 9981137D214F762400B9D176 /* Class */ = { 214 | isa = PBXGroup; 215 | children = ( 216 | 9981137E214F762400B9D176 /* Controller */, 217 | 99811384214F762400B9D176 /* View */, 218 | ); 219 | path = Class; 220 | sourceTree = ""; 221 | }; 222 | 9981137E214F762400B9D176 /* Controller */ = { 223 | isa = PBXGroup; 224 | children = ( 225 | 99811383214F762400B9D176 /* GGViewController.h */, 226 | 99811380214F762400B9D176 /* GGViewController.m */, 227 | 99811382214F762400B9D176 /* GGCookiesViewController.h */, 228 | 9981137F214F762400B9D176 /* GGCookiesViewController.m */, 229 | 99811381214F762400B9D176 /* GGCookiesViewController.xib */, 230 | ); 231 | path = Controller; 232 | sourceTree = ""; 233 | }; 234 | 99811384214F762400B9D176 /* View */ = { 235 | isa = PBXGroup; 236 | children = ( 237 | 99811385214F762400B9D176 /* GGCookieCell.h */, 238 | 99811387214F762400B9D176 /* GGCookieCell.m */, 239 | 99811386214F762400B9D176 /* GGCookieCell.xib */, 240 | 9981138D214F764100B9D176 /* GGAddCookieCell.h */, 241 | 9981138E214F764100B9D176 /* GGAddCookieCell.m */, 242 | 9981138F214F764100B9D176 /* GGAddCookieCell.xib */, 243 | ); 244 | path = View; 245 | sourceTree = ""; 246 | }; 247 | /* End PBXGroup section */ 248 | 249 | /* Begin PBXNativeTarget section */ 250 | 6003F589195388D20070C39A /* GGWkCookie_Example */ = { 251 | isa = PBXNativeTarget; 252 | buildConfigurationList = 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "GGWkCookie_Example" */; 253 | buildPhases = ( 254 | EEF2F82C8CC5E6FDC9F740B2 /* [CP] Check Pods Manifest.lock */, 255 | 6003F586195388D20070C39A /* Sources */, 256 | 6003F587195388D20070C39A /* Frameworks */, 257 | 6003F588195388D20070C39A /* Resources */, 258 | 83AFE5112EB5303901F9EE97 /* [CP] Embed Pods Frameworks */, 259 | ); 260 | buildRules = ( 261 | ); 262 | dependencies = ( 263 | ); 264 | name = GGWkCookie_Example; 265 | productName = GGWkCookie; 266 | productReference = 6003F58A195388D20070C39A /* GGWkCookie_Example.app */; 267 | productType = "com.apple.product-type.application"; 268 | }; 269 | 6003F5AD195388D20070C39A /* GGWkCookie_Tests */ = { 270 | isa = PBXNativeTarget; 271 | buildConfigurationList = 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "GGWkCookie_Tests" */; 272 | buildPhases = ( 273 | E0B5090ACCAB857A0F2E07C6 /* [CP] Check Pods Manifest.lock */, 274 | 6003F5AA195388D20070C39A /* Sources */, 275 | 6003F5AB195388D20070C39A /* Frameworks */, 276 | 6003F5AC195388D20070C39A /* Resources */, 277 | ); 278 | buildRules = ( 279 | ); 280 | dependencies = ( 281 | 6003F5B4195388D20070C39A /* PBXTargetDependency */, 282 | ); 283 | name = GGWkCookie_Tests; 284 | productName = GGWkCookieTests; 285 | productReference = 6003F5AE195388D20070C39A /* GGWkCookie_Tests.xctest */; 286 | productType = "com.apple.product-type.bundle.unit-test"; 287 | }; 288 | /* End PBXNativeTarget section */ 289 | 290 | /* Begin PBXProject section */ 291 | 6003F582195388D10070C39A /* Project object */ = { 292 | isa = PBXProject; 293 | attributes = { 294 | CLASSPREFIX = GG; 295 | LastUpgradeCheck = 0720; 296 | ORGANIZATIONNAME = gaoguohao; 297 | TargetAttributes = { 298 | 6003F5AD195388D20070C39A = { 299 | TestTargetID = 6003F589195388D20070C39A; 300 | }; 301 | }; 302 | }; 303 | buildConfigurationList = 6003F585195388D10070C39A /* Build configuration list for PBXProject "GGWkCookie" */; 304 | compatibilityVersion = "Xcode 3.2"; 305 | developmentRegion = English; 306 | hasScannedForEncodings = 0; 307 | knownRegions = ( 308 | English, 309 | en, 310 | Base, 311 | ); 312 | mainGroup = 6003F581195388D10070C39A; 313 | productRefGroup = 6003F58B195388D20070C39A /* Products */; 314 | projectDirPath = ""; 315 | projectRoot = ""; 316 | targets = ( 317 | 6003F589195388D20070C39A /* GGWkCookie_Example */, 318 | 6003F5AD195388D20070C39A /* GGWkCookie_Tests */, 319 | ); 320 | }; 321 | /* End PBXProject section */ 322 | 323 | /* Begin PBXResourcesBuildPhase section */ 324 | 6003F588195388D20070C39A /* Resources */ = { 325 | isa = PBXResourcesBuildPhase; 326 | buildActionMask = 2147483647; 327 | files = ( 328 | 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */, 329 | 71719F9F1E33DC2100824A3D /* LaunchScreen.storyboard in Resources */, 330 | 9981138A214F762400B9D176 /* GGCookiesViewController.xib in Resources */, 331 | 9981138B214F762400B9D176 /* GGCookieCell.xib in Resources */, 332 | 6003F5A9195388D20070C39A /* Images.xcassets in Resources */, 333 | 99811391214F764100B9D176 /* GGAddCookieCell.xib in Resources */, 334 | 6003F598195388D20070C39A /* InfoPlist.strings in Resources */, 335 | ); 336 | runOnlyForDeploymentPostprocessing = 0; 337 | }; 338 | 6003F5AC195388D20070C39A /* Resources */ = { 339 | isa = PBXResourcesBuildPhase; 340 | buildActionMask = 2147483647; 341 | files = ( 342 | 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */, 343 | ); 344 | runOnlyForDeploymentPostprocessing = 0; 345 | }; 346 | /* End PBXResourcesBuildPhase section */ 347 | 348 | /* Begin PBXShellScriptBuildPhase section */ 349 | 83AFE5112EB5303901F9EE97 /* [CP] Embed Pods Frameworks */ = { 350 | isa = PBXShellScriptBuildPhase; 351 | buildActionMask = 2147483647; 352 | files = ( 353 | ); 354 | inputPaths = ( 355 | "${PODS_ROOT}/Target Support Files/Pods-GGWkCookie_Example/Pods-GGWkCookie_Example-frameworks.sh", 356 | "${BUILT_PRODUCTS_DIR}/GGWkCookie/GGWkCookie.framework", 357 | ); 358 | name = "[CP] Embed Pods Frameworks"; 359 | outputPaths = ( 360 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GGWkCookie.framework", 361 | ); 362 | runOnlyForDeploymentPostprocessing = 0; 363 | shellPath = /bin/sh; 364 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-GGWkCookie_Example/Pods-GGWkCookie_Example-frameworks.sh\"\n"; 365 | showEnvVarsInLog = 0; 366 | }; 367 | E0B5090ACCAB857A0F2E07C6 /* [CP] Check Pods Manifest.lock */ = { 368 | isa = PBXShellScriptBuildPhase; 369 | buildActionMask = 2147483647; 370 | files = ( 371 | ); 372 | inputPaths = ( 373 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 374 | "${PODS_ROOT}/Manifest.lock", 375 | ); 376 | name = "[CP] Check Pods Manifest.lock"; 377 | outputPaths = ( 378 | "$(DERIVED_FILE_DIR)/Pods-GGWkCookie_Tests-checkManifestLockResult.txt", 379 | ); 380 | runOnlyForDeploymentPostprocessing = 0; 381 | shellPath = /bin/sh; 382 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 383 | showEnvVarsInLog = 0; 384 | }; 385 | EEF2F82C8CC5E6FDC9F740B2 /* [CP] Check Pods Manifest.lock */ = { 386 | isa = PBXShellScriptBuildPhase; 387 | buildActionMask = 2147483647; 388 | files = ( 389 | ); 390 | inputPaths = ( 391 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 392 | "${PODS_ROOT}/Manifest.lock", 393 | ); 394 | name = "[CP] Check Pods Manifest.lock"; 395 | outputPaths = ( 396 | "$(DERIVED_FILE_DIR)/Pods-GGWkCookie_Example-checkManifestLockResult.txt", 397 | ); 398 | runOnlyForDeploymentPostprocessing = 0; 399 | shellPath = /bin/sh; 400 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 401 | showEnvVarsInLog = 0; 402 | }; 403 | /* End PBXShellScriptBuildPhase section */ 404 | 405 | /* Begin PBXSourcesBuildPhase section */ 406 | 6003F586195388D20070C39A /* Sources */ = { 407 | isa = PBXSourcesBuildPhase; 408 | buildActionMask = 2147483647; 409 | files = ( 410 | 6003F59E195388D20070C39A /* GGAppDelegate.m in Sources */, 411 | 9981138C214F762400B9D176 /* GGCookieCell.m in Sources */, 412 | 99811388214F762400B9D176 /* GGCookiesViewController.m in Sources */, 413 | 99811389214F762400B9D176 /* GGViewController.m in Sources */, 414 | 6003F59A195388D20070C39A /* main.m in Sources */, 415 | 99811390214F764100B9D176 /* GGAddCookieCell.m in Sources */, 416 | ); 417 | runOnlyForDeploymentPostprocessing = 0; 418 | }; 419 | 6003F5AA195388D20070C39A /* Sources */ = { 420 | isa = PBXSourcesBuildPhase; 421 | buildActionMask = 2147483647; 422 | files = ( 423 | 6003F5BC195388D20070C39A /* Tests.m in Sources */, 424 | ); 425 | runOnlyForDeploymentPostprocessing = 0; 426 | }; 427 | /* End PBXSourcesBuildPhase section */ 428 | 429 | /* Begin PBXTargetDependency section */ 430 | 6003F5B4195388D20070C39A /* PBXTargetDependency */ = { 431 | isa = PBXTargetDependency; 432 | target = 6003F589195388D20070C39A /* GGWkCookie_Example */; 433 | targetProxy = 6003F5B3195388D20070C39A /* PBXContainerItemProxy */; 434 | }; 435 | /* End PBXTargetDependency section */ 436 | 437 | /* Begin PBXVariantGroup section */ 438 | 6003F596195388D20070C39A /* InfoPlist.strings */ = { 439 | isa = PBXVariantGroup; 440 | children = ( 441 | 6003F597195388D20070C39A /* en */, 442 | ); 443 | name = InfoPlist.strings; 444 | sourceTree = ""; 445 | }; 446 | 6003F5B8195388D20070C39A /* InfoPlist.strings */ = { 447 | isa = PBXVariantGroup; 448 | children = ( 449 | 6003F5B9195388D20070C39A /* en */, 450 | ); 451 | name = InfoPlist.strings; 452 | sourceTree = ""; 453 | }; 454 | 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */ = { 455 | isa = PBXVariantGroup; 456 | children = ( 457 | 71719F9E1E33DC2100824A3D /* Base */, 458 | ); 459 | name = LaunchScreen.storyboard; 460 | sourceTree = ""; 461 | }; 462 | /* End PBXVariantGroup section */ 463 | 464 | /* Begin XCBuildConfiguration section */ 465 | 6003F5BD195388D20070C39A /* Debug */ = { 466 | isa = XCBuildConfiguration; 467 | buildSettings = { 468 | ALWAYS_SEARCH_USER_PATHS = NO; 469 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 470 | CLANG_CXX_LIBRARY = "libc++"; 471 | CLANG_ENABLE_MODULES = YES; 472 | CLANG_ENABLE_OBJC_ARC = YES; 473 | CLANG_WARN_BOOL_CONVERSION = YES; 474 | CLANG_WARN_CONSTANT_CONVERSION = YES; 475 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 476 | CLANG_WARN_EMPTY_BODY = YES; 477 | CLANG_WARN_ENUM_CONVERSION = YES; 478 | CLANG_WARN_INT_CONVERSION = YES; 479 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 480 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 481 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 482 | COPY_PHASE_STRIP = NO; 483 | ENABLE_TESTABILITY = YES; 484 | GCC_C_LANGUAGE_STANDARD = gnu99; 485 | GCC_DYNAMIC_NO_PIC = NO; 486 | GCC_OPTIMIZATION_LEVEL = 0; 487 | GCC_PREPROCESSOR_DEFINITIONS = ( 488 | "DEBUG=1", 489 | "$(inherited)", 490 | ); 491 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 492 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 493 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 494 | GCC_WARN_UNDECLARED_SELECTOR = YES; 495 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 496 | GCC_WARN_UNUSED_FUNCTION = YES; 497 | GCC_WARN_UNUSED_VARIABLE = YES; 498 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 499 | ONLY_ACTIVE_ARCH = YES; 500 | SDKROOT = iphoneos; 501 | TARGETED_DEVICE_FAMILY = "1,2"; 502 | }; 503 | name = Debug; 504 | }; 505 | 6003F5BE195388D20070C39A /* Release */ = { 506 | isa = XCBuildConfiguration; 507 | buildSettings = { 508 | ALWAYS_SEARCH_USER_PATHS = NO; 509 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 510 | CLANG_CXX_LIBRARY = "libc++"; 511 | CLANG_ENABLE_MODULES = YES; 512 | CLANG_ENABLE_OBJC_ARC = YES; 513 | CLANG_WARN_BOOL_CONVERSION = YES; 514 | CLANG_WARN_CONSTANT_CONVERSION = YES; 515 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 516 | CLANG_WARN_EMPTY_BODY = YES; 517 | CLANG_WARN_ENUM_CONVERSION = YES; 518 | CLANG_WARN_INT_CONVERSION = YES; 519 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 520 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 521 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 522 | COPY_PHASE_STRIP = YES; 523 | ENABLE_NS_ASSERTIONS = NO; 524 | GCC_C_LANGUAGE_STANDARD = gnu99; 525 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 526 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 527 | GCC_WARN_UNDECLARED_SELECTOR = YES; 528 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 529 | GCC_WARN_UNUSED_FUNCTION = YES; 530 | GCC_WARN_UNUSED_VARIABLE = YES; 531 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 532 | SDKROOT = iphoneos; 533 | TARGETED_DEVICE_FAMILY = "1,2"; 534 | VALIDATE_PRODUCT = YES; 535 | }; 536 | name = Release; 537 | }; 538 | 6003F5C0195388D20070C39A /* Debug */ = { 539 | isa = XCBuildConfiguration; 540 | baseConfigurationReference = F13A652655D60513E74B3B26 /* Pods-GGWkCookie_Example.debug.xcconfig */; 541 | buildSettings = { 542 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 543 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 544 | GCC_PREFIX_HEADER = "GGWkCookie/GGWkCookie-Prefix.pch"; 545 | INFOPLIST_FILE = "GGWkCookie/GGWkCookie-Info.plist"; 546 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 547 | MARKETING_VERSION = 0.1.1; 548 | MODULE_NAME = ExampleApp; 549 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}"; 550 | PRODUCT_NAME = "$(TARGET_NAME)"; 551 | WRAPPER_EXTENSION = app; 552 | }; 553 | name = Debug; 554 | }; 555 | 6003F5C1195388D20070C39A /* Release */ = { 556 | isa = XCBuildConfiguration; 557 | baseConfigurationReference = 78E060A4ACAAC8F8D5C5EF23 /* Pods-GGWkCookie_Example.release.xcconfig */; 558 | buildSettings = { 559 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 560 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 561 | GCC_PREFIX_HEADER = "GGWkCookie/GGWkCookie-Prefix.pch"; 562 | INFOPLIST_FILE = "GGWkCookie/GGWkCookie-Info.plist"; 563 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 564 | MARKETING_VERSION = 0.1.1; 565 | MODULE_NAME = ExampleApp; 566 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}"; 567 | PRODUCT_NAME = "$(TARGET_NAME)"; 568 | WRAPPER_EXTENSION = app; 569 | }; 570 | name = Release; 571 | }; 572 | 6003F5C3195388D20070C39A /* Debug */ = { 573 | isa = XCBuildConfiguration; 574 | baseConfigurationReference = 63D7043306CF0355F6256875 /* Pods-GGWkCookie_Tests.debug.xcconfig */; 575 | buildSettings = { 576 | BUNDLE_LOADER = "$(TEST_HOST)"; 577 | FRAMEWORK_SEARCH_PATHS = ( 578 | "$(SDKROOT)/Developer/Library/Frameworks", 579 | "$(inherited)", 580 | "$(DEVELOPER_FRAMEWORKS_DIR)", 581 | ); 582 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 583 | GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch"; 584 | GCC_PREPROCESSOR_DEFINITIONS = ( 585 | "DEBUG=1", 586 | "$(inherited)", 587 | ); 588 | INFOPLIST_FILE = "Tests/Tests-Info.plist"; 589 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}"; 590 | PRODUCT_NAME = "$(TARGET_NAME)"; 591 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GGWkCookie_Example.app/GGWkCookie_Example"; 592 | WRAPPER_EXTENSION = xctest; 593 | }; 594 | name = Debug; 595 | }; 596 | 6003F5C4195388D20070C39A /* Release */ = { 597 | isa = XCBuildConfiguration; 598 | baseConfigurationReference = 8083B02F655BE7B16C9D6DD3 /* Pods-GGWkCookie_Tests.release.xcconfig */; 599 | buildSettings = { 600 | BUNDLE_LOADER = "$(TEST_HOST)"; 601 | FRAMEWORK_SEARCH_PATHS = ( 602 | "$(SDKROOT)/Developer/Library/Frameworks", 603 | "$(inherited)", 604 | "$(DEVELOPER_FRAMEWORKS_DIR)", 605 | ); 606 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 607 | GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch"; 608 | INFOPLIST_FILE = "Tests/Tests-Info.plist"; 609 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}"; 610 | PRODUCT_NAME = "$(TARGET_NAME)"; 611 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GGWkCookie_Example.app/GGWkCookie_Example"; 612 | WRAPPER_EXTENSION = xctest; 613 | }; 614 | name = Release; 615 | }; 616 | /* End XCBuildConfiguration section */ 617 | 618 | /* Begin XCConfigurationList section */ 619 | 6003F585195388D10070C39A /* Build configuration list for PBXProject "GGWkCookie" */ = { 620 | isa = XCConfigurationList; 621 | buildConfigurations = ( 622 | 6003F5BD195388D20070C39A /* Debug */, 623 | 6003F5BE195388D20070C39A /* Release */, 624 | ); 625 | defaultConfigurationIsVisible = 0; 626 | defaultConfigurationName = Release; 627 | }; 628 | 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "GGWkCookie_Example" */ = { 629 | isa = XCConfigurationList; 630 | buildConfigurations = ( 631 | 6003F5C0195388D20070C39A /* Debug */, 632 | 6003F5C1195388D20070C39A /* Release */, 633 | ); 634 | defaultConfigurationIsVisible = 0; 635 | defaultConfigurationName = Release; 636 | }; 637 | 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "GGWkCookie_Tests" */ = { 638 | isa = XCConfigurationList; 639 | buildConfigurations = ( 640 | 6003F5C3195388D20070C39A /* Debug */, 641 | 6003F5C4195388D20070C39A /* Release */, 642 | ); 643 | defaultConfigurationIsVisible = 0; 644 | defaultConfigurationName = Release; 645 | }; 646 | /* End XCConfigurationList section */ 647 | }; 648 | rootObject = 6003F582195388D10070C39A /* Project object */; 649 | } 650 | --------------------------------------------------------------------------------