├── .github └── ISSUE_TEMPLATE.md ├── .gitignore ├── .travis.yml ├── AXWebViewController.podspec ├── AXWebViewController.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ ├── AXWebViewController.xcscheme │ └── AXWebViewControllerFramework.xcscheme ├── AXWebViewController.xcworkspace └── contents.xcworkspacedata ├── AXWebViewController ├── .DS_Store ├── AXWebViewController │ ├── .DS_Store │ ├── AXWebViewController.bundle │ │ ├── AXWebViewControllerActivityChrome-iPad.png │ │ ├── AXWebViewControllerActivityChrome-iPad@2x.png │ │ ├── AXWebViewControllerActivityChrome@2x.png │ │ ├── AXWebViewControllerActivitySafari-iPad.png │ │ ├── AXWebViewControllerActivitySafari-iPad@2x.png │ │ ├── AXWebViewControllerActivitySafari@2x.png │ │ ├── AXWebViewControllerBack.png │ │ ├── AXWebViewControllerBack@2x.png │ │ ├── AXWebViewControllerNext.png │ │ ├── AXWebViewControllerNext@2x.png │ │ ├── backItemImage@2x.png │ │ ├── backItemImage_hl@2x.png │ │ ├── en.lproj │ │ │ └── AXWebViewController.strings │ │ ├── html.bundle │ │ │ ├── 404.html │ │ │ ├── css │ │ │ │ └── nosingle.css │ │ │ ├── img │ │ │ │ ├── 404.png │ │ │ │ └── nosingle.png │ │ │ ├── js │ │ │ │ └── jquery-2.1.1.min.js │ │ │ └── neterror.html │ │ ├── zh-Hans.lproj │ │ │ └── AXWebViewController.strings │ │ └── zh-Hant.lproj │ │ │ └── AXWebViewController.strings │ ├── AXWebViewController.h │ ├── AXWebViewController.m │ ├── Activity │ │ ├── AXWebViewControllerActivity.h │ │ └── AXWebViewControllerActivity.m │ └── Security │ │ ├── AXSecurityPolicy.h │ │ └── AXSecurityPolicy.m ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── icon20@2x.png │ │ ├── icon20@3x.png │ │ ├── icon29@2x.png │ │ ├── icon29@3x.png │ │ ├── icon40@2x.png │ │ ├── icon40@3x.png │ │ ├── icon60@2x.png │ │ └── icon60@3x.png │ ├── Contents.json │ └── General │ │ ├── Contents.json │ │ └── back_indicator.imageset │ │ ├── Contents.json │ │ ├── btn_back@2x.png │ │ └── btn_back@3x.png ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── FullScreenViewController.h ├── FullScreenViewController.m ├── Info.plist ├── Swift.pdf ├── TabbarViewController1.h ├── TabbarViewController1.m ├── TabbarViewController2.h ├── TabbarViewController2.m ├── TableViewController.h ├── TableViewController.m ├── WebViewController.h ├── WebViewController.m ├── main.m ├── zh-Hans.lproj │ ├── LaunchScreen.strings │ └── Main.strings └── zh-Hant.lproj │ ├── LaunchScreen.strings │ └── Main.strings ├── AXWebViewControllerFramework └── Info.plist ├── AXWebViewControllerFrameworkTests ├── AXWebViewControllerFrameworkTests.m └── Info.plist ├── LICENSE ├── Podfile ├── Podfile.lock ├── README.md └── src └── img └── logo.png /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | > 感谢支持`AXWebViewController`,希望大家一起构建优秀的开源框架!你的问题对我来说很重要! 2 | > 3 | > **提问**: 如果你有任何问题,欢迎`email`我:`devedbox@qq.com` 或者加入我的开源项目qq群:`481867135` 4 | > 5 | > **需求**: 只需要填写以下前两条内容. 6 | > 7 | > **Bugs**: 为了尽快帮助你解决问题,请描述你的问题和问题复现的步骤. 8 | > 9 | > 谢谢帮助我帮助你们! :-) 10 | > 11 | > 提交issue之前,请移除以上内容. 12 | 13 | ## 目标 14 | 15 | 你想达到的目标,或者说你想实现的功能的效果或者预期的结果? 16 | 17 | ## 预期的结果 18 | 19 | 你预期会产生的结果? 20 | 21 | ## 实际的结果 22 | 23 | 实际上使用产生的结果?  24 | 25 | 比如:崩溃的控制台打印 26 | 27 | ## 问题复现的步骤 28 | 29 | issue复现所需的步骤,尽量详细! 30 | 31 | ## 示例代码 32 | 33 | 提供一个突出问题的代码示例或测试用例. 对于量较大的代码示例,链接到外部的`gists/repositories`是首选. 需要保密的话通过邮件`devedbox@qq.com`分享,邮件主题写issue的名称. 问题严重的话可以提供完整的`Xcode`工程最好! 34 | 35 | ## AXWebViewController和工具的版本 36 | 37 | ```shell 38 | echo "\`\`\` 39 | $(sw_vers) 40 | 41 | $(xcode-select -p) 42 | $(xcodebuild -version) 43 | 44 | $(which pod && pod --version) 45 | $(test -e Podfile.lock && cat Podfile.lock | sed -nE 's/^ - (Realm(Swift)? [^:]*):?/\1/p' || echo "(not in use here)") 46 | 47 | $(which bash && bash -version | head -n1) 48 | 49 | $(which carthage && carthage version) 50 | $(test -e Cartfile.resolved && cat Cartfile.resolved | grep --color=no realm || echo "(not in use here)") 51 | 52 | $(which git && git --version) 53 | \`\`\`" | tee /dev/tty | pbcopy 54 | ``` 55 | 56 | 复制以上内容到`终端`回车,就可以获取到版本信息. 获取到版本信息之后,请将以上脚本删除! 57 | 58 | AXWebViewController版本: ? 59 | 60 | Xcode版本: ? 61 | 62 | iOS/OSX版本: ? 63 | 64 | 依赖管理工具(cocoapods)版本: ? 65 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # macOS 2 | .DS_Store 3 | *.DS_Store 4 | */.DS_Store 5 | */**/.DS_Store 6 | 7 | # Xcode 8 | # 9 | build/ 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata 19 | *.xccheckout 20 | *.moved-aside 21 | DerivedData 22 | *.hmap 23 | *.ipa 24 | *.xcuserstate 25 | 26 | # CocoaPods 27 | # 28 | # We recommend against adding the Pods directory to your .gitignore. However 29 | # you should judge for yourself, the pros and cons are mentioned at: 30 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 31 | # 32 | Pods/ 33 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | xcode_workspace: AXWebViewController.xcworkspace 3 | xcode_scheme: AXWebViewController 4 | -------------------------------------------------------------------------------- /AXWebViewController.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint AXPickerView.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | s.name = "AXWebViewController" 19 | s.version = "0.7.2" 20 | s.summary = "A light weight web view controller in iOS." 21 | 22 | # This description is used to generate tags and improve search results. 23 | # * Think: What does it do? Why did you write it? What is the focus? 24 | # * Try to keep it short, snappy and to the point. 25 | # * Write the description between the DESC delimiters below. 26 | # * Finally, don't worry about the indent, CocoaPods strips it! 27 | s.description = <<-DESC 28 | A multi style picker view in iOS. 29 | * Think: Why did you write this? What is the focus? What does it do? 30 | * CocoaPods will be using this to generate tags, and improve search results. 31 | * Try to keep it short, snappy and to the point. 32 | * Finally, don't worry about the indent, CocoaPods strips it! 33 | DESC 34 | s.homepage = "https://github.com/devedbox/AXWebViewController" 35 | # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" 36 | 37 | 38 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 39 | # 40 | # Licensing your code is important. See http://choosealicense.com for more info. 41 | # CocoaPods will detect a license file if there is a named LICENSE* 42 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 43 | # 44 | 45 | s.license = "MIT" 46 | # s.license = { :type => "MIT", :file => "FILE_LICENSE" } 47 | 48 | 49 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 50 | # 51 | # Specify the authors of the library, with email addresses. Email addresses 52 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 53 | # accepts just a name if you'd rather not provide an email address. 54 | # 55 | # Specify a social_media_url where others can refer to, for example a twitter 56 | # profile URL. 57 | # 58 | 59 | s.author = { "艾星" => "862099730@qq.com" } 60 | # Or just: s.author = "aiXing" 61 | # s.authors = { "aiXing" => "862099730@qq.com" } 62 | # s.social_media_url = "http://twitter.com/aiXing" 63 | 64 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 65 | # 66 | # If this Pod runs only on iOS or OS X, then specify the platform and 67 | # the deployment target. You can optionally include the target after the platform. 68 | # 69 | 70 | # s.platform = :ios 71 | s.platform = :ios, "7.0" 72 | 73 | # When using multiple platforms 74 | # s.ios.deployment_target = "5.0" 75 | # s.osx.deployment_target = "10.7" 76 | # s.watchos.deployment_target = "2.0" 77 | # s.tvos.deployment_target = "9.0" 78 | 79 | 80 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 81 | # 82 | # Specify the location from where the source should be retrieved. 83 | # Supports git, hg, bzr, svn and HTTP. 84 | # 85 | 86 | s.source = { :git => "https://github.com/devedbox/AXWebViewController.git", :tag => s.version } 87 | 88 | 89 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 90 | # 91 | # CocoaPods is smart about how it includes source code. For source files 92 | # giving a folder will include any swift, h, m, mm, c & cpp files. 93 | # For header files it will include any header in the folder. 94 | # Not including the public_header_files will make all headers public. 95 | # 96 | 97 | s.source_files = "AXWebViewController/AXWebViewController/*.{h,m}", "AXWebViewController/AXWebViewController/Activity/*.{h,m}", "AXWebViewController/AXWebViewController/Security/*.{h,m}" 98 | #s.exclude_files = "Classes/Exclude" 99 | 100 | # s.public_header_files = "Classes/**/*.h" 101 | 102 | 103 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 104 | # 105 | # A list of resources included with the Pod. These are copied into the 106 | # target bundle with a build phase script. Anything else will be cleaned. 107 | # You can preserve files from being cleaned, please don't preserve 108 | # non-essential files like tests, examples and documentation. 109 | # 110 | 111 | s.resource = "AXWebViewController/AXWebViewController/AXWebViewController.bundle" 112 | # s.resources = "Resources/*.png" 113 | 114 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave" 115 | 116 | 117 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 118 | # 119 | # Link your library with frameworks, or libraries. Libraries do not include 120 | # the lib prefix of their name. 121 | # 122 | 123 | # s.framework = "SomeFramework" 124 | s.frameworks = "UIKit", "Foundation", "WebKit" 125 | 126 | # s.library = "iconv" 127 | # s.libraries = "iconv", "xml2" 128 | 129 | 130 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 131 | # 132 | # If your library depends on compiler flags you can set them in the xcconfig hash 133 | # where they will only apply to your library. If you depend on other Podspecs 134 | # you can include multiple dependencies to ensure it works. 135 | 136 | s.requires_arc = true 137 | 138 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 139 | # s.dependency "JSONKit", "~> 1.4" 140 | s.dependency "AXPracticalHUD" 141 | s.dependency "AXNavigationBackItemInjection" 142 | s.dependency "NJKWebViewProgress" 143 | s.dependency "Aspects" 144 | 145 | end 146 | -------------------------------------------------------------------------------- /AXWebViewController.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 01513BF01C28F70700CB8238 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 01513BEF1C28F70700CB8238 /* main.m */; }; 11 | 01513BF31C28F70700CB8238 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 01513BF21C28F70700CB8238 /* AppDelegate.m */; }; 12 | 01513BF91C28F70700CB8238 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 01513BF71C28F70700CB8238 /* Main.storyboard */; }; 13 | 01513BFB1C28F70700CB8238 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 01513BFA1C28F70700CB8238 /* Assets.xcassets */; }; 14 | 01513BFE1C28F70700CB8238 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 01513BFC1C28F70700CB8238 /* LaunchScreen.storyboard */; }; 15 | 01513C071C28F90000CB8238 /* AXWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 01513C061C28F90000CB8238 /* AXWebViewController.m */; }; 16 | 0197B9351D3F703300AF10F9 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0197B9341D3F703300AF10F9 /* WebKit.framework */; }; 17 | 01AA4F191D4F28C2008F2A2C /* TabbarViewController1.m in Sources */ = {isa = PBXBuildFile; fileRef = 01AA4F181D4F28C2008F2A2C /* TabbarViewController1.m */; }; 18 | 01AA4F1C1D4F28DD008F2A2C /* TabbarViewController2.m in Sources */ = {isa = PBXBuildFile; fileRef = 01AA4F1B1D4F28DD008F2A2C /* TabbarViewController2.m */; }; 19 | 01CDC1511C2A3C9100D9AF53 /* AXWebViewController.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 01CDC1501C2A3C9100D9AF53 /* AXWebViewController.bundle */; }; 20 | 01CDC15D1C2A41DF00D9AF53 /* TableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 01CDC15C1C2A41DF00D9AF53 /* TableViewController.m */; }; 21 | 97F6BE6D557C0BB485DDCF88 /* libPods-AXWebViewController.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2642E682614F41BF460E7673 /* libPods-AXWebViewController.a */; }; 22 | DCA3C59F1FB0302F008DB632 /* FullScreenViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DCA3C59E1FB0302F008DB632 /* FullScreenViewController.m */; }; 23 | DCABA01B1EC5EE2A005C7D31 /* AXSecurityPolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = DCABA01A1EC5EE2A005C7D31 /* AXSecurityPolicy.m */; }; 24 | DCABA0231EC5FDFF005C7D31 /* AXWebViewControllerActivity.m in Sources */ = {isa = PBXBuildFile; fileRef = DCABA01E1EC5FDFF005C7D31 /* AXWebViewControllerActivity.m */; }; 25 | DCCF48241E7987C9009CF38E /* Swift.pdf in Resources */ = {isa = PBXBuildFile; fileRef = DCCF48231E7987C9009CF38E /* Swift.pdf */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXFileReference section */ 29 | 013513EA1D60B83D003BDCEA /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Main.strings"; sourceTree = ""; }; 30 | 013513EB1D60B83D003BDCEA /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/LaunchScreen.strings"; sourceTree = ""; }; 31 | 01513BEB1C28F70700CB8238 /* AXWebViewController.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AXWebViewController.app; sourceTree = BUILT_PRODUCTS_DIR; }; 32 | 01513BEF1C28F70700CB8238 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 33 | 01513BF11C28F70700CB8238 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 34 | 01513BF21C28F70700CB8238 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 35 | 01513BF81C28F70700CB8238 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 36 | 01513BFA1C28F70700CB8238 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 37 | 01513BFD1C28F70700CB8238 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 38 | 01513BFF1C28F70700CB8238 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 39 | 01513C051C28F90000CB8238 /* AXWebViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AXWebViewController.h; path = AXWebViewController/AXWebViewController.h; sourceTree = ""; }; 40 | 01513C061C28F90000CB8238 /* AXWebViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AXWebViewController.m; path = AXWebViewController/AXWebViewController.m; sourceTree = ""; }; 41 | 0197B9341D3F703300AF10F9 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; 42 | 01AA4F171D4F28C2008F2A2C /* TabbarViewController1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TabbarViewController1.h; sourceTree = ""; }; 43 | 01AA4F181D4F28C2008F2A2C /* TabbarViewController1.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TabbarViewController1.m; sourceTree = ""; }; 44 | 01AA4F1A1D4F28DD008F2A2C /* TabbarViewController2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TabbarViewController2.h; sourceTree = ""; }; 45 | 01AA4F1B1D4F28DD008F2A2C /* TabbarViewController2.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TabbarViewController2.m; sourceTree = ""; }; 46 | 01CDC1501C2A3C9100D9AF53 /* AXWebViewController.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = AXWebViewController.bundle; path = AXWebViewController/AXWebViewController.bundle; sourceTree = ""; }; 47 | 01CDC15B1C2A41DF00D9AF53 /* TableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableViewController.h; sourceTree = ""; }; 48 | 01CDC15C1C2A41DF00D9AF53 /* TableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TableViewController.m; sourceTree = ""; }; 49 | 0326F0589F0B7F449EE39607 /* Pods-AXWebViewController.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AXWebViewController.release.xcconfig"; path = "Pods/Target Support Files/Pods-AXWebViewController/Pods-AXWebViewController.release.xcconfig"; sourceTree = ""; }; 50 | 2642E682614F41BF460E7673 /* libPods-AXWebViewController.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AXWebViewController.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | 3B7311EC599653BFAAF42107 /* Pods-AXWebViewController.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AXWebViewController.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AXWebViewController/Pods-AXWebViewController.debug.xcconfig"; sourceTree = ""; }; 52 | A13CC1551E977227003AC1B2 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Main.strings"; sourceTree = ""; }; 53 | A13CC1561E977227003AC1B2 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/LaunchScreen.strings"; sourceTree = ""; }; 54 | DCA3C59D1FB0302F008DB632 /* FullScreenViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FullScreenViewController.h; sourceTree = ""; }; 55 | DCA3C59E1FB0302F008DB632 /* FullScreenViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FullScreenViewController.m; sourceTree = ""; }; 56 | DCABA0191EC5EE2A005C7D31 /* AXSecurityPolicy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AXSecurityPolicy.h; sourceTree = ""; }; 57 | DCABA01A1EC5EE2A005C7D31 /* AXSecurityPolicy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AXSecurityPolicy.m; sourceTree = ""; }; 58 | DCABA01D1EC5FDFF005C7D31 /* AXWebViewControllerActivity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AXWebViewControllerActivity.h; sourceTree = ""; }; 59 | DCABA01E1EC5FDFF005C7D31 /* AXWebViewControllerActivity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AXWebViewControllerActivity.m; sourceTree = ""; }; 60 | DCCF48231E7987C9009CF38E /* Swift.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = Swift.pdf; sourceTree = ""; }; 61 | /* End PBXFileReference section */ 62 | 63 | /* Begin PBXFrameworksBuildPhase section */ 64 | 01513BE81C28F70700CB8238 /* Frameworks */ = { 65 | isa = PBXFrameworksBuildPhase; 66 | buildActionMask = 2147483647; 67 | files = ( 68 | 0197B9351D3F703300AF10F9 /* WebKit.framework in Frameworks */, 69 | 97F6BE6D557C0BB485DDCF88 /* libPods-AXWebViewController.a in Frameworks */, 70 | ); 71 | runOnlyForDeploymentPostprocessing = 0; 72 | }; 73 | /* End PBXFrameworksBuildPhase section */ 74 | 75 | /* Begin PBXGroup section */ 76 | 01513BE21C28F70700CB8238 = { 77 | isa = PBXGroup; 78 | children = ( 79 | 01513BED1C28F70700CB8238 /* AXWebViewController */, 80 | 01513BEC1C28F70700CB8238 /* Products */, 81 | 0BC220E02B437FE0466F4248 /* Pods */, 82 | 6757935A39C536BCAB9BA3A3 /* Frameworks */, 83 | ); 84 | sourceTree = ""; 85 | }; 86 | 01513BEC1C28F70700CB8238 /* Products */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 01513BEB1C28F70700CB8238 /* AXWebViewController.app */, 90 | ); 91 | name = Products; 92 | sourceTree = ""; 93 | }; 94 | 01513BED1C28F70700CB8238 /* AXWebViewController */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | 01513BF11C28F70700CB8238 /* AppDelegate.h */, 98 | 01513BF21C28F70700CB8238 /* AppDelegate.m */, 99 | DCA3C59B1FB02FEE008DB632 /* Samples */, 100 | 01513C081C28F90300CB8238 /* AXWebViewController */, 101 | 01513BF71C28F70700CB8238 /* Main.storyboard */, 102 | DCCF48231E7987C9009CF38E /* Swift.pdf */, 103 | 01513BFA1C28F70700CB8238 /* Assets.xcassets */, 104 | 01513BFC1C28F70700CB8238 /* LaunchScreen.storyboard */, 105 | 01513BFF1C28F70700CB8238 /* Info.plist */, 106 | 01513BEE1C28F70700CB8238 /* Supporting Files */, 107 | ); 108 | path = AXWebViewController; 109 | sourceTree = ""; 110 | }; 111 | 01513BEE1C28F70700CB8238 /* Supporting Files */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | 01513BEF1C28F70700CB8238 /* main.m */, 115 | ); 116 | name = "Supporting Files"; 117 | sourceTree = ""; 118 | }; 119 | 01513C081C28F90300CB8238 /* AXWebViewController */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | 01513C051C28F90000CB8238 /* AXWebViewController.h */, 123 | 01513C061C28F90000CB8238 /* AXWebViewController.m */, 124 | 01CDC1501C2A3C9100D9AF53 /* AXWebViewController.bundle */, 125 | DCABA01C1EC5FDFF005C7D31 /* Activity */, 126 | DCABA0181EC5EE2A005C7D31 /* Security */, 127 | ); 128 | name = AXWebViewController; 129 | sourceTree = ""; 130 | }; 131 | 0BC220E02B437FE0466F4248 /* Pods */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 3B7311EC599653BFAAF42107 /* Pods-AXWebViewController.debug.xcconfig */, 135 | 0326F0589F0B7F449EE39607 /* Pods-AXWebViewController.release.xcconfig */, 136 | ); 137 | name = Pods; 138 | sourceTree = ""; 139 | }; 140 | 6757935A39C536BCAB9BA3A3 /* Frameworks */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | 0197B9341D3F703300AF10F9 /* WebKit.framework */, 144 | 2642E682614F41BF460E7673 /* libPods-AXWebViewController.a */, 145 | ); 146 | name = Frameworks; 147 | sourceTree = ""; 148 | }; 149 | DCA3C59B1FB02FEE008DB632 /* Samples */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | 01CDC15B1C2A41DF00D9AF53 /* TableViewController.h */, 153 | 01CDC15C1C2A41DF00D9AF53 /* TableViewController.m */, 154 | 01AA4F171D4F28C2008F2A2C /* TabbarViewController1.h */, 155 | 01AA4F181D4F28C2008F2A2C /* TabbarViewController1.m */, 156 | 01AA4F1A1D4F28DD008F2A2C /* TabbarViewController2.h */, 157 | 01AA4F1B1D4F28DD008F2A2C /* TabbarViewController2.m */, 158 | DCA3C59C1FB0300A008DB632 /* Presentation */, 159 | ); 160 | name = Samples; 161 | sourceTree = ""; 162 | }; 163 | DCA3C59C1FB0300A008DB632 /* Presentation */ = { 164 | isa = PBXGroup; 165 | children = ( 166 | DCA3C59D1FB0302F008DB632 /* FullScreenViewController.h */, 167 | DCA3C59E1FB0302F008DB632 /* FullScreenViewController.m */, 168 | ); 169 | name = Presentation; 170 | sourceTree = ""; 171 | }; 172 | DCABA0181EC5EE2A005C7D31 /* Security */ = { 173 | isa = PBXGroup; 174 | children = ( 175 | DCABA0191EC5EE2A005C7D31 /* AXSecurityPolicy.h */, 176 | DCABA01A1EC5EE2A005C7D31 /* AXSecurityPolicy.m */, 177 | ); 178 | name = Security; 179 | path = AXWebViewController/Security; 180 | sourceTree = ""; 181 | }; 182 | DCABA01C1EC5FDFF005C7D31 /* Activity */ = { 183 | isa = PBXGroup; 184 | children = ( 185 | DCABA01D1EC5FDFF005C7D31 /* AXWebViewControllerActivity.h */, 186 | DCABA01E1EC5FDFF005C7D31 /* AXWebViewControllerActivity.m */, 187 | ); 188 | name = Activity; 189 | path = AXWebViewController/Activity; 190 | sourceTree = ""; 191 | }; 192 | /* End PBXGroup section */ 193 | 194 | /* Begin PBXNativeTarget section */ 195 | 01513BEA1C28F70700CB8238 /* AXWebViewController */ = { 196 | isa = PBXNativeTarget; 197 | buildConfigurationList = 01513C021C28F70700CB8238 /* Build configuration list for PBXNativeTarget "AXWebViewController" */; 198 | buildPhases = ( 199 | 43867203D586B50CBAAFDB18 /* [CP] Check Pods Manifest.lock */, 200 | 01513BE71C28F70700CB8238 /* Sources */, 201 | 01513BE81C28F70700CB8238 /* Frameworks */, 202 | 01513BE91C28F70700CB8238 /* Resources */, 203 | F3182DEE5A600ABFAF07F7DC /* [CP] Embed Pods Frameworks */, 204 | 90CC7504393E7254ABAF393F /* [CP] Copy Pods Resources */, 205 | ); 206 | buildRules = ( 207 | ); 208 | dependencies = ( 209 | ); 210 | name = AXWebViewController; 211 | productName = AXWebViewController; 212 | productReference = 01513BEB1C28F70700CB8238 /* AXWebViewController.app */; 213 | productType = "com.apple.product-type.application"; 214 | }; 215 | /* End PBXNativeTarget section */ 216 | 217 | /* Begin PBXProject section */ 218 | 01513BE31C28F70700CB8238 /* Project object */ = { 219 | isa = PBXProject; 220 | attributes = { 221 | LastUpgradeCheck = 0900; 222 | ORGANIZATIONNAME = AiXing; 223 | TargetAttributes = { 224 | 01513BEA1C28F70700CB8238 = { 225 | CreatedOnToolsVersion = 7.2; 226 | DevelopmentTeam = TKA48YVS5T; 227 | ProvisioningStyle = Automatic; 228 | }; 229 | }; 230 | }; 231 | buildConfigurationList = 01513BE61C28F70700CB8238 /* Build configuration list for PBXProject "AXWebViewController" */; 232 | compatibilityVersion = "Xcode 3.2"; 233 | developmentRegion = English; 234 | hasScannedForEncodings = 0; 235 | knownRegions = ( 236 | en, 237 | Base, 238 | "zh-Hans", 239 | ); 240 | mainGroup = 01513BE21C28F70700CB8238; 241 | productRefGroup = 01513BEC1C28F70700CB8238 /* Products */; 242 | projectDirPath = ""; 243 | projectRoot = ""; 244 | targets = ( 245 | 01513BEA1C28F70700CB8238 /* AXWebViewController */, 246 | ); 247 | }; 248 | /* End PBXProject section */ 249 | 250 | /* Begin PBXResourcesBuildPhase section */ 251 | 01513BE91C28F70700CB8238 /* Resources */ = { 252 | isa = PBXResourcesBuildPhase; 253 | buildActionMask = 2147483647; 254 | files = ( 255 | 01CDC1511C2A3C9100D9AF53 /* AXWebViewController.bundle in Resources */, 256 | 01513BFE1C28F70700CB8238 /* LaunchScreen.storyboard in Resources */, 257 | 01513BFB1C28F70700CB8238 /* Assets.xcassets in Resources */, 258 | DCCF48241E7987C9009CF38E /* Swift.pdf in Resources */, 259 | 01513BF91C28F70700CB8238 /* Main.storyboard in Resources */, 260 | ); 261 | runOnlyForDeploymentPostprocessing = 0; 262 | }; 263 | /* End PBXResourcesBuildPhase section */ 264 | 265 | /* Begin PBXShellScriptBuildPhase section */ 266 | 43867203D586B50CBAAFDB18 /* [CP] Check Pods Manifest.lock */ = { 267 | isa = PBXShellScriptBuildPhase; 268 | buildActionMask = 2147483647; 269 | files = ( 270 | ); 271 | inputPaths = ( 272 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 273 | "${PODS_ROOT}/Manifest.lock", 274 | ); 275 | name = "[CP] Check Pods Manifest.lock"; 276 | outputPaths = ( 277 | "$(DERIVED_FILE_DIR)/Pods-AXWebViewController-checkManifestLockResult.txt", 278 | ); 279 | runOnlyForDeploymentPostprocessing = 0; 280 | shellPath = /bin/sh; 281 | 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"; 282 | showEnvVarsInLog = 0; 283 | }; 284 | 90CC7504393E7254ABAF393F /* [CP] Copy Pods Resources */ = { 285 | isa = PBXShellScriptBuildPhase; 286 | buildActionMask = 2147483647; 287 | files = ( 288 | ); 289 | inputPaths = ( 290 | "${SRCROOT}/Pods/Target Support Files/Pods-AXWebViewController/Pods-AXWebViewController-resources.sh", 291 | "${PODS_ROOT}/AXIndicatorView/AXIndicatorView/Classes/AXIndicatorView.bundle", 292 | "${PODS_ROOT}/AXPracticalHUD/AXPracticalHUD/AXPracticalHUD/AXPracticalHUD.bundle", 293 | ); 294 | name = "[CP] Copy Pods Resources"; 295 | outputPaths = ( 296 | "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}", 297 | ); 298 | runOnlyForDeploymentPostprocessing = 0; 299 | shellPath = /bin/sh; 300 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AXWebViewController/Pods-AXWebViewController-resources.sh\"\n"; 301 | showEnvVarsInLog = 0; 302 | }; 303 | F3182DEE5A600ABFAF07F7DC /* [CP] Embed Pods Frameworks */ = { 304 | isa = PBXShellScriptBuildPhase; 305 | buildActionMask = 2147483647; 306 | files = ( 307 | ); 308 | inputPaths = ( 309 | ); 310 | name = "[CP] Embed Pods Frameworks"; 311 | outputPaths = ( 312 | ); 313 | runOnlyForDeploymentPostprocessing = 0; 314 | shellPath = /bin/sh; 315 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AXWebViewController/Pods-AXWebViewController-frameworks.sh\"\n"; 316 | showEnvVarsInLog = 0; 317 | }; 318 | /* End PBXShellScriptBuildPhase section */ 319 | 320 | /* Begin PBXSourcesBuildPhase section */ 321 | 01513BE71C28F70700CB8238 /* Sources */ = { 322 | isa = PBXSourcesBuildPhase; 323 | buildActionMask = 2147483647; 324 | files = ( 325 | 01AA4F191D4F28C2008F2A2C /* TabbarViewController1.m in Sources */, 326 | 01513BF31C28F70700CB8238 /* AppDelegate.m in Sources */, 327 | DCA3C59F1FB0302F008DB632 /* FullScreenViewController.m in Sources */, 328 | 01513C071C28F90000CB8238 /* AXWebViewController.m in Sources */, 329 | DCABA0231EC5FDFF005C7D31 /* AXWebViewControllerActivity.m in Sources */, 330 | 01513BF01C28F70700CB8238 /* main.m in Sources */, 331 | 01AA4F1C1D4F28DD008F2A2C /* TabbarViewController2.m in Sources */, 332 | DCABA01B1EC5EE2A005C7D31 /* AXSecurityPolicy.m in Sources */, 333 | 01CDC15D1C2A41DF00D9AF53 /* TableViewController.m in Sources */, 334 | ); 335 | runOnlyForDeploymentPostprocessing = 0; 336 | }; 337 | /* End PBXSourcesBuildPhase section */ 338 | 339 | /* Begin PBXVariantGroup section */ 340 | 01513BF71C28F70700CB8238 /* Main.storyboard */ = { 341 | isa = PBXVariantGroup; 342 | children = ( 343 | 01513BF81C28F70700CB8238 /* Base */, 344 | 013513EA1D60B83D003BDCEA /* zh-Hans */, 345 | A13CC1551E977227003AC1B2 /* zh-Hant */, 346 | ); 347 | name = Main.storyboard; 348 | sourceTree = ""; 349 | }; 350 | 01513BFC1C28F70700CB8238 /* LaunchScreen.storyboard */ = { 351 | isa = PBXVariantGroup; 352 | children = ( 353 | 01513BFD1C28F70700CB8238 /* Base */, 354 | 013513EB1D60B83D003BDCEA /* zh-Hans */, 355 | A13CC1561E977227003AC1B2 /* zh-Hant */, 356 | ); 357 | name = LaunchScreen.storyboard; 358 | sourceTree = ""; 359 | }; 360 | /* End PBXVariantGroup section */ 361 | 362 | /* Begin XCBuildConfiguration section */ 363 | 01513C001C28F70700CB8238 /* Debug */ = { 364 | isa = XCBuildConfiguration; 365 | buildSettings = { 366 | ALWAYS_SEARCH_USER_PATHS = NO; 367 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 368 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 369 | CLANG_CXX_LIBRARY = "libc++"; 370 | CLANG_ENABLE_MODULES = YES; 371 | CLANG_ENABLE_OBJC_ARC = YES; 372 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 373 | CLANG_WARN_BOOL_CONVERSION = YES; 374 | CLANG_WARN_COMMA = YES; 375 | CLANG_WARN_CONSTANT_CONVERSION = YES; 376 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 377 | CLANG_WARN_EMPTY_BODY = YES; 378 | CLANG_WARN_ENUM_CONVERSION = YES; 379 | CLANG_WARN_INFINITE_RECURSION = YES; 380 | CLANG_WARN_INT_CONVERSION = YES; 381 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 382 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 383 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 384 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 385 | CLANG_WARN_STRICT_PROTOTYPES = YES; 386 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 387 | CLANG_WARN_UNREACHABLE_CODE = YES; 388 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 389 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 390 | COPY_PHASE_STRIP = NO; 391 | DEBUG_INFORMATION_FORMAT = dwarf; 392 | ENABLE_STRICT_OBJC_MSGSEND = YES; 393 | ENABLE_TESTABILITY = YES; 394 | GCC_C_LANGUAGE_STANDARD = gnu99; 395 | GCC_DYNAMIC_NO_PIC = NO; 396 | GCC_NO_COMMON_BLOCKS = YES; 397 | GCC_OPTIMIZATION_LEVEL = 0; 398 | GCC_PREPROCESSOR_DEFINITIONS = ( 399 | "DEBUG=1", 400 | "$(inherited)", 401 | ); 402 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 403 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 404 | GCC_WARN_UNDECLARED_SELECTOR = YES; 405 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 406 | GCC_WARN_UNUSED_FUNCTION = YES; 407 | GCC_WARN_UNUSED_VARIABLE = YES; 408 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 409 | MTL_ENABLE_DEBUG_INFO = YES; 410 | ONLY_ACTIVE_ARCH = YES; 411 | SDKROOT = iphoneos; 412 | }; 413 | name = Debug; 414 | }; 415 | 01513C011C28F70700CB8238 /* Release */ = { 416 | isa = XCBuildConfiguration; 417 | buildSettings = { 418 | ALWAYS_SEARCH_USER_PATHS = NO; 419 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 420 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 421 | CLANG_CXX_LIBRARY = "libc++"; 422 | CLANG_ENABLE_MODULES = YES; 423 | CLANG_ENABLE_OBJC_ARC = YES; 424 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 425 | CLANG_WARN_BOOL_CONVERSION = YES; 426 | CLANG_WARN_COMMA = YES; 427 | CLANG_WARN_CONSTANT_CONVERSION = YES; 428 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 429 | CLANG_WARN_EMPTY_BODY = YES; 430 | CLANG_WARN_ENUM_CONVERSION = YES; 431 | CLANG_WARN_INFINITE_RECURSION = YES; 432 | CLANG_WARN_INT_CONVERSION = YES; 433 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 434 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 435 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 436 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 437 | CLANG_WARN_STRICT_PROTOTYPES = YES; 438 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 439 | CLANG_WARN_UNREACHABLE_CODE = YES; 440 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 441 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 442 | COPY_PHASE_STRIP = NO; 443 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 444 | ENABLE_NS_ASSERTIONS = NO; 445 | ENABLE_STRICT_OBJC_MSGSEND = YES; 446 | GCC_C_LANGUAGE_STANDARD = gnu99; 447 | GCC_NO_COMMON_BLOCKS = YES; 448 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 449 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 450 | GCC_WARN_UNDECLARED_SELECTOR = YES; 451 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 452 | GCC_WARN_UNUSED_FUNCTION = YES; 453 | GCC_WARN_UNUSED_VARIABLE = YES; 454 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 455 | MTL_ENABLE_DEBUG_INFO = NO; 456 | SDKROOT = iphoneos; 457 | VALIDATE_PRODUCT = YES; 458 | }; 459 | name = Release; 460 | }; 461 | 01513C031C28F70700CB8238 /* Debug */ = { 462 | isa = XCBuildConfiguration; 463 | baseConfigurationReference = 3B7311EC599653BFAAF42107 /* Pods-AXWebViewController.debug.xcconfig */; 464 | buildSettings = { 465 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 466 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 467 | DEVELOPMENT_TEAM = TKA48YVS5T; 468 | INFOPLIST_FILE = AXWebViewController/Info.plist; 469 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 470 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 471 | PRODUCT_BUNDLE_IDENTIFIER = KEEPStudio.AXWebViewController; 472 | PRODUCT_NAME = "$(TARGET_NAME)"; 473 | PROVISIONING_PROFILE_SPECIFIER = ""; 474 | TARGETED_DEVICE_FAMILY = "1,2"; 475 | }; 476 | name = Debug; 477 | }; 478 | 01513C041C28F70700CB8238 /* Release */ = { 479 | isa = XCBuildConfiguration; 480 | baseConfigurationReference = 0326F0589F0B7F449EE39607 /* Pods-AXWebViewController.release.xcconfig */; 481 | buildSettings = { 482 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 483 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 484 | DEVELOPMENT_TEAM = TKA48YVS5T; 485 | INFOPLIST_FILE = AXWebViewController/Info.plist; 486 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 487 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 488 | PRODUCT_BUNDLE_IDENTIFIER = KEEPStudio.AXWebViewController; 489 | PRODUCT_NAME = "$(TARGET_NAME)"; 490 | PROVISIONING_PROFILE_SPECIFIER = ""; 491 | TARGETED_DEVICE_FAMILY = "1,2"; 492 | }; 493 | name = Release; 494 | }; 495 | /* End XCBuildConfiguration section */ 496 | 497 | /* Begin XCConfigurationList section */ 498 | 01513BE61C28F70700CB8238 /* Build configuration list for PBXProject "AXWebViewController" */ = { 499 | isa = XCConfigurationList; 500 | buildConfigurations = ( 501 | 01513C001C28F70700CB8238 /* Debug */, 502 | 01513C011C28F70700CB8238 /* Release */, 503 | ); 504 | defaultConfigurationIsVisible = 0; 505 | defaultConfigurationName = Release; 506 | }; 507 | 01513C021C28F70700CB8238 /* Build configuration list for PBXNativeTarget "AXWebViewController" */ = { 508 | isa = XCConfigurationList; 509 | buildConfigurations = ( 510 | 01513C031C28F70700CB8238 /* Debug */, 511 | 01513C041C28F70700CB8238 /* Release */, 512 | ); 513 | defaultConfigurationIsVisible = 0; 514 | defaultConfigurationName = Release; 515 | }; 516 | /* End XCConfigurationList section */ 517 | }; 518 | rootObject = 01513BE31C28F70700CB8238 /* Project object */; 519 | } 520 | -------------------------------------------------------------------------------- /AXWebViewController.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /AXWebViewController.xcodeproj/xcshareddata/xcschemes/AXWebViewController.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 56 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | 77 | 83 | 84 | 85 | 86 | 88 | 89 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /AXWebViewController.xcodeproj/xcshareddata/xcschemes/AXWebViewControllerFramework.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 72 | 73 | 74 | 75 | 77 | 78 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /AXWebViewController.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /AXWebViewController/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/.DS_Store -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/AXWebViewController/.DS_Store -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/AXWebViewController.bundle/AXWebViewControllerActivityChrome-iPad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/AXWebViewController/AXWebViewController.bundle/AXWebViewControllerActivityChrome-iPad.png -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/AXWebViewController.bundle/AXWebViewControllerActivityChrome-iPad@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/AXWebViewController/AXWebViewController.bundle/AXWebViewControllerActivityChrome-iPad@2x.png -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/AXWebViewController.bundle/AXWebViewControllerActivityChrome@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/AXWebViewController/AXWebViewController.bundle/AXWebViewControllerActivityChrome@2x.png -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/AXWebViewController.bundle/AXWebViewControllerActivitySafari-iPad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/AXWebViewController/AXWebViewController.bundle/AXWebViewControllerActivitySafari-iPad.png -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/AXWebViewController.bundle/AXWebViewControllerActivitySafari-iPad@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/AXWebViewController/AXWebViewController.bundle/AXWebViewControllerActivitySafari-iPad@2x.png -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/AXWebViewController.bundle/AXWebViewControllerActivitySafari@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/AXWebViewController/AXWebViewController.bundle/AXWebViewControllerActivitySafari@2x.png -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/AXWebViewController.bundle/AXWebViewControllerBack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/AXWebViewController/AXWebViewController.bundle/AXWebViewControllerBack.png -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/AXWebViewController.bundle/AXWebViewControllerBack@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/AXWebViewController/AXWebViewController.bundle/AXWebViewControllerBack@2x.png -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/AXWebViewController.bundle/AXWebViewControllerNext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/AXWebViewController/AXWebViewController.bundle/AXWebViewControllerNext.png -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/AXWebViewController.bundle/AXWebViewControllerNext@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/AXWebViewController/AXWebViewController.bundle/AXWebViewControllerNext@2x.png -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/AXWebViewController.bundle/backItemImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/AXWebViewController/AXWebViewController.bundle/backItemImage@2x.png -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/AXWebViewController.bundle/backItemImage_hl@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/AXWebViewController/AXWebViewController.bundle/backItemImage_hl@2x.png -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/AXWebViewController.bundle/en.lproj/AXWebViewController.strings: -------------------------------------------------------------------------------- 1 | /* 2 | AXWebViewController.strings 3 | AXWebViewController 4 | 5 | Created by devedbox on 16/8/14. 6 | Copyright © 2016年 AiXing. All rights reserved. 7 | */ 8 | "back" = "Back"; 9 | "close" = "Close"; 10 | "loading" = "Loading..."; 11 | "load failed" = "Load failed"; 12 | "load failed:" = "Load failed: "; 13 | "web page" = "This page was generated by "; 14 | "provided" = ""; 15 | "browsing the web" = "Web browsing"; 16 | 17 | "messages" = "Messages from web page"; 18 | "cancel" = "Cancel"; 19 | "confirm" = "Confirm"; 20 | "input" = "Input text content"; 21 | "terminate" = "Web content process did terminate"; 22 | 23 | "OpenInChrome" = "Open in Chrome"; 24 | "OpenInSafari" = "Open in Safari"; 25 | -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/AXWebViewController.bundle/html.bundle/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 404 8 | 9 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
31 |

Not Found

32 |

点击重试

33 | 34 | 35 | -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/AXWebViewController.bundle/html.bundle/css/nosingle.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | /* CSS Document */ 3 | *{ 4 | margin:0px; 5 | padding:0px; 6 | font-family:"PingFang"; 7 | } 8 | body li{ 9 | list-style-type:none; 10 | } 11 | body a{ 12 | text-decoration:none; 13 | } 14 | img{ 15 | border:0px; 16 | } 17 | a:focus{ 18 | outline:none; 19 | } 20 | a{ 21 | blr:expression(this.onFocus=this.blur()); 22 | }/**链接a在获得焦点的同时失去焦点。如果用的是图片链接之类的,不会显示周边的**/ 23 | /*****main*****/ 24 | .img404{ 25 | width:8rem; 26 | overflow:hidden; 27 | margin:5rem auto 1rem; 28 | } 29 | .img404 img{ 30 | width:100%; 31 | } 32 | .detail404,.detail_neor{ 33 | text-align:center; 34 | font-size:12px; 35 | color:#cecece; 36 | } 37 | .btn404,.detail_neor_btn{ 38 | text-align:center; 39 | color:#646464; 40 | font-size:12px; 41 | border:1px solid #cecece; 42 | width:8rem; 43 | margin:0.6rem auto; 44 | padding:0.3rem 0 0.3rem; 45 | border-radius:3px; 46 | -webkit-border-radius:3px; 47 | -moz-border-radius:3px; 48 | } 49 | .neterror{ 50 | width:4rem; 51 | overflow:hidden; 52 | margin:6rem auto 1rem; 53 | } 54 | .neterror img{ 55 | width:100%; 56 | } 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/AXWebViewController.bundle/html.bundle/img/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/AXWebViewController/AXWebViewController.bundle/html.bundle/img/404.png -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/AXWebViewController.bundle/html.bundle/img/nosingle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/AXWebViewController/AXWebViewController.bundle/html.bundle/img/nosingle.png -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/AXWebViewController.bundle/html.bundle/neterror.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 网络错误 8 | 9 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
31 |

网络出错啦,请点击按钮重新加载

32 |

重新加载

33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/AXWebViewController.bundle/zh-Hans.lproj/AXWebViewController.strings: -------------------------------------------------------------------------------- 1 | /* 2 | AXWebViewController.strings 3 | AXWebViewController 4 | 5 | Created by devedbox on 16/8/14. 6 | Copyright © 2016年 AiXing. All rights reserved. 7 | */ 8 | "back" = "返回"; 9 | "close" = "关闭"; 10 | "loading" = "加载中..."; 11 | "load failed" = "加载失败"; 12 | "load failed:" = "网页加载失败:"; 13 | "web page" = "网页由"; 14 | "provided" = "提供"; 15 | "browsing the web" = "内容浏览"; 16 | 17 | "messages" = "来自网页的消息"; 18 | "cancel" = "取消"; 19 | "confirm" = "确定"; 20 | "input" = "输入文字消息"; 21 | "terminate" = "网页进程终止"; 22 | 23 | "OpenInChrome" = "在Chrome中打开"; 24 | "OpenInSafari" = "在Safari中打开"; 25 | -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/AXWebViewController.bundle/zh-Hant.lproj/AXWebViewController.strings: -------------------------------------------------------------------------------- 1 | /* 2 | AXWebViewController.strings 3 | AXWebViewController 4 | 5 | Created by devedbox on 16/8/14. 6 | Copyright © 2016年 AiXing. All rights reserved. 7 | */ 8 | "back" = "返回"; 9 | "close" = "關閉"; 10 | "loading" = "下載中..."; 11 | "load failed" = "下載失敗"; 12 | "load failed:" = "網頁下載失敗:"; 13 | "web page" = "網頁由"; 14 | "provided" = "提供"; 15 | "browsing the web" = "內容瀏覽"; 16 | 17 | "messages" = "來自網頁的消息"; 18 | "cancel" = "取消"; 19 | "confirm" = "確定"; 20 | "input" = "輸入文字"; 21 | "terminate" = "網頁結束"; 22 | 23 | "OpenInChrome" = "在Chrome中打開"; 24 | "OpenInSafari" = "在Safari中打開"; 25 | -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/AXWebViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // AXWebViewController.h 3 | // AXWebViewController 4 | // 5 | // Created by ai on 15/12/22. 6 | // Copyright © 2015年 devedbox. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in all 16 | // copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | // SOFTWARE. 25 | 26 | #ifndef __IPHONE_8_0 27 | #define __IPHONE_8_0 80000 28 | #endif 29 | #ifndef __IPHONE_9_0 30 | #define __IPHONE_9_0 90000 31 | #endif 32 | 33 | #ifndef AX_WEB_VIEW_CONTROLLER_USING_WEBKIT 34 | #define AX_WEB_VIEW_CONTROLLER_USING_WEBKIT __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0 35 | // #define AX_WEB_VIEW_CONTROLLER_USING_WEBKIT 1 36 | #endif 37 | 38 | #ifndef AX_WEB_VIEW_CONTROLLER_DEFINES_PROXY 39 | #define AX_WEB_VIEW_CONTROLLER_DEFINES_PROXY AX_WEB_VIEW_CONTROLLER_USING_WEBKIT 40 | #endif 41 | 42 | #ifndef AX_WEB_VIEW_CONTROLLER_AVAILABLITY 43 | #define AX_WEB_VIEW_CONTROLLER_AVAILABLITY BOOL AX_WEB_VIEW_CONTROLLER_iOS8_0_AVAILABLE(void);\ 44 | BOOL AX_WEB_VIEW_CONTROLLER_iOS9_0_AVAILABLE(void);\ 45 | BOOL AX_WEB_VIEW_CONTROLLER_iOS10_0_AVAILABLE(void); 46 | #endif 47 | 48 | #import 49 | #import 50 | #import 51 | #if AX_WEB_VIEW_CONTROLLER_USING_WEBKIT 52 | #import 53 | #import "AXSecurityPolicy.h" 54 | #endif 55 | #ifndef AX_REQUIRES_SUPER 56 | #if __has_attribute(objc_requires_super) 57 | #define AX_REQUIRES_SUPER __attribute__((objc_requires_super)) 58 | #else 59 | #define AX_REQUIRES_SUPER 60 | #endif 61 | #endif 62 | /* 63 | http://www.dudas.co.uk/ns_requires_super/: 64 | -- 65 | __attribute((objc_requires_super)) was first introduced as work in progress into CLANG in September 2012 and was documented in October 2013. On both OS X and iOS there is now a NS_REQUIRES_SUPER macro that conditionally wraps the objc_requires_super attribute depending on compiler support. Once a method declaration is appended with this macro, the compiler will produce a warning if super is not called by a subclass overriding the method. 66 | */ 67 | 68 | NS_ASSUME_NONNULL_BEGIN 69 | @class AXWebViewController; 70 | 71 | typedef NS_ENUM(NSInteger, AXWebViewControllerNavigationType) { 72 | /// Navigation bar items. 73 | AXWebViewControllerNavigationBarItem, 74 | /// Tool bar items. 75 | AXWebViewControllerNavigationToolItem 76 | }; 77 | 78 | @protocol AXWebViewControllerDelegate 79 | @optional 80 | /// Called when web view will go back. 81 | /// 82 | /// @param webViewController a web view controller. 83 | - (void)webViewControllerWillGoBack:(AXWebViewController *)webViewController; 84 | /// Called when web view will go forward. 85 | /// 86 | /// @param webViewController a web view controller. 87 | - (void)webViewControllerWillGoForward:(AXWebViewController *)webViewController; 88 | /// Called when web view will reload. 89 | /// 90 | /// @param webViewController a web view controller. 91 | - (void)webViewControllerWillReload:(AXWebViewController *)webViewController; 92 | /// Called when web view will stop load. 93 | /// 94 | /// @param webViewController a web view controller. 95 | - (void)webViewControllerWillStop:(AXWebViewController *)webViewController; 96 | /// Called when web view did start loading. 97 | /// 98 | /// @param webViewController a web view controller. 99 | - (void)webViewControllerDidStartLoad:(AXWebViewController *)webViewController; 100 | /// Called when web view did finish loading. 101 | /// 102 | /// @param webViewController a web view controller. 103 | - (void)webViewControllerDidFinishLoad:(AXWebViewController *)webViewController; 104 | /// Called when web viw did fail loading. 105 | /// 106 | /// @param webViewController a web view controller. 107 | /// 108 | /// @param error a failed loading error. 109 | - (void)webViewController:(AXWebViewController *)webViewController didFailLoadWithError:(NSError *)error; 110 | @end 111 | 112 | AX_WEB_VIEW_CONTROLLER_AVAILABLITY; 113 | 114 | #if AX_WEB_VIEW_CONTROLLER_USING_WEBKIT 115 | typedef NSURLSessionAuthChallengeDisposition (^WKWebViewDidReceiveAuthenticationChallengeHandler)(WKWebView *webView, NSURLAuthenticationChallenge *challenge, NSURLCredential * _Nullable __autoreleasing * _Nullable credential); 116 | API_AVAILABLE(ios(8.0)) 117 | @interface AXWebViewController : UIViewController 118 | { 119 | @protected 120 | WKWebView *_webView; 121 | NSURL *_URL; 122 | } 123 | #else 124 | API_AVAILABLE(ios(7.0)) 125 | @interface AXWebViewController : UIViewController 126 | { 127 | @protected 128 | UIWebView *_webView; 129 | NSURL *_URL; 130 | } 131 | #endif 132 | /// Delegate. 133 | @property(assign, nonatomic) iddelegate; 134 | #if AX_WEB_VIEW_CONTROLLER_USING_WEBKIT 135 | /// WebKit web view. 136 | @property(readonly, nonatomic) WKWebView *webView; 137 | #else 138 | /// Web view. 139 | @property(readonly, nonatomic) UIWebView *webView; 140 | #endif 141 | #if AX_WEB_VIEW_CONTROLLER_USING_WEBKIT 142 | /// Default is NO. Enabled to allow present alert views. 143 | @property(assign, nonatomic) BOOL enabledWebViewUIDelegate; 144 | #endif 145 | /// Open app link in app store app. Default is NO. 146 | @property(assign, nonatomic) BOOL reviewsAppInAppStore; 147 | /// Max length of title string content. Default is 10. 148 | @property(assign, nonatomic) NSUInteger maxAllowedTitleLength; 149 | /// Time out internal. 150 | @property(assign, nonatomic) NSTimeInterval timeoutInternal; 151 | /// Cache policy. 152 | @property(assign, nonatomic) NSURLRequestCachePolicy cachePolicy; 153 | /// The based initialized url of the web view controller if any. 154 | @property(readonly, nonatomic) NSURL *URL; 155 | /// Shows tool bar. Default is YES. 156 | @property(assign, nonatomic) BOOL showsToolBar; 157 | /// Shows background description label. Default is YES. 158 | @property(assign, nonatomic) BOOL showsBackgroundLabel; 159 | /// Shows navigation close bar button item. Default is YES. 160 | @property(assign, nonatomic) BOOL showsNavigationCloseBarButtonItem; 161 | /// Shows the title of navigation back bar button item. Default is YES. 162 | @property(assign, nonatomic) BOOL showsNavigationBackBarButtonItemTitle; 163 | /// Check url can open default YES, only work after iOS 8. 164 | @property(assign, nonatomic) BOOL checkUrlCanOpen API_AVAILABLE(ios(8.0)); 165 | /// Navigation type. 166 | @property(assign, nonatomic) AXWebViewControllerNavigationType navigationType; 167 | /// Navigation close bar button item. 168 | @property(readwrite, nonatomic) UIBarButtonItem *navigationCloseItem; 169 | /// Get a instance of `AXWebViewController` by a url string. 170 | /// 171 | /// @param urlString a string of url to be loaded. 172 | /// 173 | /// @return a instance `AXWebViewController`. 174 | - (instancetype)initWithAddress:(NSString*)urlString; 175 | /// Get a instance of `AXWebViewController` by a url. 176 | /// 177 | /// @param URL a URL to be loaded. 178 | /// 179 | /// @return a instance of `AXWebViewController`. 180 | - (instancetype)initWithURL:(NSURL*)URL; 181 | /// Get a instance of `AXWebViewController` by a url request. 182 | /// 183 | /// @param request a URL request to be loaded. 184 | /// 185 | /// @return a instance of `AXWebViewController`. 186 | - (instancetype)initWithRequest:(NSURLRequest *)request; 187 | #if AX_WEB_VIEW_CONTROLLER_USING_WEBKIT 188 | /// Get a instance of `AXWebViewController` by a url and configuration of web view. 189 | /// 190 | /// @param URL a URL to be loaded. 191 | /// @param configuration configuration instance of WKWebViewConfiguration to create web view. 192 | /// 193 | /// @return a instance of `AXWebViewController`. 194 | - (instancetype)initWithURL:(NSURL *)URL configuration:(WKWebViewConfiguration *)configuration; 195 | /// Get a instance of `AXWebViewController` by a request and configuration of web view. 196 | /// 197 | /// @param request a URL request to be loaded. 198 | /// @param configuration configuration instance of WKWebViewConfiguration to create web view. 199 | /// 200 | /// @return a instance of `AXWebViewController`. 201 | - (instancetype)initWithRequest:(NSURLRequest *)request configuration:(WKWebViewConfiguration *)configuration; 202 | #endif 203 | /// Get a instance of `AXWebViewController` by a HTML string and a base URL. 204 | /// 205 | /// @param HTMLString a HTML string object. 206 | /// @param baseURL a baseURL to be loaded. 207 | /// 208 | /// @return a instance of `AXWebViewController`. 209 | - (instancetype)initWithHTMLString:(NSString *)HTMLString baseURL:(NSURL * _Nullable)baseURL; 210 | /// Load a new url. 211 | /// 212 | /// @param URL a new url. 213 | - (void)loadURL:(NSURL*)URL; 214 | /// Load a new html string. 215 | /// 216 | /// @param HTMLString a encoded html string. 217 | /// @param baseURL base url of bundle. 218 | - (void)loadHTMLString:(NSString *)HTMLString baseURL:(NSURL *)baseURL; 219 | @end 220 | 221 | @interface AXWebViewController (SubclassingHooks) 222 | /// Called when web view will go back. Do not call this directly. Same to the bottom methods. 223 | /// @discussion 使用的时候需要子类化,并且调用super的方法!切记!!! 224 | /// 225 | - (void)willGoBack AX_REQUIRES_SUPER; 226 | /// Called when web view will go forward. Do not call this directly. 227 | /// 228 | - (void)willGoForward AX_REQUIRES_SUPER; 229 | /// Called when web view will reload. Do not call this directly. 230 | /// 231 | - (void)willReload AX_REQUIRES_SUPER; 232 | /// Called when web view will stop load. Do not call this directly. 233 | /// 234 | - (void)willStop AX_REQUIRES_SUPER; 235 | /// Called when web view did start loading. Do not call this directly. 236 | /// 237 | - (void)didStartLoad AX_REQUIRES_SUPER NS_DEPRECATED_IOS(2_0, 8_0); 238 | #if AX_WEB_VIEW_CONTROLLER_USING_WEBKIT 239 | /// Called when web view(WKWebView) did start loading. Do not call this directly. 240 | /// 241 | /// @param navigation Navigation object of the current request info. 242 | - (void)didStartLoadWithNavigation:(WKNavigation *)navigation AX_REQUIRES_SUPER NS_AVAILABLE(10_10, 8_0); 243 | #endif 244 | /// Called when web view did finish loading. Do not call this directly. 245 | /// 246 | - (void)didFinishLoad AX_REQUIRES_SUPER; 247 | /// Called when web viw did fail loading. Do not call this directly. 248 | /// 249 | /// @param error a failed loading error. 250 | - (void)didFailLoadWithError:(NSError *)error AX_REQUIRES_SUPER; 251 | @end 252 | 253 | /** 254 | WebCache clearing. 255 | */ 256 | @interface AXWebViewController (WebCache) 257 | /// Clear cache data of web view. 258 | /// 259 | /// @param completion completion block. 260 | + (void)clearWebCacheCompletion:(dispatch_block_t _Nullable)completion; 261 | @end 262 | 263 | /** 264 | Accessibility to background label. 265 | */ 266 | @interface AXWebViewController (BackgroundLabel) 267 | /// Description label of web content's info. 268 | /// 269 | @property(readonly, nonatomic) UILabel *descriptionLabel; 270 | @end 271 | 272 | #if AX_WEB_VIEW_CONTROLLER_USING_WEBKIT 273 | @interface AXWebViewController (Security) 274 | /// Challenge handler for the credential. 275 | @property(copy, nonatomic, nullable) WKWebViewDidReceiveAuthenticationChallengeHandler challengeHandler; 276 | /// The security policy used by created session to evaluate server trust for secure connections. 277 | /// `AXWebViewController` uses the `defaultPolicy` unless otherwise specified. 278 | @property(readwrite, nonatomic, nullable) AXSecurityPolicy *securityPolicy; 279 | @end 280 | #endif 281 | NS_ASSUME_NONNULL_END 282 | -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/Activity/AXWebViewControllerActivity.h: -------------------------------------------------------------------------------- 1 | // 2 | // AXWebViewControllerActivity.h 3 | // AXWebViewController 4 | // 5 | // Created by ai on 15/12/23. 6 | // Copyright © 2015年 devedbox. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in all 16 | // copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | // SOFTWARE. 25 | 26 | #import 27 | 28 | 29 | @interface AXWebViewControllerActivity : UIActivity 30 | /// URL to open. 31 | @property (nonatomic, strong) NSURL *URL; 32 | /// Scheme prefix value. 33 | @property (nonatomic, strong) NSString *scheme; 34 | @end 35 | 36 | @interface AXWebViewControllerActivityChrome : AXWebViewControllerActivity @end 37 | @interface AXWebViewControllerActivitySafari : AXWebViewControllerActivity @end 38 | -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/Activity/AXWebViewControllerActivity.m: -------------------------------------------------------------------------------- 1 | // 2 | // AXWebViewControllerActivity.m 3 | // AXWebViewController 4 | // 5 | // Created by ai on 15/12/23. 6 | // Copyright © 2015年 devedbox. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in all 16 | // copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | // SOFTWARE. 25 | 26 | #import "AXWebViewControllerActivity.h" 27 | 28 | @implementation AXWebViewControllerActivity 29 | - (NSString *)activityType { 30 | return NSStringFromClass([self class]); 31 | } 32 | 33 | - (UIImage *)activityImage { 34 | NSBundle *bundle = [NSBundle bundleForClass:[self class]]; 35 | 36 | NSString *resourcePath = [bundle pathForResource:@"AXWebViewController" ofType:@"bundle"] ; 37 | 38 | if (resourcePath){ 39 | NSBundle *bundle2 = [NSBundle bundleWithPath:resourcePath]; 40 | if (bundle2){ 41 | bundle = bundle2; 42 | } 43 | } 44 | 45 | if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) 46 | return [UIImage imageNamed:[self.activityType stringByAppendingString:@"-iPad"] inBundle:bundle compatibleWithTraitCollection:nil]; 47 | 48 | else 49 | return [UIImage imageNamed:self.activityType inBundle:bundle compatibleWithTraitCollection:nil]; 50 | } 51 | 52 | - (void)prepareWithActivityItems:(NSArray *)activityItems { 53 | for (id activityItem in activityItems) { 54 | if ([activityItem isKindOfClass:[NSURL class]]) { 55 | self.URL = activityItem; 56 | } 57 | } 58 | } 59 | @end 60 | 61 | @implementation AXWebViewControllerActivityChrome 62 | - (NSString *)schemePrefix { 63 | return @"googlechrome://"; 64 | } 65 | 66 | - (NSString *)activityTitle { 67 | NSBundle *bundle = [NSBundle bundleForClass:[self class]]; 68 | 69 | NSString *resourcePath = [bundle pathForResource:@"AXWebViewController" ofType:@"bundle"] ; 70 | 71 | if (resourcePath){ 72 | NSBundle *bundle2 = [NSBundle bundleWithPath:resourcePath]; 73 | if (bundle2){ 74 | bundle = bundle2; 75 | } 76 | } 77 | 78 | return NSLocalizedStringFromTableInBundle(@"OpenInChrome", @"AXWebViewController", bundle, @"Open in Chrome"); 79 | 80 | } 81 | 82 | - (BOOL)canPerformWithActivityItems:(NSArray *)activityItems { 83 | for (id activityItem in activityItems) { 84 | if ([activityItem isKindOfClass:[NSURL class]] && [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:self.schemePrefix]]) { 85 | return YES; 86 | } 87 | } 88 | return NO; 89 | } 90 | 91 | - (void)performActivity { 92 | NSString *openingURL; 93 | if (@available(iOS 9.0, *)) { 94 | openingURL = [self.URL.absoluteString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; 95 | } else { 96 | #pragma clang diagnostic push 97 | #pragma clang diagnostic ignored "-Wdeprecated-declarations" 98 | openingURL = [self.URL.absoluteString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 99 | #pragma clang diagnostic pop 100 | } 101 | 102 | NSURL *activityURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@", self.schemePrefix, openingURL]]; 103 | 104 | if (@available(iOS 10.0, *)) { 105 | [[UIApplication sharedApplication] openURL:activityURL options:@{} completionHandler:NULL]; 106 | } else { 107 | [[UIApplication sharedApplication] openURL:activityURL]; 108 | } 109 | 110 | [self activityDidFinish:YES]; 111 | } 112 | @end 113 | 114 | @implementation AXWebViewControllerActivitySafari 115 | - (NSString *)activityTitle { 116 | 117 | NSBundle *bundle = [NSBundle bundleForClass:[self class]]; 118 | 119 | NSString *resourcePath = [bundle pathForResource:@"AXWebViewController" ofType:@"bundle"] ; 120 | 121 | if (resourcePath){ 122 | NSBundle *bundle2 = [NSBundle bundleWithPath:resourcePath]; 123 | if (bundle2){ 124 | bundle = bundle2; 125 | } 126 | } 127 | 128 | return NSLocalizedStringFromTableInBundle(@"OpenInSafari", @"AXWebViewController", bundle, @"Open in Safari"); 129 | } 130 | 131 | - (BOOL)canPerformWithActivityItems:(NSArray *)activityItems { 132 | for (id activityItem in activityItems) { 133 | if ([activityItem isKindOfClass:[NSURL class]] && [[UIApplication sharedApplication] canOpenURL:activityItem]) { 134 | return YES; 135 | } 136 | } 137 | return NO; 138 | } 139 | 140 | - (void)performActivity { 141 | BOOL completed = [[UIApplication sharedApplication] openURL:self.URL]; 142 | [self activityDidFinish:completed]; 143 | } 144 | @end 145 | -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/Security/AXSecurityPolicy.h: -------------------------------------------------------------------------------- 1 | // AXSecurityPolicy.h 2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | // THE SOFTWARE. 21 | 22 | #import 23 | #import 24 | 25 | typedef NS_ENUM(NSUInteger, AXSSLPinningMode) { 26 | AXSSLPinningModeNone, 27 | AXSSLPinningModePublicKey, 28 | AXSSLPinningModeCertificate, 29 | }; 30 | 31 | /** 32 | `AXSecurityPolicy` evaluates server trust against pinned X.509 certificates and public keys over secure connections. 33 | 34 | Adding pinned SSL certificates to your app helps prevent man-in-the-middle attacks and other vulnerabilities. Applications dealing with sensitive customer data or financial information are strongly encouraged to route all communication over an HTTPS connection with SSL pinning configured and enabled. 35 | */ 36 | 37 | NS_ASSUME_NONNULL_BEGIN 38 | 39 | @interface AXSecurityPolicy : NSObject 40 | 41 | /** 42 | The criteria by which server trust should be evaluated against the pinned SSL certificates. Defaults to `AXSSLPinningModeNone`. 43 | */ 44 | @property (readonly, nonatomic, assign) AXSSLPinningMode SSLPinningMode; 45 | 46 | /** 47 | The certificates used to evaluate server trust according to the SSL pinning mode. 48 | 49 | By default, this property is set to any (`.cer`) certificates included in the target compiling AXNetworking. Note that if you are using AXNetworking as embedded framework, no certificates will be pinned by default. Use `certificatesInBundle` to load certificates from your target, and then create a new policy by calling `policyWithPinningMode:withPinnedCertificates`. 50 | 51 | Note that if pinning is enabled, `evaluateServerTrust:forDomain:` will return true if any pinned certificate matches. 52 | */ 53 | @property (nonatomic, strong, nullable) NSSet *pinnedCertificates; 54 | 55 | /** 56 | Whether or not to trust servers with an invalid or expired SSL certificates. Defaults to `NO`. 57 | */ 58 | @property (nonatomic, assign) BOOL allowInvalidCertificates; 59 | 60 | /** 61 | Whether or not to validate the domain name in the certificate's CN field. Defaults to `YES`. 62 | */ 63 | @property (nonatomic, assign) BOOL validatesDomainName; 64 | 65 | ///----------------------------------------- 66 | /// @name Getting Certificates from the Bundle 67 | ///----------------------------------------- 68 | 69 | /** 70 | Returns any certificates included in the bundle. If you are using AXNetworking as an embedded framework, you must use this method to find the certificates you have included in your app bundle, and use them when creating your security policy by calling `policyWithPinningMode:withPinnedCertificates`. 71 | 72 | @return The certificates included in the given bundle. 73 | */ 74 | + (NSSet *)certificatesInBundle:(NSBundle *)bundle; 75 | 76 | ///----------------------------------------- 77 | /// @name Getting Specific Security Policies 78 | ///----------------------------------------- 79 | 80 | /** 81 | Returns the shared default security policy, which does not allow invalid certificates, validates domain name, and does not validate against pinned certificates or public keys. 82 | 83 | @return The default security policy. 84 | */ 85 | + (instancetype)defaultPolicy; 86 | 87 | ///--------------------- 88 | /// @name Initialization 89 | ///--------------------- 90 | 91 | /** 92 | Creates and returns a security policy with the specified pinning mode. 93 | 94 | @param pinningMode The SSL pinning mode. 95 | 96 | @return A new security policy. 97 | */ 98 | + (instancetype)policyWithPinningMode:(AXSSLPinningMode)pinningMode; 99 | 100 | /** 101 | Creates and returns a security policy with the specified pinning mode. 102 | 103 | @param pinningMode The SSL pinning mode. 104 | @param pinnedCertificates The certificates to pin against. 105 | 106 | @return A new security policy. 107 | */ 108 | + (instancetype)policyWithPinningMode:(AXSSLPinningMode)pinningMode withPinnedCertificates:(NSSet *)pinnedCertificates; 109 | 110 | ///------------------------------ 111 | /// @name Evaluating Server Trust 112 | ///------------------------------ 113 | 114 | /** 115 | Whether or not the specified server trust should be accepted, based on the security policy. 116 | 117 | This method should be used when responding to an authentication challenge from a server. 118 | 119 | @param serverTrust The X.509 certificate trust of the server. 120 | @param domain The domain of serverTrust. If `nil`, the domain will not be validated. 121 | 122 | @return Whether or not to trust the server. 123 | */ 124 | - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust 125 | forDomain:(nullable NSString *)domain; 126 | 127 | @end 128 | 129 | NS_ASSUME_NONNULL_END 130 | 131 | ///---------------- 132 | /// @name Constants 133 | ///---------------- 134 | 135 | /** 136 | ## SSL Pinning Modes 137 | 138 | The following constants are provided by `AXSSLPinningMode` as possible SSL pinning modes. 139 | 140 | enum { 141 | AXSSLPinningModeNone, 142 | AXSSLPinningModePublicKey, 143 | AXSSLPinningModeCertificate, 144 | } 145 | 146 | `AXSSLPinningModeNone` 147 | Do not used pinned certificates to validate servers. 148 | 149 | `AXSSLPinningModePublicKey` 150 | Validate host certificates against public keys of pinned certificates. 151 | 152 | `AXSSLPinningModeCertificate` 153 | Validate host certificates against pinned certificates. 154 | */ 155 | -------------------------------------------------------------------------------- /AXWebViewController/AXWebViewController/Security/AXSecurityPolicy.m: -------------------------------------------------------------------------------- 1 | // AXSecurityPolicy.m 2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | // THE SOFTWARE. 21 | 22 | #import "AXSecurityPolicy.h" 23 | 24 | #import 25 | 26 | #if !TARGET_OS_IOS && !TARGET_OS_WATCH && !TARGET_OS_TV 27 | static NSData * AXSecKeyGetData(SecKeyRef key) { 28 | CFDataRef data = NULL; 29 | 30 | __Require_noErr_Quiet(SecItemExport(key, kSecFormatUnknown, kSecItemPemArmour, NULL, &data), _out); 31 | 32 | return (__bridge_transfer NSData *)data; 33 | 34 | _out: 35 | if (data) { 36 | CFRelease(data); 37 | } 38 | 39 | return nil; 40 | } 41 | #endif 42 | 43 | static BOOL AXSecKeyIsEqualToKey(SecKeyRef key1, SecKeyRef key2) { 44 | #if TARGET_OS_IOS || TARGET_OS_WATCH || TARGET_OS_TV 45 | return [(__bridge id)key1 isEqual:(__bridge id)key2]; 46 | #else 47 | return [AXSecKeyGetData(key1) isEqual:AXSecKeyGetData(key2)]; 48 | #endif 49 | } 50 | 51 | static id AXPublicKeyForCertificate(NSData *certificate) { 52 | id allowedPublicKey = nil; 53 | SecCertificateRef allowedCertificate; 54 | SecCertificateRef allowedCertificates[1]; 55 | CFArrayRef tempCertificates = nil; 56 | SecPolicyRef policy = nil; 57 | SecTrustRef allowedTrust = nil; 58 | SecTrustResultType result; 59 | 60 | allowedCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificate); 61 | __Require_Quiet(allowedCertificate != NULL, _out); 62 | 63 | allowedCertificates[0] = allowedCertificate; 64 | tempCertificates = CFArrayCreate(NULL, (const void **)allowedCertificates, 1, NULL); 65 | 66 | policy = SecPolicyCreateBasicX509(); 67 | __Require_noErr_Quiet(SecTrustCreateWithCertificates(tempCertificates, policy, &allowedTrust), _out); 68 | __Require_noErr_Quiet(SecTrustEvaluate(allowedTrust, &result), _out); 69 | 70 | allowedPublicKey = (__bridge_transfer id)SecTrustCopyPublicKey(allowedTrust); 71 | 72 | _out: 73 | if (allowedTrust) { 74 | CFRelease(allowedTrust); 75 | } 76 | 77 | if (policy) { 78 | CFRelease(policy); 79 | } 80 | 81 | if (tempCertificates) { 82 | CFRelease(tempCertificates); 83 | } 84 | 85 | if (allowedCertificate) { 86 | CFRelease(allowedCertificate); 87 | } 88 | 89 | return allowedPublicKey; 90 | } 91 | 92 | static BOOL AXServerTrustIsValid(SecTrustRef serverTrust) { 93 | BOOL isValid = NO; 94 | SecTrustResultType result; 95 | __Require_noErr_Quiet(SecTrustEvaluate(serverTrust, &result), _out); 96 | 97 | isValid = (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed); 98 | 99 | _out: 100 | return isValid; 101 | } 102 | 103 | static NSArray * AXCertificateTrustChainForServerTrust(SecTrustRef serverTrust) { 104 | CFIndex certificateCount = SecTrustGetCertificateCount(serverTrust); 105 | NSMutableArray *trustChain = [NSMutableArray arrayWithCapacity:(NSUInteger)certificateCount]; 106 | 107 | for (CFIndex i = 0; i < certificateCount; i++) { 108 | SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, i); 109 | [trustChain addObject:(__bridge_transfer NSData *)SecCertificateCopyData(certificate)]; 110 | } 111 | 112 | return [NSArray arrayWithArray:trustChain]; 113 | } 114 | 115 | static NSArray * AXPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) { 116 | SecPolicyRef policy = SecPolicyCreateBasicX509(); 117 | CFIndex certificateCount = SecTrustGetCertificateCount(serverTrust); 118 | NSMutableArray *trustChain = [NSMutableArray arrayWithCapacity:(NSUInteger)certificateCount]; 119 | for (CFIndex i = 0; i < certificateCount; i++) { 120 | SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, i); 121 | 122 | SecCertificateRef someCertificates[] = {certificate}; 123 | CFArrayRef certificates = CFArrayCreate(NULL, (const void **)someCertificates, 1, NULL); 124 | 125 | SecTrustRef trust; 126 | __Require_noErr_Quiet(SecTrustCreateWithCertificates(certificates, policy, &trust), _out); 127 | 128 | SecTrustResultType result; 129 | __Require_noErr_Quiet(SecTrustEvaluate(trust, &result), _out); 130 | 131 | [trustChain addObject:(__bridge_transfer id)SecTrustCopyPublicKey(trust)]; 132 | 133 | _out: 134 | if (trust) { 135 | CFRelease(trust); 136 | } 137 | 138 | if (certificates) { 139 | CFRelease(certificates); 140 | } 141 | 142 | continue; 143 | } 144 | CFRelease(policy); 145 | 146 | return [NSArray arrayWithArray:trustChain]; 147 | } 148 | 149 | #pragma mark - 150 | 151 | @interface AXSecurityPolicy() 152 | @property (readwrite, nonatomic, assign) AXSSLPinningMode SSLPinningMode; 153 | @property (readwrite, nonatomic, strong) NSSet *pinnedPublicKeys; 154 | @end 155 | 156 | @implementation AXSecurityPolicy 157 | 158 | + (NSSet *)certificatesInBundle:(NSBundle *)bundle { 159 | NSArray *paths = [bundle pathsForResourcesOfType:@"cer" inDirectory:@"."]; 160 | 161 | NSMutableSet *certificates = [NSMutableSet setWithCapacity:[paths count]]; 162 | for (NSString *path in paths) { 163 | NSData *certificateData = [NSData dataWithContentsOfFile:path]; 164 | [certificates addObject:certificateData]; 165 | } 166 | 167 | return [NSSet setWithSet:certificates]; 168 | } 169 | 170 | + (NSSet *)defaultPinnedCertificates { 171 | static NSSet *_defaultPinnedCertificates = nil; 172 | static dispatch_once_t onceToken; 173 | dispatch_once(&onceToken, ^{ 174 | NSBundle *bundle = [NSBundle bundleForClass:[self class]]; 175 | _defaultPinnedCertificates = [self certificatesInBundle:bundle]; 176 | }); 177 | 178 | return _defaultPinnedCertificates; 179 | } 180 | 181 | + (instancetype)defaultPolicy { 182 | AXSecurityPolicy *securityPolicy = [[self alloc] init]; 183 | securityPolicy.SSLPinningMode = AXSSLPinningModeNone; 184 | 185 | return securityPolicy; 186 | } 187 | 188 | + (instancetype)policyWithPinningMode:(AXSSLPinningMode)pinningMode { 189 | return [self policyWithPinningMode:pinningMode withPinnedCertificates:[self defaultPinnedCertificates]]; 190 | } 191 | 192 | + (instancetype)policyWithPinningMode:(AXSSLPinningMode)pinningMode withPinnedCertificates:(NSSet *)pinnedCertificates { 193 | AXSecurityPolicy *securityPolicy = [[self alloc] init]; 194 | securityPolicy.SSLPinningMode = pinningMode; 195 | 196 | [securityPolicy setPinnedCertificates:pinnedCertificates]; 197 | 198 | return securityPolicy; 199 | } 200 | 201 | - (instancetype)init { 202 | self = [super init]; 203 | if (!self) { 204 | return nil; 205 | } 206 | 207 | self.validatesDomainName = YES; 208 | 209 | return self; 210 | } 211 | 212 | - (void)setPinnedCertificates:(NSSet *)pinnedCertificates { 213 | _pinnedCertificates = pinnedCertificates; 214 | 215 | if (self.pinnedCertificates) { 216 | NSMutableSet *mutablePinnedPublicKeys = [NSMutableSet setWithCapacity:[self.pinnedCertificates count]]; 217 | for (NSData *certificate in self.pinnedCertificates) { 218 | id publicKey = AXPublicKeyForCertificate(certificate); 219 | if (!publicKey) { 220 | continue; 221 | } 222 | [mutablePinnedPublicKeys addObject:publicKey]; 223 | } 224 | self.pinnedPublicKeys = [NSSet setWithSet:mutablePinnedPublicKeys]; 225 | } else { 226 | self.pinnedPublicKeys = nil; 227 | } 228 | } 229 | 230 | #pragma mark - 231 | 232 | - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust 233 | forDomain:(NSString *)domain 234 | { 235 | if (domain && self.allowInvalidCertificates && self.validatesDomainName && (self.SSLPinningMode == AXSSLPinningModeNone || [self.pinnedCertificates count] == 0)) { 236 | // https://developer.apple.com/library/mac/documentation/NetworkingInternet/Conceptual/NetworkingTopics/Articles/OverridingSSLChainValidationCorrectly.html 237 | // According to the docs, you should only trust your provided certs for evaluation. 238 | // Pinned certificates are added to the trust. Without pinned certificates, 239 | // there is nothing to evaluate against. 240 | // 241 | // From Apple Docs: 242 | // "Do not implicitly trust self-signed certificates as anchors (kSecTrustOptionImplicitAnchors). 243 | // Instead, add your own (self-signed) CA certificate to the list of trusted anchors." 244 | NSLog(@"In order to validate a domain name for self signed certificates, you MUST use pinning."); 245 | return NO; 246 | } 247 | 248 | NSMutableArray *policies = [NSMutableArray array]; 249 | if (self.validatesDomainName) { 250 | [policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)domain)]; 251 | } else { 252 | [policies addObject:(__bridge_transfer id)SecPolicyCreateBasicX509()]; 253 | } 254 | 255 | SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies); 256 | 257 | if (self.SSLPinningMode == AXSSLPinningModeNone) { 258 | return self.allowInvalidCertificates || AXServerTrustIsValid(serverTrust); 259 | } else if (!AXServerTrustIsValid(serverTrust) && !self.allowInvalidCertificates) { 260 | return NO; 261 | } 262 | 263 | switch (self.SSLPinningMode) { 264 | case AXSSLPinningModeNone: 265 | default: 266 | return NO; 267 | case AXSSLPinningModeCertificate: { 268 | NSMutableArray *pinnedCertificates = [NSMutableArray array]; 269 | for (NSData *certificateData in self.pinnedCertificates) { 270 | [pinnedCertificates addObject:(__bridge_transfer id)SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificateData)]; 271 | } 272 | SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)pinnedCertificates); 273 | 274 | if (!AXServerTrustIsValid(serverTrust)) { 275 | return NO; 276 | } 277 | 278 | // obtain the chain AXter being validated, which *should* contain the pinned certificate in the last position (if it's the Root CA) 279 | NSArray *serverCertificates = AXCertificateTrustChainForServerTrust(serverTrust); 280 | 281 | for (NSData *trustChainCertificate in [serverCertificates reverseObjectEnumerator]) { 282 | if ([self.pinnedCertificates containsObject:trustChainCertificate]) { 283 | return YES; 284 | } 285 | } 286 | 287 | return NO; 288 | } 289 | case AXSSLPinningModePublicKey: { 290 | NSUInteger trustedPublicKeyCount = 0; 291 | NSArray *publicKeys = AXPublicKeyTrustChainForServerTrust(serverTrust); 292 | 293 | for (id trustChainPublicKey in publicKeys) { 294 | for (id pinnedPublicKey in self.pinnedPublicKeys) { 295 | if (AXSecKeyIsEqualToKey((__bridge SecKeyRef)trustChainPublicKey, (__bridge SecKeyRef)pinnedPublicKey)) { 296 | trustedPublicKeyCount += 1; 297 | } 298 | } 299 | } 300 | return trustedPublicKeyCount > 0; 301 | } 302 | } 303 | 304 | return NO; 305 | } 306 | 307 | #pragma mark - NSKeyValueObserving 308 | 309 | + (NSSet *)keyPathsForValuesAXfectingPinnedPublicKeys { 310 | return [NSSet setWithObject:@"pinnedCertificates"]; 311 | } 312 | 313 | #pragma mark - NSSecureCoding 314 | 315 | + (BOOL)supportsSecureCoding { 316 | return YES; 317 | } 318 | 319 | - (instancetype)initWithCoder:(NSCoder *)decoder { 320 | 321 | self = [self init]; 322 | if (!self) { 323 | return nil; 324 | } 325 | 326 | self.SSLPinningMode = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(SSLPinningMode))] unsignedIntegerValue]; 327 | self.allowInvalidCertificates = [decoder decodeBoolForKey:NSStringFromSelector(@selector(allowInvalidCertificates))]; 328 | self.validatesDomainName = [decoder decodeBoolForKey:NSStringFromSelector(@selector(validatesDomainName))]; 329 | self.pinnedCertificates = [decoder decodeObjectOfClass:[NSArray class] forKey:NSStringFromSelector(@selector(pinnedCertificates))]; 330 | 331 | return self; 332 | } 333 | 334 | - (void)encodeWithCoder:(NSCoder *)coder { 335 | [coder encodeObject:[NSNumber numberWithUnsignedInteger:self.SSLPinningMode] forKey:NSStringFromSelector(@selector(SSLPinningMode))]; 336 | [coder encodeBool:self.allowInvalidCertificates forKey:NSStringFromSelector(@selector(allowInvalidCertificates))]; 337 | [coder encodeBool:self.validatesDomainName forKey:NSStringFromSelector(@selector(validatesDomainName))]; 338 | [coder encodeObject:self.pinnedCertificates forKey:NSStringFromSelector(@selector(pinnedCertificates))]; 339 | } 340 | 341 | #pragma mark - NSCopying 342 | 343 | - (instancetype)copyWithZone:(NSZone *)zone { 344 | AXSecurityPolicy *securityPolicy = [[[self class] allocWithZone:zone] init]; 345 | securityPolicy.SSLPinningMode = self.SSLPinningMode; 346 | securityPolicy.allowInvalidCertificates = self.allowInvalidCertificates; 347 | securityPolicy.validatesDomainName = self.validatesDomainName; 348 | securityPolicy.pinnedCertificates = [self.pinnedCertificates copyWithZone:zone]; 349 | 350 | return securityPolicy; 351 | } 352 | 353 | @end 354 | -------------------------------------------------------------------------------- /AXWebViewController/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // AXWebViewController 4 | // 5 | // Created by ai on 15/12/22. 6 | // Copyright © 2015年 AiXing. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | @interface UIApplication (Test) 19 | 20 | @end -------------------------------------------------------------------------------- /AXWebViewController/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // AXWebViewController 4 | // 5 | // Created by ai on 15/12/22. 6 | // Copyright © 2015年 AiXing. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import 11 | // #import "AXWebViewController.h" 12 | 13 | @interface AppDelegate () 14 | 15 | @end 16 | 17 | @implementation AppDelegate 18 | 19 | 20 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 21 | // Override point for customization after application launch. 22 | [[UINavigationBar appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor colorWithRed:0.322 green:0.322 blue:0.322 alpha:1.00],NSForegroundColorAttributeName,[UIFont boldSystemFontOfSize:16],NSFontAttributeName, nil]]; //Nav文字属性 23 | [[UINavigationBar appearance] setTintColor:[UIColor colorWithRed:0.322 green:0.322 blue:0.322 alpha:1.00]]; 24 | [[UIBarButtonItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor colorWithRed:0.322 green:0.322 blue:0.322 alpha:1.00],NSForegroundColorAttributeName, [UIFont systemFontOfSize:14],NSFontAttributeName , nil] forState:0]; 25 | [[UIBarButtonItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIFont systemFontOfSize:14],NSFontAttributeName , nil] forState:UIControlStateHighlighted]; 26 | [[UINavigationBar appearance] setBackIndicatorImage:[UIImage imageNamed:@"back_indicator"]]; 27 | [[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"back_indicator"]]; 28 | if (@available(iOS 11.0, *)) { 29 | [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(-2.0, -0.4) forBarMetrics:UIBarMetricsDefault]; 30 | } else { 31 | [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -2) forBarMetrics:UIBarMetricsDefault]; 32 | } 33 | /* 34 | NSBundle *bundle = [NSBundle bundleForClass:NSClassFromString(@"AXWebViewController")]; 35 | NSString *bundlePath = [bundle pathForResource:@"AXWebViewController.bundle/html.bundle/404" ofType:@"html"]; 36 | */ 37 | /* 38 | AXWebViewController *webVC = [[AXWebViewController alloc] initWithAddress:@"https://www.baidu.com"]; 39 | webVC.showsToolBar = NO; 40 | webVC.webView.allowsLinkPreview = YES; 41 | webVC.navigationType = AXWebViewControllerNavigationBarItem; 42 | UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:webVC]; 43 | self.window = [[UIWindow alloc] init]; 44 | self.window.backgroundColor = [UIColor whiteColor]; 45 | self.window.frame = [UIScreen mainScreen].bounds; 46 | self.window.rootViewController = nav; 47 | [self.window makeKeyAndVisible]; 48 | */ 49 | 50 | return YES; 51 | } 52 | 53 | - (void)applicationWillResignActive:(UIApplication *)application { 54 | // 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. 55 | // 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. 56 | } 57 | 58 | - (void)applicationDidEnterBackground:(UIApplication *)application { 59 | // 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. 60 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 61 | } 62 | 63 | - (void)applicationWillEnterForeground:(UIApplication *)application { 64 | // 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. 65 | } 66 | 67 | - (void)applicationDidBecomeActive:(UIApplication *)application { 68 | // 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. 69 | } 70 | 71 | - (void)applicationWillTerminate:(UIApplication *)application { 72 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 73 | } 74 | 75 | @end 76 | 77 | 78 | @implementation UIApplication (Test) 79 | + (void)load { 80 | Method originalMethod = class_getInstanceMethod(self, @selector(canOpenURL:)); 81 | Method swizzledMethod = class_getInstanceMethod(self, @selector(ax_canOpenURL:)); 82 | method_exchangeImplementations(originalMethod, swizzledMethod); 83 | originalMethod = class_getInstanceMethod(self, @selector(openURL:)); 84 | swizzledMethod = class_getInstanceMethod(self, @selector(ax_openURL:)); 85 | method_exchangeImplementations(originalMethod, swizzledMethod); 86 | } 87 | 88 | - (BOOL)ax_canOpenURL:(NSURL *)url { 89 | Class class = NSClassFromString(@"MLULookupItemContent"); 90 | unsigned int count = 0; 91 | Ivar *members = class_copyIvarList(class, &count); 92 | for (NSInteger i=0; i < count; i++) { 93 | Ivar var = members[i]; 94 | NSString *key = [NSString stringWithUTF8String:ivar_getName(var)]; 95 | NSLog(@"key: %@", key); 96 | if ([key isEqualToString:@"_commitURL"]) { 97 | // id value = object_getIvar(weakImageBrowser, var); 98 | } 99 | } 100 | return [self ax_canOpenURL:url]; 101 | } 102 | 103 | - (BOOL)ax_openURL:(NSURL *)url { 104 | return [self ax_openURL:url]; 105 | } 106 | @end 107 | -------------------------------------------------------------------------------- /AXWebViewController/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "icon20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "icon20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "icon29@2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "icon29@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "icon40@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "icon40@3x.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "icon60@2x.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "icon60@3x.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "idiom" : "ios-marketing", 53 | "size" : "1024x1024", 54 | "scale" : "1x" 55 | } 56 | ], 57 | "info" : { 58 | "version" : 1, 59 | "author" : "xcode" 60 | } 61 | } -------------------------------------------------------------------------------- /AXWebViewController/Assets.xcassets/AppIcon.appiconset/icon20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/Assets.xcassets/AppIcon.appiconset/icon20@2x.png -------------------------------------------------------------------------------- /AXWebViewController/Assets.xcassets/AppIcon.appiconset/icon20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/Assets.xcassets/AppIcon.appiconset/icon20@3x.png -------------------------------------------------------------------------------- /AXWebViewController/Assets.xcassets/AppIcon.appiconset/icon29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/Assets.xcassets/AppIcon.appiconset/icon29@2x.png -------------------------------------------------------------------------------- /AXWebViewController/Assets.xcassets/AppIcon.appiconset/icon29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/Assets.xcassets/AppIcon.appiconset/icon29@3x.png -------------------------------------------------------------------------------- /AXWebViewController/Assets.xcassets/AppIcon.appiconset/icon40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/Assets.xcassets/AppIcon.appiconset/icon40@2x.png -------------------------------------------------------------------------------- /AXWebViewController/Assets.xcassets/AppIcon.appiconset/icon40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/Assets.xcassets/AppIcon.appiconset/icon40@3x.png -------------------------------------------------------------------------------- /AXWebViewController/Assets.xcassets/AppIcon.appiconset/icon60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/Assets.xcassets/AppIcon.appiconset/icon60@2x.png -------------------------------------------------------------------------------- /AXWebViewController/Assets.xcassets/AppIcon.appiconset/icon60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/Assets.xcassets/AppIcon.appiconset/icon60@3x.png -------------------------------------------------------------------------------- /AXWebViewController/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /AXWebViewController/Assets.xcassets/General/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /AXWebViewController/Assets.xcassets/General/back_indicator.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "btn_back@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "btn_back@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /AXWebViewController/Assets.xcassets/General/back_indicator.imageset/btn_back@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/Assets.xcassets/General/back_indicator.imageset/btn_back@2x.png -------------------------------------------------------------------------------- /AXWebViewController/Assets.xcassets/General/back_indicator.imageset/btn_back@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/Assets.xcassets/General/back_indicator.imageset/btn_back@3x.png -------------------------------------------------------------------------------- /AXWebViewController/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 | -------------------------------------------------------------------------------- /AXWebViewController/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 | 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 | 91 | 92 | 93 | 94 | 95 | 96 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 121 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 145 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 169 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 193 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 217 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | -------------------------------------------------------------------------------- /AXWebViewController/FullScreenViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FullScreenViewController.h 3 | // AXWebViewController 4 | // 5 | // Created by devedbox on 2017/11/6. 6 | // Copyright © 2017年 AiXing. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FullScreenViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /AXWebViewController/FullScreenViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FullScreenViewController.m 3 | // AXWebViewController 4 | // 5 | // Created by devedbox on 2017/11/6. 6 | // Copyright © 2017年 AiXing. All rights reserved. 7 | // 8 | 9 | #import "FullScreenViewController.h" 10 | 11 | @interface FullScreenViewController () 12 | 13 | @end 14 | 15 | @implementation FullScreenViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view. 20 | [self.view setBackgroundColor:[UIColor whiteColor]]; 21 | } 22 | 23 | - (void)viewWillAppear:(BOOL)animated { 24 | [super viewWillAppear:animated]; 25 | 26 | if (self.navigationController.isBeingPresented) { 27 | [self.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithTitle:@"关闭" style:0 target:self action:@selector(dimiss:)]]; 28 | } 29 | } 30 | 31 | - (void)dimiss:(UIBarButtonItem *)sender { 32 | [self.navigationController dismissViewControllerAnimated:YES completion:NULL]; 33 | } 34 | 35 | - (void)didReceiveMemoryWarning { 36 | [super didReceiveMemoryWarning]; 37 | // Dispose of any resources that can be recreated. 38 | } 39 | 40 | /* 41 | #pragma mark - Navigation 42 | 43 | // In a storyboard-based application, you will often want to do a little preparation before navigation 44 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 45 | // Get the new view controller using [segue destinationViewController]. 46 | // Pass the selected object to the new view controller. 47 | } 48 | */ 49 | 50 | - (BOOL)prefersStatusBarHidden { 51 | return YES; 52 | } 53 | @end 54 | -------------------------------------------------------------------------------- /AXWebViewController/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | web 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 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSApplicationCategoryType 26 | 27 | LSApplicationQueriesSchemes 28 | 29 | wechat 30 | weixin 31 | sinaweibohd 32 | sinaweibo 33 | sinaweibosso 34 | weibosdk 35 | weibosdk2.5 36 | mqqapi 37 | mqq 38 | mqqOpensdkSSoLogin 39 | mqqconnect 40 | mqqopensdkdataline 41 | mqqopensdkgrouptribeshare 42 | mqqopensdkfriend 43 | mqqopensdkapi 44 | mqqopensdkapiV2 45 | mqqopensdkapiV3 46 | mqqopensdkapiV4 47 | mqzoneopensdk 48 | wtloginmqq 49 | wtloginmqq2 50 | mqqwpa 51 | mqzone 52 | mqzonev2 53 | mqzoneshare 54 | wtloginqzone 55 | mqzonewx 56 | mqzoneopensdkapiV2 57 | mqzoneopensdkapi19 58 | mqzoneopensdkapi 59 | mqqbrowser 60 | mttbrowser 61 | alipay 62 | alipays 63 | exchangestreet 64 | googlechrome 65 | 66 | LSRequiresIPhoneOS 67 | 68 | NSAppTransportSecurity 69 | 70 | NSAllowsArbitraryLoads 71 | 72 | 73 | NSLocationUsageDescription 74 | 75 | NSLocationWhenInUseUsageDescription 76 | 77 | UILaunchStoryboardName 78 | LaunchScreen 79 | UIMainStoryboardFile 80 | Main 81 | UIRequiredDeviceCapabilities 82 | 83 | armv7 84 | 85 | UISupportedInterfaceOrientations 86 | 87 | UIInterfaceOrientationPortrait 88 | UIInterfaceOrientationLandscapeLeft 89 | UIInterfaceOrientationLandscapeRight 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /AXWebViewController/Swift.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/AXWebViewController/Swift.pdf -------------------------------------------------------------------------------- /AXWebViewController/TabbarViewController1.h: -------------------------------------------------------------------------------- 1 | // 2 | // TabbarViewController1.h 3 | // AXWebViewController 4 | // 5 | // Created by devedbox on 16/8/1. 6 | // Copyright © 2016年 AiXing. All rights reserved. 7 | // 8 | 9 | #import "AXWebViewController.h" 10 | 11 | @interface TabbarViewController1 : AXWebViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /AXWebViewController/TabbarViewController1.m: -------------------------------------------------------------------------------- 1 | // 2 | // TabbarViewController1.m 3 | // AXWebViewController 4 | // 5 | // Created by devedbox on 16/8/1. 6 | // Copyright © 2016年 AiXing. All rights reserved. 7 | // 8 | 9 | #import "TabbarViewController1.h" 10 | 11 | @interface TabbarViewController1 () 12 | 13 | @end 14 | 15 | @implementation TabbarViewController1 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view. 20 | 21 | [self loadURL:[NSURL URLWithString:@"http://sports.sina.cn/premierleague/chelsea/2016-08-01/detail-ifxunyya2939640.d.html"]]; 22 | } 23 | 24 | - (void)didReceiveMemoryWarning { 25 | [super didReceiveMemoryWarning]; 26 | // Dispose of any resources that can be recreated. 27 | } 28 | 29 | /* 30 | #pragma mark - Navigation 31 | 32 | // In a storyboard-based application, you will often want to do a little preparation before navigation 33 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 34 | // Get the new view controller using [segue destinationViewController]. 35 | // Pass the selected object to the new view controller. 36 | } 37 | */ 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /AXWebViewController/TabbarViewController2.h: -------------------------------------------------------------------------------- 1 | // 2 | // TabbarViewController2.h 3 | // AXWebViewController 4 | // 5 | // Created by devedbox on 16/8/1. 6 | // Copyright © 2016年 AiXing. All rights reserved. 7 | // 8 | 9 | #import "AXWebViewController.h" 10 | 11 | @interface TabbarViewController2 : AXWebViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /AXWebViewController/TabbarViewController2.m: -------------------------------------------------------------------------------- 1 | // 2 | // TabbarViewController2.m 3 | // AXWebViewController 4 | // 5 | // Created by devedbox on 16/8/1. 6 | // Copyright © 2016年 AiXing. All rights reserved. 7 | // 8 | 9 | #import "TabbarViewController2.h" 10 | 11 | @interface TabbarViewController2 () 12 | 13 | @end 14 | 15 | @implementation TabbarViewController2 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view. 20 | 21 | [self loadURL:[NSURL URLWithString:@"https://www.baidu.com"]]; 22 | // NSString *str = @"

https://www.baidu.com

"; 23 | 24 | // [self loadHTMLString:str baseURL:[NSURL URLWithString:@"https://www.baidu.com"]]; 25 | } 26 | 27 | - (void)didReceiveMemoryWarning { 28 | [super didReceiveMemoryWarning]; 29 | // Dispose of any resources that can be recreated. 30 | } 31 | 32 | /* 33 | #pragma mark - Navigation 34 | 35 | // In a storyboard-based application, you will often want to do a little preparation before navigation 36 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 37 | // Get the new view controller using [segue destinationViewController]. 38 | // Pass the selected object to the new view controller. 39 | } 40 | */ 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /AXWebViewController/TableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewController.h 3 | // AXWebViewController 4 | // 5 | // Created by ai on 15/12/23. 6 | // Copyright © 2015年 AiXing. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TableViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /AXWebViewController/TableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewController.m 3 | // AXWebViewController 4 | // 5 | // Created by ai on 15/12/23. 6 | // Copyright © 2015年 AiXing. All rights reserved. 7 | // 8 | 9 | #import "TableViewController.h" 10 | #import "AXWebViewController.h" 11 | #import 12 | 13 | @interface TableViewController () 14 | 15 | @end 16 | 17 | @implementation TableViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | 22 | // Uncomment the following line to preserve selection between presentations. 23 | // self.clearsSelectionOnViewWillAppear = NO; 24 | 25 | // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 26 | // self.navigationItem.rightBarButtonItem = self.editButtonItem; 27 | self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedStringFromTableInBundle(@"back", @"AXWebViewController", [NSBundle bundleWithPath:[[[NSBundle bundleForClass:NSClassFromString(@"AXWebViewController")] resourcePath] stringByAppendingPathComponent:@"AXWebViewController.bundle"]], @"Back") style:0 target:nil action:nil]; 28 | } 29 | 30 | - (void)didReceiveMemoryWarning { 31 | [super didReceiveMemoryWarning]; 32 | // Dispose of any resources that can be recreated. 33 | } 34 | 35 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 36 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 37 | switch (indexPath.row) { 38 | case 0: 39 | { 40 | AXWebViewController *webVC = [[AXWebViewController alloc] initWithURL:[NSURL fileURLWithPath:[NSBundle.mainBundle pathForResource:@"Swift" ofType:@"pdf"]]]; 41 | webVC.title = @"Swift.pdf"; 42 | webVC.showsToolBar = NO; 43 | if (AX_WEB_VIEW_CONTROLLER_iOS9_0_AVAILABLE()) { 44 | webVC.webView.allowsLinkPreview = YES; 45 | } 46 | [self.navigationController pushViewController:webVC animated:YES]; 47 | } 48 | break; 49 | case 1: 50 | { 51 | AXWebViewController *webVC = [[AXWebViewController alloc] initWithAddress:@"http://www.baidu.com"]; 52 | webVC.showsToolBar = NO; 53 | // webVC.showsNavigationCloseBarButtonItem = NO; 54 | if (AX_WEB_VIEW_CONTROLLER_iOS9_0_AVAILABLE()) { 55 | webVC.webView.allowsLinkPreview = YES; 56 | } 57 | [self.navigationController pushViewController:webVC animated:YES]; 58 | } 59 | break; 60 | case 2: 61 | { 62 | AXWebViewController *webVC = [[AXWebViewController alloc] initWithAddress:@"http://www.baidu.com"]; 63 | UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:webVC]; 64 | nav.navigationBar.tintColor = [UIColor colorWithRed:0.322 green:0.322 blue:0.322 alpha:1.00]; 65 | [self presentViewController:nav animated:YES completion:NULL]; 66 | webVC.showsToolBar = YES; 67 | webVC.navigationType = 1; 68 | } 69 | break; 70 | case 3: { 71 | AXWebViewController *webVC = [[AXWebViewController alloc] initWithAddress:@"https://github.com/devedbox/AXWebViewController"]; 72 | webVC.showsToolBar = NO; 73 | webVC.showsBackgroundLabel = NO; 74 | // webVC.showsNavigationBackBarButtonItemTitle = NO; 75 | if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_9_0) { 76 | webVC.webView.allowsLinkPreview = YES; 77 | } 78 | [self.navigationController pushViewController:webVC animated:YES]; 79 | } break; 80 | case 4: { 81 | AXWebViewController *webVC = [[AXWebViewController alloc] initWithAddress:@"https://github.com/devedbox/AXWebViewController/releases/latest"]; 82 | webVC.showsToolBar = NO; 83 | if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_9_0) { 84 | webVC.webView.allowsLinkPreview = YES; 85 | } 86 | [self.navigationController pushViewController:webVC animated:YES]; 87 | } break; 88 | default: 89 | break; 90 | } 91 | } 92 | 93 | - (void)handle:(id)sender { 94 | NSURL *URL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"AXWebViewController.bundle/html.bundle/neterror" ofType:@"html" inDirectory:nil]]; 95 | AXWebViewController *webVC = [[AXWebViewController alloc] initWithURL:URL]; 96 | webVC.showsToolBar = NO; 97 | webVC.navigationController.navigationBar.translucent = NO; 98 | self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:0.100f green:0.100f blue:0.100f alpha:0.800f]; 99 | self.navigationController.navigationBar.barTintColor = [UIColor colorWithRed:0.996f green:0.867f blue:0.522f alpha:1.00f]; 100 | [self.navigationController pushViewController:webVC animated:YES]; 101 | } 102 | 103 | - (IBAction)gotoGithub:(id)sender { 104 | AXWebViewController *webVC = [[AXWebViewController alloc] initWithAddress:@"https://github.com/devedbox/AXWebViewController"]; 105 | webVC.showsToolBar = NO; 106 | if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_9_0) { 107 | webVC.webView.allowsLinkPreview = YES; 108 | } 109 | [self.navigationController pushViewController:webVC animated:YES]; 110 | } 111 | 112 | - (IBAction)clearCache:(id)sender { 113 | [[AXPracticalHUD sharedHUD] showNormalInView:self.navigationController.view text:@"清理缓存..." detail:nil configuration:NULL]; 114 | [AXWebViewController clearWebCacheCompletion:^{ 115 | [[AXPracticalHUD sharedHUD] hide:YES afterDelay:0.5 completion:NULL]; 116 | }]; 117 | } 118 | 119 | #pragma mark - UITextFieldDelegate 120 | - (BOOL)textFieldShouldReturn:(UITextField *)textField { 121 | // Get the text of text field. 122 | NSString *text = [textField.text copy]; 123 | // Create an url object with the text string. 124 | NSURL *URL = [NSURL URLWithString:text]; 125 | 126 | if (URL) { 127 | [self.view endEditing:YES]; 128 | 129 | AXWebViewController *webVC = [[AXWebViewController alloc] initWithURL:URL]; 130 | webVC.showsToolBar = NO; 131 | if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_9_0) { 132 | webVC.webView.allowsLinkPreview = YES; 133 | } 134 | [self.navigationController pushViewController:webVC animated:YES]; 135 | } 136 | 137 | return YES; 138 | } 139 | @end 140 | -------------------------------------------------------------------------------- /AXWebViewController/WebViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // WebViewController.h 3 | // AXWebViewController 4 | // 5 | // Created by devedbox on 2017/9/7. 6 | // Copyright © 2017年 AiXing. All rights reserved. 7 | // 8 | 9 | #import "AXWebViewController.h" 10 | 11 | @interface WebViewController : AXWebViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /AXWebViewController/WebViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // WebViewController.m 3 | // AXWebViewController 4 | // 5 | // Created by devedbox on 2017/9/7. 6 | // Copyright © 2017年 AiXing. All rights reserved. 7 | // 8 | 9 | #import "WebViewController.h" 10 | 11 | @interface WebViewController () 12 | 13 | @end 14 | 15 | @implementation WebViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view. 20 | [self setupSubviews]; 21 | } 22 | 23 | - (void)didReceiveMemoryWarning { 24 | [super didReceiveMemoryWarning]; 25 | // Dispose of any resources that can be recreated. 26 | } 27 | 28 | - (void)setupSubviews { 29 | // Add from label and constraints. 30 | id topLayoutGuide = self.topLayoutGuide; 31 | id bottomLayoutGuide = self.bottomLayoutGuide; 32 | 33 | // Add web view. 34 | #if AX_WEB_VIEW_CONTROLLER_USING_WEBKIT 35 | UIView *containerView = [self valueForKeyPath:@"containerView"]; 36 | UIView *progressView = [self valueForKeyPath:@"progressView"]; 37 | UILabel *_backgroundLabel = [self valueForKeyPath:@"backgroundLabel"]; 38 | 39 | [_backgroundLabel removeFromSuperview]; 40 | [_webView removeFromSuperview]; 41 | 42 | [containerView addSubview:_backgroundLabel]; 43 | [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[_backgroundLabel(<=width)]" options:0 metrics:@{@"width":@(self.view.bounds.size.width)} views:NSDictionaryOfVariableBindings(_backgroundLabel)]]; 44 | [containerView addConstraint:[NSLayoutConstraint constraintWithItem:_backgroundLabel attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:containerView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]]; 45 | 46 | [containerView addSubview:self.webView]; 47 | [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_webView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_webView)]]; 48 | // 在这里加上自己的布局代码. 49 | [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_webView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_webView, topLayoutGuide, bottomLayoutGuide, _backgroundLabel)]]; 50 | [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_backgroundLabel]-20-[_webView]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_backgroundLabel, _webView)]]; 51 | 52 | [containerView bringSubviewToFront:_backgroundLabel]; 53 | #else 54 | [self.view insertSubview:_backgroundLabel atIndex:0]; 55 | [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-8-[_backgroundLabel]-8-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_backgroundLabel)]]; 56 | [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[topLayoutGuide]-10-[_backgroundLabel]-(>=0)-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_backgroundLabel, topLayoutGuide)]]; 57 | [self.view addSubview:self.webView]; 58 | [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_webView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_webView)]]; 59 | [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[topLayoutGuide][_webView][bottomLayoutGuide]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_webView, topLayoutGuide, bottomLayoutGuide)]]; 60 | #endif 61 | 62 | progressView.frame = CGRectMake(0, 0, CGRectGetWidth(self.view.frame), 2); 63 | [self.view addSubview:progressView]; 64 | [self.view bringSubviewToFront:progressView]; 65 | } 66 | @end 67 | -------------------------------------------------------------------------------- /AXWebViewController/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // AXWebViewController 4 | // 5 | // Created by ai on 15/12/22. 6 | // Copyright © 2015年 AiXing. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /AXWebViewController/zh-Hans.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /AXWebViewController/zh-Hans.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "Present"; ObjectID = "58i-qo-HOo"; */ 3 | "58i-qo-HOo.text" = "Present"; 4 | 5 | /* Class = "UITabBarItem"; title = "Item 1"; ObjectID = "E5r-4X-WNV"; */ 6 | "E5r-4X-WNV.title" = "Item 1"; 7 | 8 | /* Class = "UILabel"; text = "Push"; ObjectID = "Kda-Lk-aAt"; */ 9 | "Kda-Lk-aAt.text" = "Push"; 10 | 11 | /* Class = "UILabel"; text = "push the web view controller in."; ObjectID = "LSh-pc-osX"; */ 12 | "LSh-pc-osX.text" = "push the web view controller in."; 13 | 14 | /* Class = "UITabBarItem"; title = "Item"; ObjectID = "O96-bZ-DiV"; */ 15 | "O96-bZ-DiV.title" = "Item"; 16 | 17 | /* Class = "UINavigationItem"; title = "AXWebViewController"; ObjectID = "bUd-Nc-6R5"; */ 18 | "bUd-Nc-6R5.title" = "AXWebViewController"; 19 | 20 | /* Class = "UITabBarItem"; title = "Item"; ObjectID = "fZg-v3-Wbd"; */ 21 | "fZg-v3-Wbd.title" = "Item"; 22 | 23 | /* Class = "UILabel"; text = "present the web view controller in."; ObjectID = "vDR-sB-qKY"; */ 24 | "vDR-sB-qKY.text" = "present the web view controller in."; 25 | 26 | /* Class = "UITabBarItem"; title = "Item 2"; ObjectID = "zOo-MN-831"; */ 27 | "zOo-MN-831.title" = "Item 2"; 28 | -------------------------------------------------------------------------------- /AXWebViewController/zh-Hant.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /AXWebViewController/zh-Hant.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "Present"; ObjectID = "58i-qo-HOo"; */ 3 | "58i-qo-HOo.text" = "Present"; 4 | 5 | /* Class = "UILabel"; text = "Github pages of AXWebViewController."; ObjectID = "96P-Cp-yAs"; */ 6 | "96P-Cp-yAs.text" = "Github pages of AXWebViewController."; 7 | 8 | /* Class = "UITabBarItem"; title = "Item 1"; ObjectID = "E5r-4X-WNV"; */ 9 | "E5r-4X-WNV.title" = "Item 1"; 10 | 11 | /* Class = "UILabel"; text = "Lastest release pages of AXWebViewController."; ObjectID = "IH4-tk-BHC"; */ 12 | "IH4-tk-BHC.text" = "Lastest release pages of AXWebViewController."; 13 | 14 | /* Class = "UILabel"; text = "File"; ObjectID = "Kda-Lk-aAt"; */ 15 | "Kda-Lk-aAt.text" = "File"; 16 | 17 | /* Class = "UILabel"; text = "push the web view controller in showing file at the bundle."; ObjectID = "LSh-pc-osX"; */ 18 | "LSh-pc-osX.text" = "push the web view controller in showing file at the bundle."; 19 | 20 | /* Class = "UITabBarItem"; title = "Item"; ObjectID = "O96-bZ-DiV"; */ 21 | "O96-bZ-DiV.title" = "Item"; 22 | 23 | /* Class = "UILabel"; text = "Lastest release"; ObjectID = "Zyx-H3-mt5"; */ 24 | "Zyx-H3-mt5.text" = "Lastest release"; 25 | 26 | /* Class = "UILabel"; text = "Github"; ObjectID = "bBD-du-OYx"; */ 27 | "bBD-du-OYx.text" = "Github"; 28 | 29 | /* Class = "UILabel"; text = "push the web view controller in."; ObjectID = "c1w-bj-kxv"; */ 30 | "c1w-bj-kxv.text" = "push the web view controller in."; 31 | 32 | /* Class = "UITabBarItem"; title = "Item"; ObjectID = "fZg-v3-Wbd"; */ 33 | "fZg-v3-Wbd.title" = "Item"; 34 | 35 | /* Class = "UILabel"; text = "Push"; ObjectID = "jPO-kr-MDH"; */ 36 | "jPO-kr-MDH.text" = "Push"; 37 | 38 | /* Class = "UITextField"; placeholder = "Input an address."; ObjectID = "mDR-r7-p1o"; */ 39 | "mDR-r7-p1o.placeholder" = "Input an address."; 40 | 41 | /* Class = "UILabel"; text = "present the web view controller in."; ObjectID = "vDR-sB-qKY"; */ 42 | "vDR-sB-qKY.text" = "present the web view controller in."; 43 | 44 | /* Class = "UITabBarItem"; title = "Item 2"; ObjectID = "zOo-MN-831"; */ 45 | "zOo-MN-831.title" = "Item 2"; 46 | -------------------------------------------------------------------------------- /AXWebViewControllerFramework/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 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /AXWebViewControllerFrameworkTests/AXWebViewControllerFrameworkTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // AXWebViewControllerFrameworkTests.m 3 | // AXWebViewControllerFrameworkTests 4 | // 5 | // Created by devedbox on 2017/7/21. 6 | // Copyright © 2017年 AiXing. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AXWebViewControllerFrameworkTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation AXWebViewControllerFrameworkTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /AXWebViewControllerFrameworkTests/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 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Ed.x 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform:ios, '7.0' 2 | 3 | inhibit_all_warnings! 4 | target 'AXWebViewController' do 5 | pod 'AXNavigationBackItemInjection' 6 | pod 'NJKWebViewProgress' 7 | pod 'Aspects' 8 | pod 'AXPracticalHUD' 9 | end 10 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Aspects (1.4.1) 3 | - AXIndicatorView (0.1.1) 4 | - AXNavigationBackItemInjection (0.0.2) 5 | - AXPracticalHUD (2.0.2): 6 | - AXIndicatorView 7 | - NJKWebViewProgress (0.2.3): 8 | - NJKWebViewProgress/Core (= 0.2.3) 9 | - NJKWebViewProgress/ProgressView (= 0.2.3) 10 | - NJKWebViewProgress/Core (0.2.3) 11 | - NJKWebViewProgress/ProgressView (0.2.3) 12 | 13 | DEPENDENCIES: 14 | - Aspects 15 | - AXNavigationBackItemInjection 16 | - AXPracticalHUD 17 | - NJKWebViewProgress 18 | 19 | SPEC CHECKSUMS: 20 | Aspects: 7595ba96a6727a58ebcbfc954497fc5d2fdde546 21 | AXIndicatorView: 566b490a2dd9781d4ffbcc9752be9b9cdc6e728e 22 | AXNavigationBackItemInjection: efe0446967f3cbcc85a9118decd1e145138912dd 23 | AXPracticalHUD: 16c3ff6d97c061e80e80897b2e6ac8e330079472 24 | NJKWebViewProgress: f481fd424cb5ecc27eacae11b5397db92fba9a4d 25 | 26 | PODFILE CHECKSUM: 207fd9270929cf3153a3b3d5d06cc43eac68880f 27 | 28 | COCOAPODS: 1.3.1 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![AXWebViewController](src/img/logo.png) 2 | 3 | ![Build](https://img.shields.io/badge/build-passing-52c435.svg)[![Version](https://img.shields.io/cocoapods/v/AXWebViewController.svg?style=flat)](http://cocoapods.org/pods/AXWebViewController)[![License](https://img.shields.io/cocoapods/l/AXWebViewController.svg?style=flat)](http://cocoapods.org/pods/AXWebViewController)[![Platform](https://img.shields.io/cocoapods/p/AXWebViewController.svg?style=flat)](http://cocoapods.org/pods/AXWebViewController)[![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) 4 | 5 | 6 | ## Summary 7 | 8 | `AXWebViewController`是一款基于`WKWebView(WebKit)`封装的**view controller**,高度集成,一行代码即可使用;能够满足大部分的App加载html网页的场景,`AXWebViewController`实现了`WKUIDelegate`和`WKNavigationDelegate`两个协议,在使用过程中,若需要自定义功能,可自行**Overrides**相关方法予以实现; 9 | 10 | `AXWebViewController`可实现**微信样式**的网页浏览导航控制,可在导航栏显示`返回`和`关闭`两个功能按钮,这个功能主要基于[`AXNavigationBackItemInjection`](https://github.com/devedbox/AXNavigationBackItemInjection)而实现,**AXNavigationBackItemInjection**可以拦截点击返回导航或者手势滑动返回,有兴趣的朋友可以了解了解! 11 | 12 | [![sample2](http://ww3.sinaimg.cn/large/d2297bd2gw1f5wpniezqpg209o0h44qr.gif)](http://ww3.sinaimg.cn/large/d2297bd2gw1f5wpniezqpg209o0h44qr.gif) [![sample](http://ww4.sinaimg.cn/large/d2297bd2gw1f5wpmh7vfgg209o0h4qv5.gif)](http://ww4.sinaimg.cn/large/d2297bd2gw1f5wpmh7vfgg209o0h4qv5.gif) 13 | 14 | [视频链接](http://video.weibo.com/show?fid=1034:5a4102ad40573447a44ae74d56a80451) 15 | ## Features 16 | >* 手势滑动返回上个页面 17 | >* 微信样式导航返回、关闭 18 | >* 网页加载失败提示 19 | >* 网页加载进度提示 20 | >* 网页来源host提示 21 | >* 支持__Peek__和__Pop__浏览网页,并且commit之后在本网页进行加载,不用跳转到Safari进行浏览,这里使用到了很多运行时的方法,因此,谨慎使用! 22 | 23 | ## Requirements 24 | 25 | `AXWebViewController` 对系统版本支持到iOS7.0;版本`0.7.0`以后仅支持`Xcode9`,需要使用到: 26 | 27 | >* Foundation.framework 28 | >* UIKit.framework 29 | 30 | 使用的时候最好使用最新版Xcode。 31 | 32 | ## Adding AXWebViewController to your projet 33 | ### CocoaPods 34 | [CocoaPods](http://cocoapods.org) is the recommended way to add AXWebViewController to your project. 35 | 36 | 1. Add a pod entry for `AXWebViewController` to your Podfile `pod 'AXWebViewController', '~> 0.6.0'` 37 | 2. Install the pod(s) by running `pod install`. 38 | 3. Include `AXWebViewController` wherever you need it with `#import "AXWebViewController.h"`. 39 | 40 | ### Source files 41 | 42 | Alternatively you can directly add the source files under path `*/AXWebViewController/` to your project. 43 | 44 | 1. Download the [latest code version](https://github.com/devedbox/AXWebViewController/archive/master.zip) or add the repository as a git submodule to your git-tracked project. 45 | 2. Open your project in Xcode, then drag and drop the source files onto your project (use the "Product Navigator view"). Make sure to select Copy items when asked if you extracted the code archive outside of your project. 46 | 3. Include `AXWebViewController` wherever you need it with `#import "AXWebViewController.h"`. 47 | 48 | ## License 49 | 50 | This code is distributed under the terms and conditions of the [MIT license](LICENSE). 51 | 52 | ## Usage 53 | 54 | `AXWebViewController`使用和使用普通`UIViewController`一样简单,只需要在需要使用的地方使用`URL`初始化即可: 55 | ```objcetive-c 56 | AXWebViewController *webVC = [[AXWebViewController alloc] initWithAddress:@"http://www.baidu.com"]; 57 | webVC.showsToolBar = NO; 58 | webVC.navigationController.navigationBar.translucent = NO; 59 | self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:0.100f green:0.100f blue:0.100f alpha:0.800f]; 60 | self.navigationController.navigationBar.barTintColor = [UIColor colorWithRed:0.996f green:0.867f blue:0.522f alpha:1.00f]; 61 | [self.navigationController pushViewController:webVC animated:YES]; 62 | ``` 63 | ### 使用工具条导航 64 | 使用工具条只需在`AXWebViewController`初始化之后加入一句代码: 65 | ```objcetive-c 66 | webVC.navigationType = AXWebViewControllerNavigationToolItem; 67 | webVC.showsToolBar = YES; 68 | ``` 69 | 注意,在设置`navigationType`为`AXWebViewControllerNavigationToolItem`之后,须确认`showsToolBar`为`YES`才能生效. 70 | ### 使用微信样式导航 71 | 在`AXWebViewController`初始化之后加入一句代码: 72 | ```objcetive-c 73 | webVC.navigationType = AXWebViewControllerNavigationBarItem; 74 | ``` 75 | 即可生效. 76 | ### Peek&Pop 77 | Peek和Pop使用的是原生的系统功能,在使用的时候只需要将`webView.allowsLinkPreview`设置为`YES`即可使用,这里需要注意下,在实现Peek和Pop的时候,使用了Runtime的相关知识,而且使用AOP的一个框架__[Aspects](https://github.com/steipete/Aspects)__进行了编程,在使用的过程中可能会出错,当然,出错的几率也是很小的(苹果不可能隔三差五的去修改自家的Private API吧= =),实现原理就不多讲了,基本上就是运行时的一些知识,代码如下: 78 | ```objcetive-c 79 | 80 | - (void)hookWebContentCommitPreviewHandler { 81 | // Find the `WKContentView` in the webview. 82 | __weak typeof(self) wself = self; 83 | for (UIView *_view in _webView.scrollView.subviews) { 84 | if ([_view isKindOfClass:NSClassFromString(@"WKContentView")]) { 85 | id _previewItemController = object_getIvar(_view, class_getInstanceVariable([_view class], "_previewItemController")); 86 | Class _class = [_previewItemController class]; 87 | SEL _performCustomCommitSelector = NSSelectorFromString(@"previewInteractionController:interactionProgress:forRevealAtLocation:inSourceView:containerView:"); 88 | [_previewItemController aspect_hookSelector:_performCustomCommitSelector withOptions:AspectPositionAfter usingBlock:^() { 89 | UIViewController *pred = [_previewItemController valueForKeyPath:@"presentedViewController"]; 90 | [pred aspect_hookSelector:NSSelectorFromString(@"_addRemoteView") withOptions:AspectPositionAfter usingBlock:^() { 91 | UIViewController *_remoteViewController = object_getIvar(pred, class_getInstanceVariable([pred class], "_remoteViewController")); 92 | 93 | [_remoteViewController aspect_hookSelector:@selector(viewDidLoad) withOptions:AspectPositionAfter usingBlock:^() { 94 | _remoteViewController.view.tintColor = wself.navigationController.navigationBar.tintColor; 95 | } error:NULL]; 96 | } error:NULL]; 97 | 98 | NSArray *ddActions = [pred valueForKeyPath:@"ddActions"]; 99 | id openURLAction = [ddActions firstObject]; 100 | 101 | [openURLAction aspect_hookSelector:NSSelectorFromString(@"perform") withOptions:AspectPositionInstead usingBlock:^ () { 102 | NSURL *_url = object_getIvar(openURLAction, class_getInstanceVariable([openURLAction class], "_url")); 103 | [wself loadURL:_url]; 104 | } error:NULL]; 105 | 106 | id _lookupItem = object_getIvar(_previewItemController, class_getInstanceVariable([_class class], "_lookupItem")); 107 | [_lookupItem aspect_hookSelector:NSSelectorFromString(@"commit") withOptions:AspectPositionInstead usingBlock:^() { 108 | NSURL *_url = object_getIvar(_lookupItem, class_getInstanceVariable([_lookupItem class], "_url")); 109 | [wself loadURL:_url]; 110 | } error:NULL]; 111 | [_lookupItem aspect_hookSelector:NSSelectorFromString(@"commitWithTransitionForPreviewViewController:inViewController:completion:") withOptions:AspectPositionInstead usingBlock:^() { 112 | NSURL *_url = object_getIvar(_lookupItem, class_getInstanceVariable([_lookupItem class], "_url")); 113 | [wself loadURL:_url]; 114 | } error:NULL]; 115 | /* 116 | UIWindow 117 | -UITransitionView 118 | --UIVisualEffectView 119 | ---_UIVisualEffectContentView 120 | ----UIView 121 | -----_UIPreviewActionSheetView 122 | */ 123 | /* 124 | for (UIView * transitionView in [UIApplication sharedApplication].keyWindow.subviews) { 125 | if ([transitionView isMemberOfClass:NSClassFromString(@"UITransitionView")]) { 126 | transitionView.tintColor = wself.navigationController.navigationBar.tintColor; 127 | for (UIView *__view in transitionView.subviews) { 128 | if ([__view isMemberOfClass:NSClassFromString(@"UIVisualEffectView")]) { 129 | for (UIView *___view in __view.subviews) { 130 | if ([___view isMemberOfClass:NSClassFromString(@"_UIVisualEffectContentView")]) { 131 | for (UIView *____view in ___view.subviews) { 132 | if ([____view isMemberOfClass:NSClassFromString(@"UIView")]) { 133 | __weak typeof(____view) w____view = ____view; 134 | [____view aspect_hookSelector:@selector(addSubview:) withOptions:AspectPositionAfter usingBlock:^() { 135 | for (UIView *actionSheet in w____view.subviews) { 136 | if ([actionSheet isMemberOfClass:NSClassFromString(@"_UIPreviewActionSheetView")]) { 137 | break; 138 | } 139 | } 140 | } error:NULL]; 141 | } 142 | }break; 143 | } 144 | }break; 145 | } 146 | }break; 147 | } 148 | } 149 | */ 150 | } error:NULL]; 151 | break; 152 | } 153 | } 154 | } 155 | 156 | ``` 157 | 158 | ## 致谢 159 | [RxWebViewController](https://github.com/Roxasora/RxWebViewController)为我提供了思路,有些地方做了参考 160 | 161 | `iOS8.0`以下使用了[NJKWebViewProgress](https://github.com/ninjinkun/NJKWebViewProgress)作为进度条,感谢! 162 | ## 更新日志 163 | ### 0.1.10 164 | 使用基于`UIWebView`的实现,进度条使用`NJKWebViewProgress`实现. 165 | ### 0.2.0 166 | iOS8.0以上使用`WKWebView`实现,进度条使用`UIProgressView`实现. 实现了本页面Peek&Pop而不用跳转到Safari进行浏览. 167 | ### 0.3.0 168 | 使用[AXNavigationBackItemInjection](https://github.com/devedbox/AXNavigationBackItemInjection)实现微信导航样式,也可以自定义返回的操作,只需要几行代码就可以搞定! 169 | #### 查看更多日志请移步[`Latest release`](https://github.com/devedbox/AXWebViewController/releases/latest). 170 | -------------------------------------------------------------------------------- /src/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devedbox/AXWebViewController/3d2044ac6d4780d411eaa5823bea242b77e29eee/src/img/logo.png --------------------------------------------------------------------------------