├── .gitignore ├── LICENSE ├── README.md ├── SmartConfig ├── SmartConfig.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata └── SmartConfig │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── icon-20-ipad.png │ │ ├── icon-20@2x-ipad.png │ │ ├── icon-20@2x.png │ │ ├── icon-20@3x.png │ │ ├── icon-29-ipad.png │ │ ├── icon-29.png │ │ ├── icon-29@2x-ipad.png │ │ ├── icon-29@2x.png │ │ ├── icon-29@3x.png │ │ ├── icon-40.png │ │ ├── icon-40@2x.png │ │ ├── icon-40@3x.png │ │ ├── icon-50.png │ │ ├── icon-50@2x.png │ │ ├── icon-57.png │ │ ├── icon-57@2x.png │ │ ├── icon-60@2x.png │ │ ├── icon-60@3x.png │ │ ├── icon-72.png │ │ ├── icon-72@2x.png │ │ ├── icon-76.png │ │ ├── icon-76@2x.png │ │ └── icon-83.5@2x.png │ ├── Config-1.imageset │ │ ├── Contents.json │ │ └── Custom Preset.png │ ├── Config.imageset │ │ ├── Contents.json │ │ └── Custom Preset.png │ ├── Contents.json │ ├── ESP8266.imageset │ │ ├── 1.png │ │ └── Contents.json │ ├── More-1.imageset │ │ ├── Contents.json │ │ └── more-1.png │ ├── More.imageset │ │ ├── Contents.json │ │ └── more.png │ ├── NodeMCU.imageset │ │ ├── 3.png │ │ └── Contents.json │ ├── NodeMCU32S.imageset │ │ ├── Contents.json │ │ └── NodeMCU32S.png │ ├── Pin-1.imageset │ │ ├── Contents.json │ │ └── Custom Preset.png │ ├── Pin.imageset │ │ ├── Contents.json │ │ └── 引脚-未选中状态.png │ └── Wi-Fi 背景.imageset │ │ ├── Contents.json │ │ └── Wi-Fi 背景.png │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Controller │ ├── ContentViewController.swift │ ├── OtherTableVC.swift │ ├── PageViewController.swift │ ├── SmartConfigViewController.swift │ └── WebViewController.swift │ ├── ESPtouch │ ├── ESPTouchDelegate.h │ ├── ESPTouchResult.h │ ├── ESPTouchTask.h │ ├── GetWiFi.swift │ └── libEsptouch_v0.3.5.3.a │ ├── HTML │ ├── OpenSource.html │ ├── SmartConfig.html │ └── css │ │ └── weui.min.css │ ├── Info.plist │ ├── SmartConfig-Bridging-Header.h │ ├── SmartConfig.entitlements │ ├── View │ ├── CustomTextField.swift │ └── SystemButton.swift │ ├── en.lproj │ ├── Localizable.strings │ └── Main.strings │ └── zh-Hans.lproj │ ├── Localizable.strings │ └── Main.strings └── images ├── 1.png ├── 2.png └── 3.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | ## Playgrounds 31 | timeline.xctimeline 32 | playground.xcworkspace 33 | 34 | # Swift Package Manager 35 | # 36 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 37 | # Packages/ 38 | .build/ 39 | 40 | # CocoaPods 41 | # 42 | # We recommend against adding the Pods directory to your .gitignore. However 43 | # you should judge for yourself, the pros and cons are mentioned at: 44 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 45 | # 46 | # Pods/ 47 | 48 | # Carthage 49 | # 50 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 51 | # Carthage/Checkouts 52 | 53 | Carthage/Build 54 | 55 | # fastlane 56 | # 57 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 58 | # screenshots whenever they are needed. 59 | # For more information about the recommended setup visit: 60 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 61 | 62 | fastlane/report.xml 63 | fastlane/Preview.html 64 | fastlane/screenshots 65 | fastlane/test_output 66 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 楼兰 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SmartConfig 2 | SmartConfig is an ESP board auto connect WiFi demo written in Swift. 3 | 4 | ## Requirements 5 | - iOS 8.0+ 6 | - Xcode 8.0+ 7 | - Swift 3.0 8 | ## Bridge ESPtouch lib 9 | 1.Xcode -> Create a new Xcode project -> Single View App. 10 | 2.Download lib [https://github.com/EspressifApp/LibEsptouchForIOS](https://github.com/EspressifApp/LibEsptouchForIOS). 11 | 3.Move libEsptouch_v0.3.5.3.a, ESPTouchTask.h, ESPTouchResult.h, ESPTouchDelegate.h to your new project. 12 | ![](https://github.com/lou-lan/SmartConfig/blob/master/images/1.png) 13 | 4.In project group finder, create a new fire, select Objecttive-C file, then select Create Bridging Header. 14 | ![](https://github.com/lou-lan/SmartConfig/blob/master/images/2.png) 15 | 5.In Demo-Bridging-Header.h file, import lib. 16 | ![](https://github.com/lou-lan/SmartConfig/blob/master/images/3.png) 17 | ``` 18 | #import "ESPTouchTask.h" 19 | #import "ESPTouchResult.h" 20 | #import "ESPTouchDelegate.h" 21 | ``` 22 | ## Hardware ESP8266 NodeMCU Code init.lua Test 23 | ```lua 24 | print("Start SmartConfig ...") 25 | wifi.setmode(wifi.STATION) 26 | wifi.startsmart(0, 27 | function(ssid, password) 28 | print(string.format("Success. SSID:%s ; PASSWORD:%s", ssid, password)) 29 | print("Back init.lua") 30 | dofile("init.lua") 31 | end 32 | ) 33 | ``` 34 | 35 | ## TODO 36 | [] SwiftUI 37 | [] WiFi 5G 38 | 39 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 7F1F71F01EC72CE60077D070 /* GetWiFi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F1F71EF1EC72CE60077D070 /* GetWiFi.swift */; }; 11 | 7F5FD50C1EBDA4B200ACB2C0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F5FD50B1EBDA4B200ACB2C0 /* AppDelegate.swift */; }; 12 | 7F5FD5111EBDA4B200ACB2C0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7F5FD50F1EBDA4B200ACB2C0 /* Main.storyboard */; }; 13 | 7F5FD5131EBDA4B200ACB2C0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7F5FD5121EBDA4B200ACB2C0 /* Assets.xcassets */; }; 14 | 7F5FD51E1EBDB35900ACB2C0 /* SmartConfigViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F5FD51D1EBDB35900ACB2C0 /* SmartConfigViewController.swift */; }; 15 | 7F6379C91EBDBD620071DBA5 /* libEsptouch_v0.3.5.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F6379C81EBDBD620071DBA5 /* libEsptouch_v0.3.5.3.a */; }; 16 | 7F6B53611EC8859A0035E0CF /* WebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F6B53601EC8859A0035E0CF /* WebViewController.swift */; }; 17 | 7F6EF81C1EC9A1CD00B2EC75 /* HTML in Resources */ = {isa = PBXBuildFile; fileRef = 7F6EF81B1EC9A1CD00B2EC75 /* HTML */; }; 18 | 7F7DAE1B1EEAA19300D4598F /* ContentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F7DAE1A1EEAA19300D4598F /* ContentViewController.swift */; }; 19 | 7F7DAE1D1EEAAF7600D4598F /* PageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F7DAE1C1EEAAF7600D4598F /* PageViewController.swift */; }; 20 | 7F8E9F0B1EEF884100BFC6C9 /* OtherTableVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F8E9F0A1EEF884100BFC6C9 /* OtherTableVC.swift */; }; 21 | 7F9E88B61EF504B1006C8371 /* SystemButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F9E88B51EF504B1006C8371 /* SystemButton.swift */; }; 22 | 7FA649551EF93FBC00AECA36 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7FA649571EF93FBC00AECA36 /* Localizable.strings */; }; 23 | 7FF5D2521EF7D029002429F2 /* CustomTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FF5D2511EF7D029002429F2 /* CustomTextField.swift */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXFileReference section */ 27 | 7F1F71EF1EC72CE60077D070 /* GetWiFi.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GetWiFi.swift; path = ESPtouch/GetWiFi.swift; sourceTree = ""; }; 28 | 7F5FD5081EBDA4B200ACB2C0 /* SmartConfig.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SmartConfig.app; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | 7F5FD50B1EBDA4B200ACB2C0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 30 | 7F5FD5121EBDA4B200ACB2C0 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 31 | 7F5FD5171EBDA4B200ACB2C0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 32 | 7F5FD51D1EBDB35900ACB2C0 /* SmartConfigViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmartConfigViewController.swift; sourceTree = ""; }; 33 | 7F5FD5261EBDB3FA00ACB2C0 /* SmartConfig-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SmartConfig-Bridging-Header.h"; sourceTree = ""; }; 34 | 7F6379C51EBDBD620071DBA5 /* ESPTouchDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ESPTouchDelegate.h; sourceTree = ""; }; 35 | 7F6379C61EBDBD620071DBA5 /* ESPTouchResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ESPTouchResult.h; sourceTree = ""; }; 36 | 7F6379C71EBDBD620071DBA5 /* ESPTouchTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ESPTouchTask.h; sourceTree = ""; }; 37 | 7F6379C81EBDBD620071DBA5 /* libEsptouch_v0.3.5.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libEsptouch_v0.3.5.3.a; sourceTree = ""; }; 38 | 7F6B53601EC8859A0035E0CF /* WebViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WebViewController.swift; sourceTree = ""; }; 39 | 7F6EF81B1EC9A1CD00B2EC75 /* HTML */ = {isa = PBXFileReference; lastKnownFileType = folder; path = HTML; sourceTree = ""; }; 40 | 7F7DAE1A1EEAA19300D4598F /* ContentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentViewController.swift; sourceTree = ""; }; 41 | 7F7DAE1C1EEAAF7600D4598F /* PageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageViewController.swift; sourceTree = ""; }; 42 | 7F8E9F0A1EEF884100BFC6C9 /* OtherTableVC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OtherTableVC.swift; sourceTree = ""; }; 43 | 7F9E88B51EF504B1006C8371 /* SystemButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemButton.swift; sourceTree = ""; }; 44 | 7FA649261EF8F72600AECA36 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 45 | 7FA6494D1EF8F93600AECA36 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Main.strings; sourceTree = ""; }; 46 | 7FA6494E1EF8F93D00AECA36 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Main.strings"; sourceTree = ""; }; 47 | 7FA649561EF93FBC00AECA36 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; 48 | 7FA649581EF93FC100AECA36 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; 49 | 7FF5D2511EF7D029002429F2 /* CustomTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTextField.swift; sourceTree = ""; }; 50 | 7FFF83192454208100846688 /* SmartConfig.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SmartConfig.entitlements; sourceTree = ""; }; 51 | /* End PBXFileReference section */ 52 | 53 | /* Begin PBXFrameworksBuildPhase section */ 54 | 7F5FD5051EBDA4B200ACB2C0 /* Frameworks */ = { 55 | isa = PBXFrameworksBuildPhase; 56 | buildActionMask = 2147483647; 57 | files = ( 58 | 7F6379C91EBDBD620071DBA5 /* libEsptouch_v0.3.5.3.a in Frameworks */, 59 | ); 60 | runOnlyForDeploymentPostprocessing = 0; 61 | }; 62 | /* End PBXFrameworksBuildPhase section */ 63 | 64 | /* Begin PBXGroup section */ 65 | 7F5FD4FF1EBDA4B200ACB2C0 = { 66 | isa = PBXGroup; 67 | children = ( 68 | 7F5FD50A1EBDA4B200ACB2C0 /* SmartConfig */, 69 | 7F5FD5091EBDA4B200ACB2C0 /* Products */, 70 | ); 71 | sourceTree = ""; 72 | }; 73 | 7F5FD5091EBDA4B200ACB2C0 /* Products */ = { 74 | isa = PBXGroup; 75 | children = ( 76 | 7F5FD5081EBDA4B200ACB2C0 /* SmartConfig.app */, 77 | ); 78 | name = Products; 79 | sourceTree = ""; 80 | }; 81 | 7F5FD50A1EBDA4B200ACB2C0 /* SmartConfig */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | 7FFF83192454208100846688 /* SmartConfig.entitlements */, 85 | 7F6EF81B1EC9A1CD00B2EC75 /* HTML */, 86 | 7F5FD52B1EBDB44C00ACB2C0 /* Model */, 87 | 7F9E88B31EF50358006C8371 /* View */, 88 | 7F9E88B41EF50374006C8371 /* Controller */, 89 | 7F5FD51F1EBDB37500ACB2C0 /* Lib */, 90 | 7F5FD50B1EBDA4B200ACB2C0 /* AppDelegate.swift */, 91 | 7F5FD50F1EBDA4B200ACB2C0 /* Main.storyboard */, 92 | 7F5FD5121EBDA4B200ACB2C0 /* Assets.xcassets */, 93 | 7F5FD5261EBDB3FA00ACB2C0 /* SmartConfig-Bridging-Header.h */, 94 | 7F5FD5171EBDA4B200ACB2C0 /* Info.plist */, 95 | 7FA649571EF93FBC00AECA36 /* Localizable.strings */, 96 | ); 97 | path = SmartConfig; 98 | sourceTree = ""; 99 | }; 100 | 7F5FD51F1EBDB37500ACB2C0 /* Lib */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 7F6379C41EBDBD620071DBA5 /* ESPtouch */, 104 | ); 105 | name = Lib; 106 | sourceTree = ""; 107 | }; 108 | 7F5FD52B1EBDB44C00ACB2C0 /* Model */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 7F1F71EF1EC72CE60077D070 /* GetWiFi.swift */, 112 | ); 113 | name = Model; 114 | sourceTree = ""; 115 | }; 116 | 7F6379C41EBDBD620071DBA5 /* ESPtouch */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | 7F6379C51EBDBD620071DBA5 /* ESPTouchDelegate.h */, 120 | 7F6379C61EBDBD620071DBA5 /* ESPTouchResult.h */, 121 | 7F6379C71EBDBD620071DBA5 /* ESPTouchTask.h */, 122 | 7F6379C81EBDBD620071DBA5 /* libEsptouch_v0.3.5.3.a */, 123 | ); 124 | path = ESPtouch; 125 | sourceTree = ""; 126 | }; 127 | 7F9E88B31EF50358006C8371 /* View */ = { 128 | isa = PBXGroup; 129 | children = ( 130 | 7F9E88B51EF504B1006C8371 /* SystemButton.swift */, 131 | 7FF5D2511EF7D029002429F2 /* CustomTextField.swift */, 132 | ); 133 | path = View; 134 | sourceTree = ""; 135 | }; 136 | 7F9E88B41EF50374006C8371 /* Controller */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | 7F5FD51D1EBDB35900ACB2C0 /* SmartConfigViewController.swift */, 140 | 7F7DAE1A1EEAA19300D4598F /* ContentViewController.swift */, 141 | 7F7DAE1C1EEAAF7600D4598F /* PageViewController.swift */, 142 | 7F8E9F0A1EEF884100BFC6C9 /* OtherTableVC.swift */, 143 | 7F6B53601EC8859A0035E0CF /* WebViewController.swift */, 144 | ); 145 | path = Controller; 146 | sourceTree = ""; 147 | }; 148 | /* End PBXGroup section */ 149 | 150 | /* Begin PBXNativeTarget section */ 151 | 7F5FD5071EBDA4B200ACB2C0 /* SmartConfig */ = { 152 | isa = PBXNativeTarget; 153 | buildConfigurationList = 7F5FD51A1EBDA4B200ACB2C0 /* Build configuration list for PBXNativeTarget "SmartConfig" */; 154 | buildPhases = ( 155 | 7F5FD5041EBDA4B200ACB2C0 /* Sources */, 156 | 7F5FD5051EBDA4B200ACB2C0 /* Frameworks */, 157 | 7F5FD5061EBDA4B200ACB2C0 /* Resources */, 158 | ); 159 | buildRules = ( 160 | ); 161 | dependencies = ( 162 | ); 163 | name = SmartConfig; 164 | productName = SmartConfig; 165 | productReference = 7F5FD5081EBDA4B200ACB2C0 /* SmartConfig.app */; 166 | productType = "com.apple.product-type.application"; 167 | }; 168 | /* End PBXNativeTarget section */ 169 | 170 | /* Begin PBXProject section */ 171 | 7F5FD5001EBDA4B200ACB2C0 /* Project object */ = { 172 | isa = PBXProject; 173 | attributes = { 174 | LastSwiftUpdateCheck = 0830; 175 | LastUpgradeCheck = 1140; 176 | ORGANIZATIONNAME = "翟怀楼"; 177 | TargetAttributes = { 178 | 7F5FD5071EBDA4B200ACB2C0 = { 179 | CreatedOnToolsVersion = 8.3.2; 180 | DevelopmentTeam = 6687NJS8Y9; 181 | LastSwiftMigration = 0900; 182 | ProvisioningStyle = Automatic; 183 | }; 184 | }; 185 | }; 186 | buildConfigurationList = 7F5FD5031EBDA4B200ACB2C0 /* Build configuration list for PBXProject "SmartConfig" */; 187 | compatibilityVersion = "Xcode 3.2"; 188 | developmentRegion = en; 189 | hasScannedForEncodings = 0; 190 | knownRegions = ( 191 | Base, 192 | en, 193 | "zh-Hans", 194 | ); 195 | mainGroup = 7F5FD4FF1EBDA4B200ACB2C0; 196 | productRefGroup = 7F5FD5091EBDA4B200ACB2C0 /* Products */; 197 | projectDirPath = ""; 198 | projectRoot = ""; 199 | targets = ( 200 | 7F5FD5071EBDA4B200ACB2C0 /* SmartConfig */, 201 | ); 202 | }; 203 | /* End PBXProject section */ 204 | 205 | /* Begin PBXResourcesBuildPhase section */ 206 | 7F5FD5061EBDA4B200ACB2C0 /* Resources */ = { 207 | isa = PBXResourcesBuildPhase; 208 | buildActionMask = 2147483647; 209 | files = ( 210 | 7F6EF81C1EC9A1CD00B2EC75 /* HTML in Resources */, 211 | 7FA649551EF93FBC00AECA36 /* Localizable.strings in Resources */, 212 | 7F5FD5131EBDA4B200ACB2C0 /* Assets.xcassets in Resources */, 213 | 7F5FD5111EBDA4B200ACB2C0 /* Main.storyboard in Resources */, 214 | ); 215 | runOnlyForDeploymentPostprocessing = 0; 216 | }; 217 | /* End PBXResourcesBuildPhase section */ 218 | 219 | /* Begin PBXSourcesBuildPhase section */ 220 | 7F5FD5041EBDA4B200ACB2C0 /* Sources */ = { 221 | isa = PBXSourcesBuildPhase; 222 | buildActionMask = 2147483647; 223 | files = ( 224 | 7F7DAE1B1EEAA19300D4598F /* ContentViewController.swift in Sources */, 225 | 7F5FD50C1EBDA4B200ACB2C0 /* AppDelegate.swift in Sources */, 226 | 7F1F71F01EC72CE60077D070 /* GetWiFi.swift in Sources */, 227 | 7F7DAE1D1EEAAF7600D4598F /* PageViewController.swift in Sources */, 228 | 7F8E9F0B1EEF884100BFC6C9 /* OtherTableVC.swift in Sources */, 229 | 7F6B53611EC8859A0035E0CF /* WebViewController.swift in Sources */, 230 | 7F9E88B61EF504B1006C8371 /* SystemButton.swift in Sources */, 231 | 7F5FD51E1EBDB35900ACB2C0 /* SmartConfigViewController.swift in Sources */, 232 | 7FF5D2521EF7D029002429F2 /* CustomTextField.swift in Sources */, 233 | ); 234 | runOnlyForDeploymentPostprocessing = 0; 235 | }; 236 | /* End PBXSourcesBuildPhase section */ 237 | 238 | /* Begin PBXVariantGroup section */ 239 | 7F5FD50F1EBDA4B200ACB2C0 /* Main.storyboard */ = { 240 | isa = PBXVariantGroup; 241 | children = ( 242 | 7FA649261EF8F72600AECA36 /* Base */, 243 | 7FA6494D1EF8F93600AECA36 /* en */, 244 | 7FA6494E1EF8F93D00AECA36 /* zh-Hans */, 245 | ); 246 | name = Main.storyboard; 247 | sourceTree = ""; 248 | }; 249 | 7FA649571EF93FBC00AECA36 /* Localizable.strings */ = { 250 | isa = PBXVariantGroup; 251 | children = ( 252 | 7FA649561EF93FBC00AECA36 /* zh-Hans */, 253 | 7FA649581EF93FC100AECA36 /* en */, 254 | ); 255 | name = Localizable.strings; 256 | sourceTree = ""; 257 | }; 258 | /* End PBXVariantGroup section */ 259 | 260 | /* Begin XCBuildConfiguration section */ 261 | 7F5FD5181EBDA4B200ACB2C0 /* Debug */ = { 262 | isa = XCBuildConfiguration; 263 | buildSettings = { 264 | ALWAYS_SEARCH_USER_PATHS = NO; 265 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 266 | CLANG_ANALYZER_NONNULL = YES; 267 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 268 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 269 | CLANG_CXX_LIBRARY = "libc++"; 270 | CLANG_ENABLE_MODULES = YES; 271 | CLANG_ENABLE_OBJC_ARC = YES; 272 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 273 | CLANG_WARN_BOOL_CONVERSION = YES; 274 | CLANG_WARN_COMMA = YES; 275 | CLANG_WARN_CONSTANT_CONVERSION = YES; 276 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 277 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 278 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 279 | CLANG_WARN_EMPTY_BODY = YES; 280 | CLANG_WARN_ENUM_CONVERSION = YES; 281 | CLANG_WARN_INFINITE_RECURSION = YES; 282 | CLANG_WARN_INT_CONVERSION = YES; 283 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 284 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 285 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 286 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 287 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 288 | CLANG_WARN_STRICT_PROTOTYPES = YES; 289 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 290 | CLANG_WARN_UNREACHABLE_CODE = YES; 291 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 292 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 293 | COPY_PHASE_STRIP = NO; 294 | DEBUG_INFORMATION_FORMAT = dwarf; 295 | ENABLE_STRICT_OBJC_MSGSEND = YES; 296 | ENABLE_TESTABILITY = YES; 297 | GCC_C_LANGUAGE_STANDARD = gnu99; 298 | GCC_DYNAMIC_NO_PIC = NO; 299 | GCC_NO_COMMON_BLOCKS = YES; 300 | GCC_OPTIMIZATION_LEVEL = 0; 301 | GCC_PREPROCESSOR_DEFINITIONS = ( 302 | "DEBUG=1", 303 | "$(inherited)", 304 | ); 305 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 306 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 307 | GCC_WARN_UNDECLARED_SELECTOR = YES; 308 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 309 | GCC_WARN_UNUSED_FUNCTION = YES; 310 | GCC_WARN_UNUSED_VARIABLE = YES; 311 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 312 | MTL_ENABLE_DEBUG_INFO = YES; 313 | ONLY_ACTIVE_ARCH = YES; 314 | SDKROOT = iphoneos; 315 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 316 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 317 | TARGETED_DEVICE_FAMILY = "1,2"; 318 | }; 319 | name = Debug; 320 | }; 321 | 7F5FD5191EBDA4B200ACB2C0 /* Release */ = { 322 | isa = XCBuildConfiguration; 323 | buildSettings = { 324 | ALWAYS_SEARCH_USER_PATHS = NO; 325 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 326 | CLANG_ANALYZER_NONNULL = YES; 327 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 328 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 329 | CLANG_CXX_LIBRARY = "libc++"; 330 | CLANG_ENABLE_MODULES = YES; 331 | CLANG_ENABLE_OBJC_ARC = YES; 332 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 333 | CLANG_WARN_BOOL_CONVERSION = YES; 334 | CLANG_WARN_COMMA = YES; 335 | CLANG_WARN_CONSTANT_CONVERSION = YES; 336 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 337 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 338 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 339 | CLANG_WARN_EMPTY_BODY = YES; 340 | CLANG_WARN_ENUM_CONVERSION = YES; 341 | CLANG_WARN_INFINITE_RECURSION = YES; 342 | CLANG_WARN_INT_CONVERSION = YES; 343 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 344 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 345 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 346 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 347 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 348 | CLANG_WARN_STRICT_PROTOTYPES = YES; 349 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 350 | CLANG_WARN_UNREACHABLE_CODE = YES; 351 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 352 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 353 | COPY_PHASE_STRIP = NO; 354 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 355 | ENABLE_NS_ASSERTIONS = NO; 356 | ENABLE_STRICT_OBJC_MSGSEND = YES; 357 | GCC_C_LANGUAGE_STANDARD = gnu99; 358 | GCC_NO_COMMON_BLOCKS = YES; 359 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 360 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 361 | GCC_WARN_UNDECLARED_SELECTOR = YES; 362 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 363 | GCC_WARN_UNUSED_FUNCTION = YES; 364 | GCC_WARN_UNUSED_VARIABLE = YES; 365 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 366 | MTL_ENABLE_DEBUG_INFO = NO; 367 | SDKROOT = iphoneos; 368 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 369 | TARGETED_DEVICE_FAMILY = "1,2"; 370 | VALIDATE_PRODUCT = YES; 371 | }; 372 | name = Release; 373 | }; 374 | 7F5FD51B1EBDA4B200ACB2C0 /* Debug */ = { 375 | isa = XCBuildConfiguration; 376 | buildSettings = { 377 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 378 | CLANG_ENABLE_MODULES = YES; 379 | CODE_SIGN_ENTITLEMENTS = SmartConfig/SmartConfig.entitlements; 380 | CODE_SIGN_IDENTITY = "Apple Development"; 381 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 382 | "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; 383 | CODE_SIGN_STYLE = Automatic; 384 | DEVELOPMENT_TEAM = 6687NJS8Y9; 385 | INFOPLIST_FILE = SmartConfig/Info.plist; 386 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 387 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 388 | LIBRARY_SEARCH_PATHS = ( 389 | "$(inherited)", 390 | "$(PROJECT_DIR)/SmartConfig/ESPtouch", 391 | ); 392 | PRODUCT_BUNDLE_IDENTIFIER = me.loulan.smartconfig; 393 | PRODUCT_NAME = "$(TARGET_NAME)"; 394 | PROVISIONING_PROFILE_SPECIFIER = ""; 395 | SUPPORTS_MACCATALYST = YES; 396 | SWIFT_OBJC_BRIDGING_HEADER = "SmartConfig/SmartConfig-Bridging-Header.h"; 397 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 398 | SWIFT_SWIFT3_OBJC_INFERENCE = On; 399 | SWIFT_VERSION = 3.0; 400 | }; 401 | name = Debug; 402 | }; 403 | 7F5FD51C1EBDA4B200ACB2C0 /* Release */ = { 404 | isa = XCBuildConfiguration; 405 | buildSettings = { 406 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 407 | CLANG_ENABLE_MODULES = YES; 408 | CODE_SIGN_ENTITLEMENTS = SmartConfig/SmartConfig.entitlements; 409 | CODE_SIGN_IDENTITY = "Apple Development"; 410 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 411 | "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; 412 | CODE_SIGN_STYLE = Automatic; 413 | DEVELOPMENT_TEAM = 6687NJS8Y9; 414 | INFOPLIST_FILE = SmartConfig/Info.plist; 415 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 416 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 417 | LIBRARY_SEARCH_PATHS = ( 418 | "$(inherited)", 419 | "$(PROJECT_DIR)/SmartConfig/ESPtouch", 420 | ); 421 | PRODUCT_BUNDLE_IDENTIFIER = me.loulan.smartconfig; 422 | PRODUCT_NAME = "$(TARGET_NAME)"; 423 | PROVISIONING_PROFILE_SPECIFIER = ""; 424 | SUPPORTS_MACCATALYST = YES; 425 | SWIFT_OBJC_BRIDGING_HEADER = "SmartConfig/SmartConfig-Bridging-Header.h"; 426 | SWIFT_SWIFT3_OBJC_INFERENCE = On; 427 | SWIFT_VERSION = 3.0; 428 | }; 429 | name = Release; 430 | }; 431 | /* End XCBuildConfiguration section */ 432 | 433 | /* Begin XCConfigurationList section */ 434 | 7F5FD5031EBDA4B200ACB2C0 /* Build configuration list for PBXProject "SmartConfig" */ = { 435 | isa = XCConfigurationList; 436 | buildConfigurations = ( 437 | 7F5FD5181EBDA4B200ACB2C0 /* Debug */, 438 | 7F5FD5191EBDA4B200ACB2C0 /* Release */, 439 | ); 440 | defaultConfigurationIsVisible = 0; 441 | defaultConfigurationName = Release; 442 | }; 443 | 7F5FD51A1EBDA4B200ACB2C0 /* Build configuration list for PBXNativeTarget "SmartConfig" */ = { 444 | isa = XCConfigurationList; 445 | buildConfigurations = ( 446 | 7F5FD51B1EBDA4B200ACB2C0 /* Debug */, 447 | 7F5FD51C1EBDA4B200ACB2C0 /* Release */, 448 | ); 449 | defaultConfigurationIsVisible = 0; 450 | defaultConfigurationName = Release; 451 | }; 452 | /* End XCConfigurationList section */ 453 | }; 454 | rootObject = 7F5FD5001EBDA4B200ACB2C0 /* Project object */; 455 | } 456 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SmartConfig 4 | // 5 | // Created by 翟怀楼 on 2017/5/6. 6 | // Copyright © 2017年 翟怀楼. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | 20 | let pageController = UIPageControl.appearance() 21 | pageController.pageIndicatorTintColor = UIColor.lightGray 22 | pageController.currentPageIndicatorTintColor = UIColor.black 23 | pageController.backgroundColor = UIColor.white 24 | 25 | return true 26 | } 27 | 28 | func applicationWillResignActive(_ application: UIApplication) { 29 | // 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. 30 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 31 | } 32 | 33 | func applicationDidEnterBackground(_ application: UIApplication) { 34 | // 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. 35 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 36 | } 37 | 38 | func applicationWillEnterForeground(_ application: UIApplication) { 39 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 40 | } 41 | 42 | func applicationDidBecomeActive(_ application: UIApplication) { 43 | // 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. 44 | } 45 | 46 | func applicationWillTerminate(_ application: UIApplication) { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | } 52 | 53 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "icon-20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "icon-20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "icon-29.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "icon-29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "icon-29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "icon-40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "icon-40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "57x57", 47 | "idiom" : "iphone", 48 | "filename" : "icon-57.png", 49 | "scale" : "1x" 50 | }, 51 | { 52 | "size" : "57x57", 53 | "idiom" : "iphone", 54 | "filename" : "icon-57@2x.png", 55 | "scale" : "2x" 56 | }, 57 | { 58 | "size" : "60x60", 59 | "idiom" : "iphone", 60 | "filename" : "icon-60@2x.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "60x60", 65 | "idiom" : "iphone", 66 | "filename" : "icon-60@3x.png", 67 | "scale" : "3x" 68 | }, 69 | { 70 | "size" : "20x20", 71 | "idiom" : "ipad", 72 | "filename" : "icon-20-ipad.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "20x20", 77 | "idiom" : "ipad", 78 | "filename" : "icon-20@2x-ipad.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "29x29", 83 | "idiom" : "ipad", 84 | "filename" : "icon-29-ipad.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "29x29", 89 | "idiom" : "ipad", 90 | "filename" : "icon-29@2x-ipad.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "40x40", 95 | "idiom" : "ipad", 96 | "filename" : "icon-40.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "40x40", 101 | "idiom" : "ipad", 102 | "filename" : "icon-40@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "50x50", 107 | "idiom" : "ipad", 108 | "filename" : "icon-50.png", 109 | "scale" : "1x" 110 | }, 111 | { 112 | "size" : "50x50", 113 | "idiom" : "ipad", 114 | "filename" : "icon-50@2x.png", 115 | "scale" : "2x" 116 | }, 117 | { 118 | "size" : "72x72", 119 | "idiom" : "ipad", 120 | "filename" : "icon-72.png", 121 | "scale" : "1x" 122 | }, 123 | { 124 | "size" : "72x72", 125 | "idiom" : "ipad", 126 | "filename" : "icon-72@2x.png", 127 | "scale" : "2x" 128 | }, 129 | { 130 | "size" : "76x76", 131 | "idiom" : "ipad", 132 | "filename" : "icon-76.png", 133 | "scale" : "1x" 134 | }, 135 | { 136 | "size" : "76x76", 137 | "idiom" : "ipad", 138 | "filename" : "icon-76@2x.png", 139 | "scale" : "2x" 140 | }, 141 | { 142 | "size" : "83.5x83.5", 143 | "idiom" : "ipad", 144 | "filename" : "icon-83.5@2x.png", 145 | "scale" : "2x" 146 | }, 147 | { 148 | "idiom" : "ios-marketing", 149 | "size" : "1024x1024", 150 | "scale" : "1x" 151 | } 152 | ], 153 | "info" : { 154 | "version" : 1, 155 | "author" : "xcode" 156 | } 157 | } -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-20-ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-20-ipad.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-20@2x-ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-20@2x-ipad.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-29-ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-29-ipad.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-29.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-29@2x-ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-29@2x-ipad.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-40.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-50.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-50@2x.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-57.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-57@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-57@2x.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-72.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-76.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/Config-1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "Custom Preset.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/Config-1.imageset/Custom Preset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/Config-1.imageset/Custom Preset.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/Config.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "Custom Preset.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/Config.imageset/Custom Preset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/Config.imageset/Custom Preset.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/ESP8266.imageset/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/ESP8266.imageset/1.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/ESP8266.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "1.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/More-1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "more-1.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/More-1.imageset/more-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/More-1.imageset/more-1.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/More.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "more.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/More.imageset/more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/More.imageset/more.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/NodeMCU.imageset/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/NodeMCU.imageset/3.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/NodeMCU.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "3.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/NodeMCU32S.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "NodeMCU32S.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/NodeMCU32S.imageset/NodeMCU32S.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/NodeMCU32S.imageset/NodeMCU32S.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/Pin-1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "Custom Preset.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/Pin-1.imageset/Custom Preset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/Pin-1.imageset/Custom Preset.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/Pin.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "引脚-未选中状态.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/Pin.imageset/引脚-未选中状态.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/Pin.imageset/引脚-未选中状态.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/Wi-Fi 背景.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Wi-Fi 背景.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Assets.xcassets/Wi-Fi 背景.imageset/Wi-Fi 背景.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/Assets.xcassets/Wi-Fi 背景.imageset/Wi-Fi 背景.png -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/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 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/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 | 35 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 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 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 228 | 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 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Controller/ContentViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentViewController.swift 3 | // SmartConfig 4 | // 5 | // Created by 翟怀楼 on 2017/6/9. 6 | // Copyright © 2017年 翟怀楼. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ContentViewController: UIViewController { 12 | 13 | @IBOutlet weak var imageView: UIImageView! 14 | @IBOutlet weak var imageTitle: UILabel! 15 | 16 | var pageIndex: Int! 17 | var titleText: String! 18 | var imageFile: String! 19 | 20 | override func viewDidLoad() { 21 | super.viewDidLoad() 22 | 23 | self.imageView.image = UIImage(named: imageFile) 24 | self.imageTitle.text = self.titleText 25 | 26 | } 27 | 28 | override func didReceiveMemoryWarning() { 29 | super.didReceiveMemoryWarning() 30 | // Dispose of any resources that can be recreated. 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Controller/OtherTableVC.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OtherTableVC.swift 3 | // SmartConfig 4 | // 5 | // Created by 翟怀楼 on 2017/6/13. 6 | // Copyright © 2017年 翟怀楼. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class OtherTableVC: UITableViewController { 12 | 13 | let htmlFileStrings = ["HTML/SmartConfig", "HTML/OpenSource", "", ""] 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | } 18 | 19 | override func didReceiveMemoryWarning() { 20 | super.didReceiveMemoryWarning() 21 | } 22 | 23 | 24 | // MARK: - Table view data source 25 | 26 | override func numberOfSections(in tableView: UITableView) -> Int { 27 | return 2 28 | } 29 | 30 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 31 | if section == 0 { 32 | return 2 33 | } 34 | 35 | if section == 1 { 36 | return 1 37 | } 38 | 39 | return 0 40 | } 41 | 42 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 43 | tableView.deselectRow(at: indexPath, animated: true) 44 | 45 | if indexPath == [0, 0] 46 | { 47 | let vc = self.storyboard?.instantiateViewController(withIdentifier: "WebViewController") as! WebViewController 48 | vc.htmlFileString = htmlFileStrings[indexPath.row] 49 | self.navigationController?.pushViewController(vc, animated: true) 50 | } 51 | 52 | if indexPath == [0, 1] 53 | { 54 | let vc = self.storyboard?.instantiateViewController(withIdentifier: "WebViewController") as! WebViewController 55 | vc.htmlFileString = htmlFileStrings[indexPath.row] 56 | self.navigationController?.pushViewController(vc, animated: true) 57 | } 58 | 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Controller/PageViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PageViewController.swift 3 | // SmartConfig 4 | // 5 | // Created by 翟怀楼 on 2017/6/9. 6 | // Copyright © 2017年 翟怀楼. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class PageViewController: UIViewController, UIPageViewControllerDataSource { 12 | 13 | var pageViewController: UIPageViewController! 14 | var pageTitles:NSArray! 15 | var pageImaages:NSArray! 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | 20 | let espTitle = "ESP-07 08 12E " + NSLocalizedString("MINIMAL_SYSTEMS", comment: "") 21 | 22 | self.pageTitles = NSArray(objects: "ESP8266 NodeMCU", "ESP32S NodeMCU", espTitle) 23 | self.pageImaages = NSArray(objects: "NodeMCU", "NodeMCU32S", "ESP8266") 24 | 25 | self.pageViewController = self.storyboard?.instantiateViewController(withIdentifier: "PageViewController") as! UIPageViewController 26 | self.pageViewController.dataSource = self 27 | 28 | let startVC = self.viewControllerAtIndex(index: 0) as ContentViewController 29 | let viewControllers = NSArray(object: startVC) 30 | 31 | self.pageViewController.setViewControllers(viewControllers as? [UIViewController], direction: .forward, animated: true, completion: nil) 32 | 33 | self.pageViewController.view.frame = CGRect(x: 0, y: 30, width: self.view.frame.width, height: self.view.frame.height - 80) 34 | 35 | self.addChildViewController(self.pageViewController) 36 | self.view.addSubview(self.pageViewController.view) 37 | self.pageViewController.didMove(toParentViewController: self) 38 | 39 | } 40 | 41 | override func didReceiveMemoryWarning() { 42 | super.didReceiveMemoryWarning() 43 | // Dispose of any resources that can be recreated. 44 | } 45 | 46 | func viewControllerAtIndex(index: Int) -> ContentViewController { 47 | 48 | if (self.pageTitles.count == 0 || index >= self.pageTitles.count) 49 | { 50 | return ContentViewController() 51 | } 52 | 53 | let vc: ContentViewController = self.storyboard?.instantiateViewController(withIdentifier: "ContentViewController") as! ContentViewController 54 | 55 | vc.imageFile = self.pageImaages[index] as! String 56 | vc.titleText = self.pageTitles[index] as! String 57 | vc.pageIndex = index 58 | 59 | return vc 60 | 61 | } 62 | 63 | // MARK: - Page View Controller Data Source 64 | 65 | func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { 66 | 67 | let vc = viewController as! ContentViewController 68 | var index = vc.pageIndex as Int 69 | 70 | if (index == 0 || index == NSNotFound) 71 | { 72 | return nil 73 | } 74 | 75 | index = index - 1 76 | return self.viewControllerAtIndex(index: index) 77 | 78 | } 79 | 80 | func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { 81 | 82 | let vc = viewController as! ContentViewController 83 | var index = vc.pageIndex as Int 84 | 85 | if (index == NSNotFound) 86 | { 87 | return nil 88 | } 89 | 90 | index = index + 1 91 | 92 | if index == self.pageTitles.count 93 | { 94 | return nil 95 | } 96 | 97 | return self.viewControllerAtIndex(index: index) 98 | } 99 | 100 | func presentationCount(for pageViewController: UIPageViewController) -> Int { 101 | return self.pageTitles.count 102 | } 103 | 104 | func presentationIndex(for pageViewController: UIPageViewController) -> Int { 105 | return 0 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Controller/SmartConfigViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SmartConfig.swift 3 | // SmartConfig 4 | // 5 | // Created by 翟怀楼 on 2017/5/6. 6 | // Copyright © 2017年 翟怀楼. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SmartConfigViewController: UIViewController { 12 | 13 | var SSID:String = "" 14 | var PASS:String = "" 15 | var BSSID:String = "" 16 | 17 | var isConfirmState: Bool! 18 | 19 | var condition:NSCondition! 20 | var esptouchTask: ESPTouchTask! 21 | var esptouchDelegate: EspTouchDelegateImpl! 22 | 23 | @IBOutlet weak var wifiName: UILabel! 24 | @IBOutlet weak var wifiPass: CustomTextField! 25 | 26 | @IBOutlet weak var spinner: UIActivityIndicatorView! 27 | 28 | @IBOutlet weak var confirmCancelBtn: SystemButton! 29 | 30 | @IBAction func tapConfirmForResult(_ sender: SystemButton) { 31 | if isConnectWiFi() { 32 | if wifiPass.text != "" { 33 | SSID = getwifi().getSSID()! 34 | PASS = wifiPass.text! 35 | BSSID = getwifi().getBSSID()! 36 | self.tapConfirmForResult() 37 | } else { 38 | let title = NSLocalizedString("WIFI_INPUT_PASSWORD", comment: "") 39 | let butonTitle = NSLocalizedString("CONFIRM", comment: "") 40 | 41 | let alert = UIAlertController(title: title, message: nil, preferredStyle: .alert) 42 | let doneButton = UIAlertAction(title: butonTitle, style: .default, handler: nil) 43 | alert.addAction(doneButton) 44 | self.present(alert, animated: true, completion: nil) 45 | } 46 | 47 | } else { 48 | let title = NSLocalizedString("WIFI_DISCONNECTED", comment: "") 49 | let butonTitle = NSLocalizedString("CONFIRM", comment: "") 50 | let alert = UIAlertController(title: title, message: nil, preferredStyle: .alert) 51 | let doneButton = UIAlertAction(title: butonTitle, style: .default, handler: nil) 52 | alert.addAction(doneButton) 53 | self.present(alert, animated: true, completion: nil) 54 | return 55 | } 56 | } 57 | 58 | 59 | override func viewDidLoad() { 60 | super.viewDidLoad() 61 | 62 | // 解决导航栏跳转变黑1s的BUG 63 | self.navigationController?.view.backgroundColor = UIColor.white 64 | 65 | // 初始化同步锁 66 | condition = NSCondition() 67 | 68 | // 代理 69 | esptouchDelegate = EspTouchDelegateImpl() 70 | 71 | // 初始化按钮配置状态 72 | self.isConfirmState = false 73 | 74 | enableConfirmBtn() 75 | 76 | } 77 | 78 | override func viewWillAppear(_ animated: Bool) { 79 | // 每次载入都刷新无线网络的状态 80 | loadingNetworkStatus() 81 | } 82 | 83 | override func didReceiveMemoryWarning() { 84 | super.didReceiveMemoryWarning() 85 | // Dispose of any resources that can be recreated. 86 | } 87 | 88 | func loadingNetworkStatus() { 89 | let wifiSSID = getwifi().getSSID() 90 | 91 | guard wifiSSID != nil else { 92 | let text = NSLocalizedString("WIFI_DISCONNECTED", comment: "") 93 | wifiName.text = text 94 | return 95 | } 96 | let text = NSLocalizedString("WIFI_CONNECTED", comment: "") 97 | wifiName.text = text + wifiSSID! 98 | } 99 | 100 | func isConnectWiFi() -> Bool { 101 | let wifiSSID = getwifi().getSSID() 102 | return wifiSSID != nil ? true : false 103 | } 104 | 105 | 106 | func tapConfirmForResult() { 107 | if isConfirmState { 108 | spinner.startAnimating() 109 | enableCancelBtn() 110 | print("正在进行配置...") 111 | let queue = DispatchQueue.global(qos: .default) 112 | queue.async { 113 | print("线程正在工作...") 114 | let esptouchResult: ESPTouchResult = self.executeForResult() 115 | DispatchQueue.main.async(execute: { 116 | self.spinner.stopAnimating() 117 | self.enableConfirmBtn() 118 | 119 | let resultTitle = NSLocalizedString("RESULT_TITLE", comment: "") 120 | let confirmSring = NSLocalizedString("CONFIRM", comment: "") 121 | 122 | if !esptouchResult.isCancelled { 123 | UIAlertView(title: resultTitle, message: esptouchResult.description, delegate: nil, cancelButtonTitle: confirmSring).show() 124 | // IP拼接 125 | /* 126 | let strIP = String(esptouchResult.ipAddrData[0]) + "." + String(esptouchResult.ipAddrData[1]) + "." + String(esptouchResult.ipAddrData[2]) + "." + String(esptouchResult.ipAddrData[3]) 127 | print("⭕️\(strIP)") 128 | */ 129 | } 130 | }) 131 | } 132 | } else { 133 | self.spinner.stopAnimating() 134 | self.enableConfirmBtn() 135 | print("取消配置...") 136 | self.cancel() 137 | } 138 | } 139 | 140 | /* 改变按钮状态 */ 141 | func enableCancelBtn() { 142 | isConfirmState = false 143 | let title = NSLocalizedString("CONFIG_BUTTON_CANCEL", comment: "") 144 | confirmCancelBtn.setTitle(title, for: .normal) 145 | } 146 | func enableConfirmBtn() { 147 | isConfirmState = true 148 | let title = NSLocalizedString("CONFIG_BUTTON_CONFIRM", comment: "") 149 | confirmCancelBtn.setTitle(title, for: .normal) 150 | } 151 | 152 | /* 配置结果 */ 153 | func executeForResult() -> ESPTouchResult { 154 | // 同步锁 155 | condition.lock() 156 | // 获得配置所需要的参数 157 | esptouchTask = ESPTouchTask(apSsid: SSID, andApBssid: BSSID, andApPwd: PASS) 158 | // 设置代理 159 | esptouchTask.setEsptouchDelegate(esptouchDelegate) 160 | condition.unlock() 161 | let esptouchResult: ESPTouchResult = self.esptouchTask.executeForResult() 162 | return esptouchResult 163 | } 164 | 165 | /* 取消配网 */ 166 | func cancel() { 167 | condition.lock() 168 | if self.esptouchTask != nil { 169 | self.esptouchTask.interrupt() 170 | } 171 | condition.unlock() 172 | } 173 | 174 | 175 | /* 点击空白隐藏键盘 */ 176 | override func touchesBegan(_ touches: Set, with event: UIEvent?) { 177 | self.view.endEditing(true) 178 | } 179 | 180 | func textFieldShouldReturn(_ textField: UITextField) -> Bool { 181 | textField.resignFirstResponder() 182 | return true 183 | } 184 | 185 | } 186 | 187 | class EspTouchDelegateImpl: NSObject, ESPTouchDelegate { 188 | 189 | @objc func dismissAlert(_ alertView: UIAlertView) { 190 | alertView.dismiss(withClickedButtonIndex: alertView.cancelButtonIndex, animated: true) 191 | } 192 | 193 | func showAlert(with result: ESPTouchResult) { 194 | let text = NSLocalizedString("WIFI_CONNECTION", comment: "") 195 | 196 | let message: String = result.bssid + text 197 | let dismissSeconds: TimeInterval = 3.5 198 | let alertView = UIAlertView(title: "", message: message, delegate: nil, cancelButtonTitle: nil) 199 | alertView.show() 200 | perform(#selector(self.dismissAlert), with: alertView, afterDelay: dismissSeconds) 201 | } 202 | 203 | func onEsptouchResultAdded(with result: ESPTouchResult) { 204 | print("EspTouchDelegateImpl onEsptouchResultAddedWithResult bssid: \(result.bssid)") 205 | // 放到主线程显示 206 | DispatchQueue.main.async(execute: {() -> Void in 207 | self.showAlert(with: result) 208 | }) 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Controller/WebViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SmartConfig 4 | // 5 | // Created by 翟怀楼 on 2017/5/14. 6 | // Copyright © 2017年 翟怀楼. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class WebViewController: UIViewController { 12 | 13 | var htmlFileString:String! 14 | 15 | @IBOutlet weak var webView: UIWebView! 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | 20 | // 进制页面拖动 21 | webView.scrollView.bounces = false 22 | 23 | // 加载HTML 24 | let path = Bundle.main.path(forResource: htmlFileString, ofType: "html") 25 | let url = URL(string: path!) 26 | 27 | webView.loadRequest(NSURLRequest(url: url!) as URLRequest) 28 | } 29 | 30 | override func didReceiveMemoryWarning() { 31 | super.didReceiveMemoryWarning() 32 | // Dispose of any resources that can be recreated. 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/ESPtouch/ESPTouchDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // ESPTouchDelegate.h 3 | // EspTouchDemo 4 | // 5 | // Created by 白 桦 on 8/14/15. 6 | // Copyright (c) 2015 白 桦. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ESPTouchResult.h" 11 | 12 | 13 | @protocol ESPTouchDelegate 14 | 15 | /** 16 | * when new esptouch result is added, the listener will call 17 | * onEsptouchResultAdded callback 18 | * 19 | * @param result 20 | * the Esptouch result 21 | */ 22 | -(void) onEsptouchResultAddedWithResult: (ESPTouchResult *) result; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/ESPtouch/ESPTouchResult.h: -------------------------------------------------------------------------------- 1 | // 2 | // ESPTouchResult.h 3 | // EspTouchDemo 4 | // 5 | // Created by 白 桦 on 4/14/15. 6 | // Copyright (c) 2015 白 桦. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ESPTouchResult : NSObject 12 | 13 | // it is used to check whether the esptouch task is executed suc 14 | @property (nonatomic,assign) BOOL isSuc; 15 | 16 | // it is used to store the device's bssid 17 | @property (nonatomic,strong) NSString * bssid; 18 | 19 | // it is used to check whether the esptouch task is cancelled by user 20 | @property (atomic,assign) BOOL isCancelled; 21 | 22 | // it is used to store the device's ip address 23 | @property (atomic) NSData * ipAddrData; 24 | 25 | /** 26 | * Constructor of EsptouchResult 27 | * 28 | * @param isSuc whether the esptouch task is executed suc 29 | * @param bssid the device's bssid 30 | * @param ipAddrData the device's ip address 31 | */ 32 | - (id) initWithIsSuc: (BOOL) isSuc andBssid: (NSString *) bssid andInetAddrData: (NSData *) ipAddrData; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/ESPtouch/ESPTouchTask.h: -------------------------------------------------------------------------------- 1 | // 2 | // ESPTouchTask.h 3 | // EspTouchDemo 4 | // 5 | // Created by 白 桦 on 4/14/15. 6 | // Copyright (c) 2015 白 桦. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ESPTouchResult.h" 11 | #import "ESPTouchDelegate.h" 12 | 13 | #define DEBUG_ON YES 14 | 15 | @interface ESPTouchTask : NSObject 16 | 17 | @property (atomic,assign) BOOL isCancelled; 18 | 19 | /** 20 | * Constructor of EsptouchTask 21 | * 22 | * @param apSsid 23 | * the Ap's ssid 24 | * @param apBssid 25 | * the Ap's bssid 26 | * @param apPassword 27 | * the Ap's password 28 | * @param isSsidHidden 29 | * whether the Ap's ssid is hidden 30 | */ 31 | - (id) initWithApSsid: (NSString *)apSsid andApBssid: (NSString *) apBssid andApPwd: (NSString *)apPwd; 32 | 33 | /** 34 | * Deprecated 35 | */ 36 | - (id) initWithApSsid: (NSString *)apSsid andApBssid: (NSString *) apBssid andApPwd: (NSString *)apPwd andIsSsidHiden: (BOOL) isSsidHidden __deprecated_msg("Use initWithApSsid:(NSString *) andApBssid:(NSString *) andApPwd:(NSString *) instead."); 37 | 38 | /** 39 | * Constructor of EsptouchTask 40 | * 41 | * @param apSsid 42 | * the Ap's ssid 43 | * @param apBssid 44 | * the Ap's bssid 45 | * @param apPassword 46 | * the Ap's password 47 | * @param isSsidHidden 48 | * whether the Ap's ssid is hidden 49 | * @param timeoutMillisecond(it should be >= 15000+6000) 50 | * millisecond of total timeout 51 | * @param context 52 | * the Context of the Application 53 | */ 54 | - (id) initWithApSsid: (NSString *)apSsid andApBssid: (NSString *) apBssid andApPwd: (NSString *)apPwd andTimeoutMillisecond: (int) timeoutMillisecond; 55 | 56 | /** 57 | * Constructor of EsptouchTask 58 | * 59 | * @param apSsid 60 | * the Ap's ssid 61 | * @param apBssid 62 | * the Ap's bssid 63 | * @param apPassword 64 | * the Ap's password 65 | * @param isSsidHidden 66 | * whether the Ap's ssid is hidden 67 | * @param timeoutMillisecond(it should be >= 15000+6000) 68 | * millisecond of total timeout 69 | * @param context 70 | * the Context of the Application 71 | */ 72 | - (id) initWithApSsid: (NSString *)apSsid andApBssid: (NSString *) apBssid andApPwd: (NSString *)apPwd andIsSsidHiden: (BOOL) isSsidHidden andTimeoutMillisecond: (int) timeoutMillisecond __deprecated_msg("Use initWithApSsid:(NSString *) andApBssid:(NSString *) andApPwd:(NSString *) andTimeoutMillisecond:(int) instead."); 73 | 74 | /** 75 | * Interrupt the Esptouch Task when User tap back or close the Application. 76 | */ 77 | - (void) interrupt; 78 | 79 | /** 80 | * Note: !!!Don't call the task at UI Main Thread 81 | * 82 | * Smart Config v2.4 support the API 83 | * 84 | * @return the ESPTouchResult 85 | */ 86 | - (ESPTouchResult*) executeForResult; 87 | 88 | /** 89 | * Note: !!!Don't call the task at UI Main Thread 90 | * 91 | * Smart Config v2.4 support the API 92 | * 93 | * It will be blocked until the client receive result count >= expectTaskResultCount. 94 | * If it fail, it will return one fail result will be returned in the list. 95 | * If it is cancelled while executing, 96 | * if it has received some results, all of them will be returned in the list. 97 | * if it hasn't received any results, one cancel result will be returned in the list. 98 | * 99 | * @param expectTaskResultCount 100 | * the expect result count(if expectTaskResultCount <= 0, 101 | * expectTaskResultCount = INT32_MAX) 102 | * @return the NSArray of EsptouchResult 103 | * @throws RuntimeException 104 | */ 105 | - (NSArray*) executeForResults:(int) expectTaskResultCount; 106 | 107 | /** 108 | * set the esptouch delegate, when one device is connected to the Ap, it will be called back 109 | * @param esptouchDelegate when one device is connected to the Ap, it will be called back 110 | */ 111 | - (void) setEsptouchDelegate: (NSObject *) esptouchDelegate; 112 | 113 | @end 114 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/ESPtouch/GetWiFi.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GetSSID.swift 3 | // Lightbulb 4 | // 5 | // Created by 翟怀楼 on 2017/4/4. 6 | // Copyright © 2017年 翟怀楼. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import SystemConfiguration.CaptiveNetwork 11 | 12 | // MARK: - 获取手机所连接无线网络的名称 13 | class getwifi : NSObject { 14 | 15 | func getSSID() -> String? { 16 | 17 | let interfaces = CNCopySupportedInterfaces() 18 | if interfaces == nil { 19 | return nil 20 | } 21 | 22 | let interfacesArray = interfaces as! [String] 23 | if interfacesArray.count <= 0 { 24 | return nil 25 | } 26 | 27 | let interfaceName = interfacesArray[0] as String 28 | let unsafeInterfaceData = CNCopyCurrentNetworkInfo(interfaceName as CFString) 29 | if unsafeInterfaceData == nil { 30 | return nil 31 | } 32 | 33 | let interfaceData = unsafeInterfaceData as! Dictionary 34 | 35 | return interfaceData["SSID"] as? String 36 | } 37 | 38 | func getBSSID() -> String? { 39 | 40 | let interfaces = CNCopySupportedInterfaces() 41 | if interfaces == nil { 42 | return nil 43 | } 44 | 45 | let interfacesArray = interfaces as! [String] 46 | if interfacesArray.count <= 0 { 47 | return nil 48 | } 49 | 50 | let interfaceName = interfacesArray[0] as String 51 | let unsafeInterfaceData = CNCopyCurrentNetworkInfo(interfaceName as CFString) 52 | if unsafeInterfaceData == nil { 53 | return nil 54 | } 55 | 56 | let interfaceData = unsafeInterfaceData as! Dictionary 57 | 58 | return interfaceData["BSSID"] as? String 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/ESPtouch/libEsptouch_v0.3.5.3.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/SmartConfig/SmartConfig/ESPtouch/libEsptouch_v0.3.5.3.a -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/HTML/OpenSource.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 开源组件协议许可 6 | 7 | 8 | 9 | 10 |
11 |

ESPTouch

12 |
13 |

ESPRSSIF MIT License ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD

14 |
15 |

Copyright © 2015

16 |

Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, it is free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 |

22 |
23 | 24 |
25 |
26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/HTML/SmartConfig.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 开发文档 6 | 7 | 8 | 9 | 10 |
11 |

SmartConfig

12 |
13 |

SmartConfig介绍

14 |
15 |

引入

16 |

17 | 随着无线网络的快速发展,越来越多的智能硬件开始接入无线网络。但是许多智能硬件没有配备通常没有用于输入WiFi网络名称和密码的显示屏或键盘。这就需要SmartConifg技术了,这是一种让你可以在没有和其他设备建立任何性质的通讯链路的情况下,配置该设备接入WiFi网络。 18 |

19 |
20 |
21 |

应用场景

22 |

23 | 虚构一个实际场景应该是这样:你买了一个带WiFi智能灯,不过这个摄像头没有USB, 没有以太网, 没有蓝牙, 没有NFC,那么问题来了,你如何让这个智能灯接入WiFi呢?SmartConfig就是用在这种场景下的。 24 |

25 |
26 |
27 |

使用步骤

28 |

29 | 如果这个摄像头的WiFi支持SmartConfig技术, 那么你只需这样几个步骤:
30 | 1.智能灯连接电源,进入配置模式。
31 | 2.打开SmartConfig应用接入WiFi,输入密码。
32 | 3.点击确认, 稍等片刻, 智能设备已经接入你家WiFi了。 33 |

34 |
35 |
36 |
37 | 38 | 39 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/HTML/css/weui.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * WeUI v1.1.2 (https://github.com/weui/weui) 3 | * Copyright 2017 Tencent, Inc. 4 | * Licensed under the MIT license 5 | */html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{line-height:1.6;font-family:-apple-system-font,Helvetica Neue,sans-serif}*{margin:0;padding:0}a img{border:0}a{text-decoration:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}@font-face{font-weight:400;font-style:normal;font-family:weui;src:url('data:application/octet-stream;base64,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') format('truetype')}[class*=" weui-icon-"],[class^=weui-icon-]{display:inline-block;vertical-align:middle;font:normal normal normal 14px/1 weui;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased}[class*=" weui-icon-"]:before,[class^=weui-icon-]:before{display:inline-block;margin-left:.2em;margin-right:.2em}.weui-icon-circle:before{content:"\EA01"}.weui-icon-download:before{content:"\EA02"}.weui-icon-info:before{content:"\EA03"}.weui-icon-safe-success:before{content:"\EA04"}.weui-icon-safe-warn:before{content:"\EA05"}.weui-icon-success:before{content:"\EA06"}.weui-icon-success-circle:before{content:"\EA07"}.weui-icon-success-no-circle:before{content:"\EA08"}.weui-icon-waiting:before{content:"\EA09"}.weui-icon-waiting-circle:before{content:"\EA0A"}.weui-icon-warn:before{content:"\EA0B"}.weui-icon-info-circle:before{content:"\EA0C"}.weui-icon-cancel:before{content:"\EA0D"}.weui-icon-search:before{content:"\EA0E"}.weui-icon-clear:before{content:"\EA0F"}.weui-icon-back:before{content:"\EA10"}.weui-icon-delete:before{content:"\EA11"}[class*=" weui-icon_"]:before,[class^=weui-icon_]:before{margin:0}.weui-icon-success{font-size:23px;color:#09bb07}.weui-icon-waiting{font-size:23px;color:#10aeff}.weui-icon-warn{font-size:23px;color:#f43530}.weui-icon-info{font-size:23px;color:#10aeff}.weui-icon-success-circle,.weui-icon-success-no-circle{font-size:23px;color:#09bb07}.weui-icon-waiting-circle{font-size:23px;color:#10aeff}.weui-icon-circle{font-size:23px;color:#c9c9c9}.weui-icon-download,.weui-icon-info-circle{font-size:23px;color:#09bb07}.weui-icon-safe-success{color:#09bb07}.weui-icon-safe-warn{color:#ffbe00}.weui-icon-cancel{color:#f43530;font-size:22px}.weui-icon-clear,.weui-icon-search{color:#b2b2b2;font-size:14px}.weui-icon-delete.weui-icon_gallery-delete{color:#fff;font-size:22px}.weui-icon_msg{font-size:93px}.weui-icon_msg.weui-icon-warn{color:#f76260}.weui-icon_msg-primary{font-size:93px}.weui-icon_msg-primary.weui-icon-warn{color:#ffbe00}.weui-btn{position:relative;display:block;margin-left:auto;margin-right:auto;padding-left:14px;padding-right:14px;box-sizing:border-box;font-size:18px;text-align:center;text-decoration:none;color:#fff;line-height:2.55555556;border-radius:5px;-webkit-tap-highlight-color:rgba(0,0,0,0);overflow:hidden}.weui-btn:after{content:" ";width:200%;height:200%;position:absolute;top:0;left:0;border:1px solid rgba(0,0,0,.2);-webkit-transform:scale(.5);transform:scale(.5);-webkit-transform-origin:0 0;transform-origin:0 0;box-sizing:border-box;border-radius:10px}.weui-btn_inline{display:inline-block}.weui-btn_default{color:#000;background-color:#f8f8f8}.weui-btn_default:not(.weui-btn_disabled):visited{color:#000}.weui-btn_default:not(.weui-btn_disabled):active{color:rgba(0,0,0,.6);background-color:#dedede}.weui-btn_primary{background-color:#1aad19}.weui-btn_primary:not(.weui-btn_disabled):visited{color:#fff}.weui-btn_primary:not(.weui-btn_disabled):active{color:hsla(0,0%,100%,.6);background-color:#179b16}.weui-btn_warn{background-color:#e64340}.weui-btn_warn:not(.weui-btn_disabled):visited{color:#fff}.weui-btn_warn:not(.weui-btn_disabled):active{color:hsla(0,0%,100%,.6);background-color:#ce3c39}.weui-btn_disabled{color:hsla(0,0%,100%,.6)}.weui-btn_disabled.weui-btn_default{color:rgba(0,0,0,.3);background-color:#f7f7f7}.weui-btn_disabled.weui-btn_primary{background-color:#9ed99d}.weui-btn_disabled.weui-btn_warn{background-color:#ec8b89}.weui-btn_loading .weui-loading{margin:-.2em .34em 0 0}.weui-btn_loading.weui-btn_primary,.weui-btn_loading.weui-btn_warn{color:hsla(0,0%,100%,.6)}.weui-btn_loading.weui-btn_primary{background-color:#179b16}.weui-btn_loading.weui-btn_warn{background-color:#ce3c39}.weui-btn_plain-primary{color:#1aad19;border:1px solid #1aad19}.weui-btn_plain-primary:not(.weui-btn_plain-disabled):active{color:rgba(26,173,25,.6);border-color:rgba(26,173,25,.6)}.weui-btn_plain-primary:after{border-width:0}.weui-btn_plain-default{color:#353535;border:1px solid #353535}.weui-btn_plain-default:not(.weui-btn_plain-disabled):active{color:rgba(53,53,53,.6);border-color:rgba(53,53,53,.6)}.weui-btn_plain-default:after{border-width:0}.weui-btn_plain-disabled{color:rgba(0,0,0,.2);border-color:rgba(0,0,0,.2)}button.weui-btn,input.weui-btn{width:100%;border-width:0;outline:0;-webkit-appearance:none}button.weui-btn:focus,input.weui-btn:focus{outline:0}button.weui-btn_inline,button.weui-btn_mini,input.weui-btn_inline,input.weui-btn_mini{width:auto}button.weui-btn_plain-default,button.weui-btn_plain-primary,input.weui-btn_plain-default,input.weui-btn_plain-primary{border-width:1px;background-color:transparent}.weui-btn_mini{display:inline-block;padding:0 1.32em;line-height:2.3;font-size:13px}.weui-btn+.weui-btn{margin-top:15px}.weui-btn.weui-btn_inline+.weui-btn.weui-btn_inline{margin-top:auto;margin-left:15px}.weui-btn-area{margin:1.17647059em 15px .3em}.weui-btn-area_inline{display:-webkit-box;display:-webkit-flex;display:flex}.weui-btn-area_inline .weui-btn{margin-top:auto;margin-right:15px;width:100%;-webkit-box-flex:1;-webkit-flex:1;flex:1}.weui-btn-area_inline .weui-btn:last-child{margin-right:0}.weui-cells{margin-top:1.17647059em;background-color:#fff;line-height:1.47058824;font-size:17px;overflow:hidden;position:relative}.weui-cells:before{top:0;border-top:1px solid #e5e5e5;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.weui-cells:after,.weui-cells:before{content:" ";position:absolute;left:0;right:0;height:1px;color:#e5e5e5;z-index:2}.weui-cells:after{bottom:0;border-bottom:1px solid #e5e5e5;-webkit-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.weui-cells__title{margin-top:.77em;margin-bottom:.3em;padding-left:15px;padding-right:15px;color:#999;font-size:14px}.weui-cells__title+.weui-cells{margin-top:0}.weui-cells__tips{margin-top:.3em;color:#999;padding-left:15px;padding-right:15px;font-size:14px}.weui-cell{padding:10px 15px;position:relative;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.weui-cell:before{content:" ";position:absolute;left:0;top:0;right:0;height:1px;border-top:1px solid #e5e5e5;color:#e5e5e5;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(.5);transform:scaleY(.5);left:15px;z-index:2}.weui-cell:first-child:before{display:none}.weui-cell_primary{-webkit-box-align:start;-webkit-align-items:flex-start;align-items:flex-start}.weui-cell__bd{-webkit-box-flex:1;-webkit-flex:1;flex:1}.weui-cell__ft{text-align:right;color:#999}.weui-cell_swiped{display:block;padding:0}.weui-cell_swiped>.weui-cell__bd{position:relative;z-index:1;background-color:#fff}.weui-cell_swiped>.weui-cell__ft{position:absolute;right:0;top:0;bottom:0;display:-webkit-box;display:-webkit-flex;display:flex;color:#fff}.weui-swiped-btn{display:block;padding:10px 1em;line-height:1.47058824;color:inherit}.weui-swiped-btn_default{background-color:#c7c7cc}.weui-swiped-btn_warn{background-color:#ff3b30}.weui-cell_access{-webkit-tap-highlight-color:rgba(0,0,0,0);color:inherit}.weui-cell_access:active{background-color:#ececec}.weui-cell_access .weui-cell__ft{padding-right:13px;position:relative}.weui-cell_access .weui-cell__ft:after{content:" ";display:inline-block;height:6px;width:6px;border-width:2px 2px 0 0;border-color:#c8c8cd;border-style:solid;-webkit-transform:matrix(.71,.71,-.71,.71,0,0);transform:matrix(.71,.71,-.71,.71,0,0);position:relative;top:-2px;position:absolute;top:50%;margin-top:-4px;right:2px}.weui-cell_link{color:#586c94;font-size:14px}.weui-cell_link:first-child:before{display:block}.weui-check__label{-webkit-tap-highlight-color:rgba(0,0,0,0)}.weui-check__label:active{background-color:#ececec}.weui-check{position:absolute;left:-9999em}.weui-cells_radio .weui-cell__ft{padding-left:.35em}.weui-cells_radio .weui-check:checked+.weui-icon-checked:before{display:block;content:'\EA08';color:#09bb07;font-size:16px}.weui-cells_checkbox .weui-cell__hd{padding-right:.35em}.weui-cells_checkbox .weui-icon-checked:before{content:'\EA01';color:#c9c9c9;font-size:23px;display:block}.weui-cells_checkbox .weui-check:checked+.weui-icon-checked:before{content:'\EA06';color:#09bb07}.weui-label{display:block;width:105px;word-wrap:break-word;word-break:break-all}.weui-input{width:100%;border:0;outline:0;-webkit-appearance:none;background-color:transparent;font-size:inherit;color:inherit;height:1.47058824em;line-height:1.47058824}.weui-input::-webkit-inner-spin-button,.weui-input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.weui-textarea{display:block;border:0;resize:none;width:100%;color:inherit;font-size:1em;line-height:inherit;outline:0}.weui-textarea-counter{color:#b2b2b2;text-align:right}.weui-cell_warn .weui-textarea-counter{color:#e64340}.weui-toptips{display:none;position:fixed;-webkit-transform:translateZ(0);transform:translateZ(0);top:0;left:0;right:0;padding:5px;font-size:14px;text-align:center;color:#fff;z-index:5000;word-wrap:break-word;word-break:break-all}.weui-toptips_warn{background-color:#e64340}.weui-cells_form .weui-cell__ft{font-size:0}.weui-cells_form .weui-icon-warn{display:none}.weui-cells_form input,.weui-cells_form label[for],.weui-cells_form textarea{-webkit-tap-highlight-color:rgba(0,0,0,0)}.weui-cell_warn{color:#e64340}.weui-cell_warn .weui-icon-warn{display:inline-block}.weui-form-preview{position:relative;background-color:#fff}.weui-form-preview:before{top:0;border-top:1px solid #e5e5e5;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.weui-form-preview:after,.weui-form-preview:before{content:" ";position:absolute;left:0;right:0;height:1px;color:#e5e5e5}.weui-form-preview:after{bottom:0;border-bottom:1px solid #e5e5e5;-webkit-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.weui-form-preview__hd{position:relative;padding:10px 15px;text-align:right;line-height:2.5em}.weui-form-preview__hd:after{content:" ";position:absolute;left:0;bottom:0;right:0;height:1px;border-bottom:1px solid #e5e5e5;color:#e5e5e5;-webkit-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:scaleY(.5);transform:scaleY(.5);left:15px}.weui-form-preview__hd .weui-form-preview__value{font-style:normal;font-size:1.6em}.weui-form-preview__bd{padding:10px 15px;font-size:.9em;text-align:right;color:#999;line-height:2}.weui-form-preview__ft{position:relative;line-height:50px;display:-webkit-box;display:-webkit-flex;display:flex}.weui-form-preview__ft:before{content:" ";position:absolute;left:0;top:0;right:0;height:1px;border-top:1px solid #d5d5d6;color:#d5d5d6;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.weui-form-preview__item{overflow:hidden}.weui-form-preview__label{float:left;margin-right:1em;min-width:4em;color:#999;text-align:justify;text-align-last:justify}.weui-form-preview__value{display:block;overflow:hidden;word-break:normal;word-wrap:break-word}.weui-form-preview__btn{position:relative;display:block;-webkit-box-flex:1;-webkit-flex:1;flex:1;color:#3cc51f;text-align:center;-webkit-tap-highlight-color:rgba(0,0,0,0)}button.weui-form-preview__btn{background-color:transparent;border:0;outline:0;line-height:inherit;font-size:inherit}.weui-form-preview__btn:active{background-color:#eee}.weui-form-preview__btn:after{content:" ";position:absolute;left:0;top:0;width:1px;bottom:0;border-left:1px solid #d5d5d6;color:#d5d5d6;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleX(.5);transform:scaleX(.5)}.weui-form-preview__btn:first-child:after{display:none}.weui-form-preview__btn_default{color:#999}.weui-form-preview__btn_primary{color:#0bb20c}.weui-cell_select{padding:0}.weui-cell_select .weui-select{padding-right:30px}.weui-cell_select .weui-cell__bd:after{content:" ";display:inline-block;height:6px;width:6px;border-width:2px 2px 0 0;border-color:#c8c8cd;border-style:solid;-webkit-transform:matrix(.71,.71,-.71,.71,0,0);transform:matrix(.71,.71,-.71,.71,0,0);position:relative;top:-2px;position:absolute;top:50%;right:15px;margin-top:-4px}.weui-select{-webkit-appearance:none;border:0;outline:0;background-color:transparent;width:100%;font-size:inherit;height:45px;line-height:45px;position:relative;z-index:1;padding-left:15px}.weui-cell_select-before{padding-right:15px}.weui-cell_select-before .weui-select{width:105px;box-sizing:border-box}.weui-cell_select-before .weui-cell__hd{position:relative}.weui-cell_select-before .weui-cell__hd:after{content:" ";position:absolute;right:0;top:0;width:1px;bottom:0;border-right:1px solid #e5e5e5;color:#e5e5e5;-webkit-transform-origin:100% 0;transform-origin:100% 0;-webkit-transform:scaleX(.5);transform:scaleX(.5)}.weui-cell_select-before .weui-cell__hd:before{content:" ";display:inline-block;height:6px;width:6px;border-width:2px 2px 0 0;border-color:#c8c8cd;border-style:solid;-webkit-transform:matrix(.71,.71,-.71,.71,0,0);transform:matrix(.71,.71,-.71,.71,0,0);position:relative;top:-2px;position:absolute;top:50%;right:15px;margin-top:-4px}.weui-cell_select-before .weui-cell__bd{padding-left:15px}.weui-cell_select-before .weui-cell__bd:after{display:none}.weui-cell_select-after{padding-left:15px}.weui-cell_select-after .weui-select{padding-left:0}.weui-cell_vcode{padding-top:0;padding-right:0;padding-bottom:0}.weui-vcode-btn,.weui-vcode-img{margin-left:5px;height:45px;vertical-align:middle}.weui-vcode-btn{display:inline-block;padding:0 .6em 0 .7em;border-left:1px solid #e5e5e5;line-height:45px;font-size:17px;color:#3cc51f}button.weui-vcode-btn{background-color:transparent;border-top:0;border-right:0;border-bottom:0;outline:0}.weui-vcode-btn:active{color:#52a341}.weui-gallery{display:none;position:fixed;top:0;right:0;bottom:0;left:0;background-color:#000;z-index:1000}.weui-gallery__img{position:absolute;top:0;right:0;bottom:60px;left:0;background:50% no-repeat;background-size:contain}.weui-gallery__opr{position:absolute;right:0;bottom:0;left:0;background-color:#0d0d0d;color:#fff;line-height:60px;text-align:center}.weui-gallery__del{display:block}.weui-cell_switch{padding-top:6.5px;padding-bottom:6.5px}.weui-switch{-webkit-appearance:none;appearance:none}.weui-switch,.weui-switch-cp__box{position:relative;width:52px;height:32px;border:1px solid #dfdfdf;outline:0;border-radius:16px;box-sizing:border-box;background-color:#dfdfdf;-webkit-transition:background-color .1s,border .1s;transition:background-color .1s,border .1s}.weui-switch-cp__box:before,.weui-switch:before{content:" ";position:absolute;top:0;left:0;width:50px;height:30px;border-radius:15px;background-color:#fdfdfd;-webkit-transition:-webkit-transform .35s cubic-bezier(.45,1,.4,1);transition:-webkit-transform .35s cubic-bezier(.45,1,.4,1);transition:transform .35s cubic-bezier(.45,1,.4,1);transition:transform .35s cubic-bezier(.45,1,.4,1),-webkit-transform .35s cubic-bezier(.45,1,.4,1)}.weui-switch-cp__box:after,.weui-switch:after{content:" ";position:absolute;top:0;left:0;width:30px;height:30px;border-radius:15px;background-color:#fff;box-shadow:0 1px 3px rgba(0,0,0,.4);-webkit-transition:-webkit-transform .35s cubic-bezier(.4,.4,.25,1.35);transition:-webkit-transform .35s cubic-bezier(.4,.4,.25,1.35);transition:transform .35s cubic-bezier(.4,.4,.25,1.35);transition:transform .35s cubic-bezier(.4,.4,.25,1.35),-webkit-transform .35s cubic-bezier(.4,.4,.25,1.35)}.weui-switch-cp__input:checked~.weui-switch-cp__box,.weui-switch:checked{border-color:#04be02;background-color:#04be02}.weui-switch-cp__input:checked~.weui-switch-cp__box:before,.weui-switch:checked:before{-webkit-transform:scale(0);transform:scale(0)}.weui-switch-cp__input:checked~.weui-switch-cp__box:after,.weui-switch:checked:after{-webkit-transform:translateX(20px);transform:translateX(20px)}.weui-switch-cp__input{position:absolute;left:-9999px}.weui-switch-cp__box{display:block}.weui-uploader__hd{display:-webkit-box;display:-webkit-flex;display:flex;padding-bottom:10px;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.weui-uploader__title{-webkit-box-flex:1;-webkit-flex:1;flex:1}.weui-uploader__info{color:#b2b2b2}.weui-uploader__bd{margin-bottom:-4px;margin-right:-9px;overflow:hidden}.weui-uploader__files{list-style:none}.weui-uploader__file{float:left;margin-right:9px;margin-bottom:9px;width:79px;height:79px;background:no-repeat 50%;background-size:cover}.weui-uploader__file_status{position:relative}.weui-uploader__file_status:before{content:" ";position:absolute;top:0;right:0;bottom:0;left:0;background-color:rgba(0,0,0,.5)}.weui-uploader__file_status .weui-uploader__file-content{display:block}.weui-uploader__file-content{display:none;position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);color:#fff}.weui-uploader__file-content .weui-icon-warn{display:inline-block}.weui-uploader__input-box{float:left;position:relative;margin-right:9px;margin-bottom:9px;width:77px;height:77px;border:1px solid #d9d9d9}.weui-uploader__input-box:after,.weui-uploader__input-box:before{content:" ";position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);background-color:#d9d9d9}.weui-uploader__input-box:before{width:2px;height:39.5px}.weui-uploader__input-box:after{width:39.5px;height:2px}.weui-uploader__input-box:active{border-color:#999}.weui-uploader__input-box:active:after,.weui-uploader__input-box:active:before{background-color:#999}.weui-uploader__input{position:absolute;z-index:1;top:0;left:0;width:100%;height:100%;opacity:0;-webkit-tap-highlight-color:rgba(0,0,0,0)}.weui-msg{padding-top:36px;text-align:center}.weui-msg__icon-area{margin-bottom:30px}.weui-msg__text-area{margin-bottom:25px;padding:0 20px}.weui-msg__text-area a{color:#586c94}.weui-msg__title{margin-bottom:5px;font-weight:400;font-size:20px}.weui-msg__desc{font-size:14px;color:#999}.weui-msg__opr-area{margin-bottom:25px}.weui-msg__extra-area{margin-bottom:15px;font-size:14px;color:#999}.weui-msg__extra-area a{color:#586c94}@media screen and (min-height:438px){.weui-msg__extra-area{position:fixed;left:0;bottom:0;width:100%;text-align:center}}.weui-article{padding:20px 15px;font-size:15px}.weui-article section{margin-bottom:1.5em}.weui-article h1{font-size:18px;font-weight:400;margin-bottom:.9em}.weui-article h2{font-size:16px}.weui-article h2,.weui-article h3{font-weight:400;margin-bottom:.34em}.weui-article h3{font-size:15px}.weui-article *{max-width:100%;box-sizing:border-box;word-wrap:break-word}.weui-article p{margin:0 0 .8em}.weui-tabbar{display:-webkit-box;display:-webkit-flex;display:flex;position:absolute;z-index:500;bottom:0;width:100%;background-color:#f7f7fa}.weui-tabbar:before{content:" ";position:absolute;left:0;top:0;right:0;height:1px;border-top:1px solid #c0bfc4;color:#c0bfc4;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.weui-tabbar__item{display:block;-webkit-box-flex:1;-webkit-flex:1;flex:1;padding:5px 0 0;font-size:0;color:#999;text-align:center;-webkit-tap-highlight-color:rgba(0,0,0,0)}.weui-tabbar__item.weui-bar__item_on .weui-tabbar__icon,.weui-tabbar__item.weui-bar__item_on .weui-tabbar__icon>i,.weui-tabbar__item.weui-bar__item_on .weui-tabbar__label{color:#09bb07}.weui-tabbar__icon{display:inline-block;width:27px;height:27px}.weui-tabbar__icon>i,i.weui-tabbar__icon{font-size:24px;color:#999}.weui-tabbar__icon img{width:100%;height:100%}.weui-tabbar__label{text-align:center;color:#999;font-size:10px;line-height:1.8}.weui-navbar{display:-webkit-box;display:-webkit-flex;display:flex;position:absolute;z-index:500;top:0;width:100%;background-color:#fafafa}.weui-navbar:after{content:" ";position:absolute;left:0;bottom:0;right:0;height:1px;border-bottom:1px solid #ccc;color:#ccc;-webkit-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.weui-navbar+.weui-tab__panel{padding-top:50px;padding-bottom:0}.weui-navbar__item{position:relative;display:block;-webkit-box-flex:1;-webkit-flex:1;flex:1;padding:13px 0;text-align:center;font-size:15px;-webkit-tap-highlight-color:rgba(0,0,0,0)}.weui-navbar__item:active{background-color:#ededed}.weui-navbar__item.weui-bar__item_on{background-color:#eaeaea}.weui-navbar__item:after{content:" ";position:absolute;right:0;top:0;width:1px;bottom:0;border-right:1px solid #ccc;color:#ccc;-webkit-transform-origin:100% 0;transform-origin:100% 0;-webkit-transform:scaleX(.5);transform:scaleX(.5)}.weui-navbar__item:last-child:after{display:none}.weui-tab{position:relative;height:100%}.weui-tab__panel{box-sizing:border-box;height:100%;padding-bottom:50px;overflow:auto;-webkit-overflow-scrolling:touch}.weui-tab__content{display:none}.weui-progress{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.weui-progress__bar{background-color:#ebebeb;height:3px;-webkit-box-flex:1;-webkit-flex:1;flex:1}.weui-progress__inner-bar{width:0;height:100%;background-color:#09bb07}.weui-progress__opr{display:block;margin-left:15px;font-size:0}.weui-panel{background-color:#fff;margin-top:10px;position:relative;overflow:hidden}.weui-panel:first-child{margin-top:0}.weui-panel:before{top:0;border-top:1px solid #e5e5e5;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.weui-panel:after,.weui-panel:before{content:" ";position:absolute;left:0;right:0;height:1px;color:#e5e5e5}.weui-panel:after{bottom:0;border-bottom:1px solid #e5e5e5;-webkit-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.weui-panel__hd{padding:14px 15px 10px;color:#999;font-size:13px;position:relative}.weui-panel__hd:after{content:" ";position:absolute;left:0;bottom:0;right:0;height:1px;border-bottom:1px solid #e5e5e5;color:#e5e5e5;-webkit-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:scaleY(.5);transform:scaleY(.5);left:15px}.weui-media-box{padding:15px;position:relative}.weui-media-box:before{content:" ";position:absolute;left:0;top:0;right:0;height:1px;border-top:1px solid #e5e5e5;color:#e5e5e5;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(.5);transform:scaleY(.5);left:15px}.weui-media-box:first-child:before{display:none}a.weui-media-box{color:#000;-webkit-tap-highlight-color:rgba(0,0,0,0)}a.weui-media-box:active{background-color:#ececec}.weui-media-box__title{font-weight:400;font-size:17px;width:auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-wrap:normal;word-wrap:break-word;word-break:break-all}.weui-media-box__desc{color:#999;font-size:13px;line-height:1.2;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.weui-media-box__info{margin-top:15px;padding-bottom:5px;font-size:13px;color:#cecece;line-height:1em;list-style:none;overflow:hidden}.weui-media-box__info__meta{float:left;padding-right:1em}.weui-media-box__info__meta_extra{padding-left:1em;border-left:1px solid #cecece}.weui-media-box_text .weui-media-box__title{margin-bottom:8px}.weui-media-box_appmsg{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.weui-media-box_appmsg .weui-media-box__hd{margin-right:.8em;width:60px;height:60px;line-height:60px;text-align:center}.weui-media-box_appmsg .weui-media-box__thumb{width:100%;max-height:100%;vertical-align:top}.weui-media-box_appmsg .weui-media-box__bd{-webkit-box-flex:1;-webkit-flex:1;flex:1;min-width:0}.weui-media-box_small-appmsg{padding:0}.weui-media-box_small-appmsg .weui-cells{margin-top:0}.weui-media-box_small-appmsg .weui-cells:before{display:none}.weui-grids{position:relative;overflow:hidden}.weui-grids:before{right:0;height:1px;border-top:1px solid #d9d9d9;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.weui-grids:after,.weui-grids:before{content:" ";position:absolute;left:0;top:0;color:#d9d9d9}.weui-grids:after{width:1px;bottom:0;border-left:1px solid #d9d9d9;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleX(.5);transform:scaleX(.5)}.weui-grid{position:relative;float:left;padding:20px 10px;width:33.33333333%;box-sizing:border-box}.weui-grid:before{top:0;width:1px;border-right:1px solid #d9d9d9;-webkit-transform-origin:100% 0;transform-origin:100% 0;-webkit-transform:scaleX(.5);transform:scaleX(.5)}.weui-grid:after,.weui-grid:before{content:" ";position:absolute;right:0;bottom:0;color:#d9d9d9}.weui-grid:after{left:0;height:1px;border-bottom:1px solid #d9d9d9;-webkit-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.weui-grid:active{background-color:#ececec}.weui-grid__icon{width:28px;height:28px;margin:0 auto}.weui-grid__icon img{display:block;width:100%;height:100%}.weui-grid__icon+.weui-grid__label{margin-top:5px}.weui-grid__label{display:block;color:#000;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.weui-footer,.weui-grid__label{text-align:center;font-size:14px}.weui-footer{color:#999}.weui-footer a{color:#586c94}.weui-footer_fixed-bottom{position:fixed;bottom:.52em;left:0;right:0}.weui-footer__links{font-size:0}.weui-footer__link{display:inline-block;vertical-align:top;margin:0 .62em;position:relative;font-size:14px}.weui-footer__link:before{content:" ";position:absolute;left:0;top:0;width:1px;bottom:0;border-left:1px solid #c7c7c7;color:#c7c7c7;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleX(.5);transform:scaleX(.5);left:-.65em;top:.36em;bottom:.36em}.weui-footer__link:first-child:before{display:none}.weui-footer__text{padding:0 .34em;font-size:12px}.weui-flex{display:-webkit-box;display:-webkit-flex;display:flex}.weui-flex__item{-webkit-box-flex:1;-webkit-flex:1;flex:1}.weui-dialog{position:fixed;z-index:5000;width:80%;max-width:300px;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);background-color:#fff;text-align:center;border-radius:3px;overflow:hidden}.weui-dialog__hd{padding:1.3em 1.6em .5em}.weui-dialog__title{font-weight:400;font-size:18px}.weui-dialog__bd{padding:0 1.6em .8em;min-height:40px;font-size:15px;line-height:1.3;word-wrap:break-word;word-break:break-all;color:#999}.weui-dialog__bd:first-child{padding:2.7em 20px 1.7em;color:#353535}.weui-dialog__ft{position:relative;line-height:48px;font-size:18px;display:-webkit-box;display:-webkit-flex;display:flex}.weui-dialog__ft:after{content:" ";position:absolute;left:0;top:0;right:0;height:1px;border-top:1px solid #d5d5d6;color:#d5d5d6;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.weui-dialog__btn{display:block;-webkit-box-flex:1;-webkit-flex:1;flex:1;color:#3cc51f;text-decoration:none;-webkit-tap-highlight-color:rgba(0,0,0,0);position:relative}.weui-dialog__btn:active{background-color:#eee}.weui-dialog__btn:after{content:" ";position:absolute;left:0;top:0;width:1px;bottom:0;border-left:1px solid #d5d5d6;color:#d5d5d6;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleX(.5);transform:scaleX(.5)}.weui-dialog__btn:first-child:after{display:none}.weui-dialog__btn_default{color:#353535}.weui-dialog__btn_primary{color:#0bb20c}.weui-skin_android .weui-dialog{text-align:left;box-shadow:0 6px 30px 0 rgba(0,0,0,.1)}.weui-skin_android .weui-dialog__title{font-size:21px}.weui-skin_android .weui-dialog__hd{text-align:left}.weui-skin_android .weui-dialog__bd{color:#999;padding:.25em 1.6em 2em;font-size:17px;text-align:left}.weui-skin_android .weui-dialog__bd:first-child{padding:1.6em 1.6em 2em;color:#353535}.weui-skin_android .weui-dialog__ft{display:block;text-align:right;line-height:42px;font-size:16px;padding:0 1.6em .7em}.weui-skin_android .weui-dialog__ft:after{display:none}.weui-skin_android .weui-dialog__btn{display:inline-block;vertical-align:top;padding:0 .8em}.weui-skin_android .weui-dialog__btn:after{display:none}.weui-skin_android .weui-dialog__btn:active,.weui-skin_android .weui-dialog__btn:visited{background-color:rgba(0,0,0,.06)}.weui-skin_android .weui-dialog__btn:last-child{margin-right:-.8em}.weui-skin_android .weui-dialog__btn_default{color:gray}@media screen and (min-width:1024px){.weui-dialog{width:35%}}.weui-toast{position:fixed;z-index:5000;width:7.6em;min-height:7.6em;top:180px;left:50%;margin-left:-3.8em;background:hsla(0,0%,7%,.7);text-align:center;border-radius:5px;color:#fff}.weui-icon_toast{margin:22px 0 0;display:block}.weui-icon_toast.weui-icon-success-no-circle:before{color:#fff;font-size:55px}.weui-icon_toast.weui-loading{margin:30px 0 0;width:38px;height:38px;vertical-align:baseline}.weui-toast__content{margin:0 0 15px}.weui-mask{background:rgba(0,0,0,.6)}.weui-mask,.weui-mask_transparent{position:fixed;z-index:1000;top:0;right:0;left:0;bottom:0}.weui-actionsheet{position:fixed;left:0;bottom:0;-webkit-transform:translateY(100%);transform:translateY(100%);-webkit-backface-visibility:hidden;backface-visibility:hidden;z-index:5000;width:100%;background-color:#efeff4;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s}.weui-actionsheet__title{position:relative;height:65px;padding:0 20px;line-height:1.4;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;flex-direction:column;text-align:center;font-size:14px;color:#888;background:#fcfcfd}.weui-actionsheet__title:before{content:" ";position:absolute;left:0;bottom:0;right:0;height:1px;border-bottom:1px solid #e5e5e5;color:#e5e5e5;-webkit-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.weui-actionsheet__title .weui-actionsheet__title-text{overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.weui-actionsheet__menu{background-color:#fcfcfd}.weui-actionsheet__action{margin-top:6px;background-color:#fcfcfd}.weui-actionsheet__cell{position:relative;padding:10px 0;text-align:center;font-size:18px}.weui-actionsheet__cell:before{content:" ";position:absolute;left:0;top:0;right:0;height:1px;border-top:1px solid #e5e5e5;color:#e5e5e5;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.weui-actionsheet__cell:active{background-color:#ececec}.weui-actionsheet__cell:first-child:before{display:none}.weui-skin_android .weui-actionsheet{position:fixed;left:50%;top:50%;bottom:auto;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);width:274px;box-sizing:border-box;-webkit-backface-visibility:hidden;backface-visibility:hidden;background:transparent;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s}.weui-skin_android .weui-actionsheet__action{display:none}.weui-skin_android .weui-actionsheet__menu{border-radius:2px;box-shadow:0 6px 30px 0 rgba(0,0,0,.1)}.weui-skin_android .weui-actionsheet__cell{padding:13px 24px;font-size:16px;line-height:1.4;text-align:left}.weui-skin_android .weui-actionsheet__cell:first-child{border-top-left-radius:2px;border-top-right-radius:2px}.weui-skin_android .weui-actionsheet__cell:last-child{border-bottom-left-radius:2px;border-bottom-right-radius:2px}.weui-actionsheet_toggle{-webkit-transform:translate(0);transform:translate(0)}.weui-loadmore{width:65%;margin:1.5em auto;line-height:1.6em;font-size:14px;text-align:center}.weui-loadmore__tips{display:inline-block;vertical-align:middle}.weui-loadmore_line{border-top:1px solid #e5e5e5;margin-top:2.4em}.weui-loadmore_line .weui-loadmore__tips{position:relative;top:-.9em;padding:0 .55em;background-color:#fff;color:#999}.weui-loadmore_dot .weui-loadmore__tips{padding:0 .16em}.weui-loadmore_dot .weui-loadmore__tips:before{content:" ";width:4px;height:4px;border-radius:50%;background-color:#e5e5e5;display:inline-block;position:relative;vertical-align:0;top:-.16em}.weui-badge{display:inline-block;padding:.15em .4em;min-width:8px;border-radius:18px;background-color:#f43530;color:#fff;line-height:1.2;text-align:center;font-size:12px;vertical-align:middle}.weui-badge_dot{padding:.4em;min-width:0}.weui-search-bar{position:relative;padding:8px 10px;display:-webkit-box;display:-webkit-flex;display:flex;box-sizing:border-box;background-color:#efeff4}.weui-search-bar:before{top:0;border-top:1px solid #d7d6dc;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.weui-search-bar:after,.weui-search-bar:before{content:" ";position:absolute;left:0;right:0;height:1px;color:#d7d6dc}.weui-search-bar:after{bottom:0;border-bottom:1px solid #d7d6dc;-webkit-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.weui-search-bar.weui-search-bar_focusing .weui-search-bar__cancel-btn{display:block}.weui-search-bar.weui-search-bar_focusing .weui-search-bar__label{display:none}.weui-search-bar__form{position:relative;-webkit-box-flex:1;-webkit-flex:auto;flex:auto;background-color:#efeff4}.weui-search-bar__form:after{content:'';position:absolute;left:0;top:0;width:200%;height:200%;-webkit-transform:scale(.5);transform:scale(.5);-webkit-transform-origin:0 0;transform-origin:0 0;border-radius:10px;border:1px solid #e6e6ea;box-sizing:border-box;background:#fff}.weui-search-bar__box{position:relative;padding-left:30px;padding-right:30px;height:100%;width:100%;box-sizing:border-box;z-index:1}.weui-search-bar__box .weui-search-bar__input{padding:4px 0;width:100%;height:1.42857143em;border:0;font-size:14px;line-height:1.42857143em;box-sizing:content-box;background:transparent}.weui-search-bar__box .weui-search-bar__input:focus{outline:none}.weui-search-bar__box .weui-icon-search{position:absolute;left:10px;top:0;line-height:28px}.weui-search-bar__box .weui-icon-clear{position:absolute;top:0;right:0;padding:0 10px;line-height:28px}.weui-search-bar__label{position:absolute;top:1px;right:1px;bottom:1px;left:1px;z-index:2;border-radius:3px;text-align:center;color:#9b9b9b;background:#fff}.weui-search-bar__label span{display:inline-block;font-size:14px;vertical-align:middle}.weui-search-bar__label .weui-icon-search{margin-right:5px}.weui-search-bar__cancel-btn{display:none;margin-left:10px;line-height:28px;color:#09bb07;white-space:nowrap}.weui-search-bar__input:not(:valid)~.weui-icon-clear{display:none}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration,input[type=search]::-webkit-search-results-button,input[type=search]::-webkit-search-results-decoration{display:none}.weui-picker{position:fixed;width:100%;left:0;bottom:0;z-index:5000;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform:translateY(100%);transform:translateY(100%);-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s}.weui-picker__hd{display:-webkit-box;display:-webkit-flex;display:flex;padding:9px 15px;background-color:#fff;position:relative;text-align:center;font-size:17px}.weui-picker__hd:after{content:" ";position:absolute;left:0;bottom:0;right:0;height:1px;border-bottom:1px solid #e5e5e5;color:#e5e5e5;-webkit-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.weui-picker__action{display:block;-webkit-box-flex:1;-webkit-flex:1;flex:1;color:#1aad19}.weui-picker__action:first-child{text-align:left;color:#888}.weui-picker__action:last-child{text-align:right}.weui-picker__bd{display:-webkit-box;display:-webkit-flex;display:flex;position:relative;background-color:#fff;height:238px;overflow:hidden}.weui-picker__group{-webkit-box-flex:1;-webkit-flex:1;flex:1;position:relative;height:100%}.weui-picker__mask{top:0;height:100%;margin:0 auto;background:-webkit-linear-gradient(top,hsla(0,0%,100%,.95),hsla(0,0%,100%,.6)),-webkit-linear-gradient(bottom,hsla(0,0%,100%,.95),hsla(0,0%,100%,.6));background:linear-gradient(180deg,hsla(0,0%,100%,.95),hsla(0,0%,100%,.6)),linear-gradient(0deg,hsla(0,0%,100%,.95),hsla(0,0%,100%,.6));background-position:top,bottom;background-size:100% 102px;background-repeat:no-repeat;-webkit-transform:translateZ(0);transform:translateZ(0)}.weui-picker__indicator,.weui-picker__mask{position:absolute;left:0;width:100%;z-index:3}.weui-picker__indicator{height:34px;top:102px}.weui-picker__indicator:before{top:0;border-top:1px solid #e5e5e5;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.weui-picker__indicator:after,.weui-picker__indicator:before{content:" ";position:absolute;left:0;right:0;height:1px;color:#e5e5e5}.weui-picker__indicator:after{bottom:0;border-bottom:1px solid #e5e5e5;-webkit-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.weui-picker__content{position:absolute;top:0;left:0;width:100%}.weui-picker__item{padding:0;height:34px;line-height:34px;text-align:center;color:#000;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.weui-picker__item_disabled{color:#999}@-webkit-keyframes a{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes a{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.weui-animate-slide-up{-webkit-animation:a ease .3s forwards;animation:a ease .3s forwards}@-webkit-keyframes b{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes b{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.weui-animate-slide-down{-webkit-animation:b ease .3s forwards;animation:b ease .3s forwards}@-webkit-keyframes c{0%{opacity:0}to{opacity:1}}@keyframes c{0%{opacity:0}to{opacity:1}}.weui-animate-fade-in{-webkit-animation:c ease .3s forwards;animation:c ease .3s forwards}@-webkit-keyframes d{0%{opacity:1}to{opacity:0}}@keyframes d{0%{opacity:1}to{opacity:0}}.weui-animate-fade-out{-webkit-animation:d ease .3s forwards;animation:d ease .3s forwards}.weui-agree{display:block;padding:.5em 15px;font-size:13px}.weui-agree a{color:#586c94}.weui-agree__text{color:#999}.weui-agree__checkbox{-webkit-appearance:none;appearance:none;outline:0;font-size:0;border:1px solid #d1d1d1;background-color:#fff;border-radius:3px;width:13px;height:13px;position:relative;vertical-align:0;top:2px}.weui-agree__checkbox:checked:before{font-family:weui;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;text-align:center;speak:none;display:inline-block;vertical-align:middle;text-decoration:inherit;content:"\EA08";color:#09bb07;font-size:13px;position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-48%) scale(.73);transform:translate(-50%,-48%) scale(.73)}.weui-agree__checkbox:disabled{background-color:#e1e1e1}.weui-agree__checkbox:disabled:before{color:#adadad}.weui-loading{width:20px;height:20px;display:inline-block;vertical-align:middle;-webkit-animation:e 1s steps(12) infinite;animation:e 1s steps(12) infinite;background:transparent url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAiIGhlaWdodD0iMTIwIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgxMDB2MTAwSDB6Ii8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTlFOUU5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTMwKSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iIzk4OTY5NyIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgzMCAxMDUuOTggNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjOUI5OTlBIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDYwIDc1Ljk4IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0EzQTFBMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSg5MCA2NSA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNBQkE5QUEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoMTIwIDU4LjY2IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0IyQjJCMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgxNTAgNTQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjQkFCOEI5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDE4MCA1MCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDMkMwQzEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTE1MCA0NS45OCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDQkNCQ0IiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTEyMCA0MS4zNCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNEMkQyRDIiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTkwIDM1IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0RBREFEQSIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgtNjAgMjQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTJFMkUyIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKC0zMCAtNS45OCA2NSkiLz48L3N2Zz4=) no-repeat;background-size:100%}.weui-btn_loading.weui-btn_primary .weui-loading,.weui-btn_loading.weui-btn_warn .weui-loading,.weui-loading.weui-loading_transparent{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 100 100'%3E%3Cpath fill='none' d='M0 0h100v100H0z'/%3E%3Crect xmlns='http://www.w3.org/2000/svg' width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.56)' rx='5' ry='5' transform='translate(0 -30)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.5)' rx='5' ry='5' transform='rotate(30 105.98 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.43)' rx='5' ry='5' transform='rotate(60 75.98 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.38)' rx='5' ry='5' transform='rotate(90 65 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.32)' rx='5' ry='5' transform='rotate(120 58.66 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.28)' rx='5' ry='5' transform='rotate(150 54.02 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.25)' rx='5' ry='5' transform='rotate(180 50 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.2)' rx='5' ry='5' transform='rotate(-150 45.98 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.17)' rx='5' ry='5' transform='rotate(-120 41.34 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.14)' rx='5' ry='5' transform='rotate(-90 35 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.1)' rx='5' ry='5' transform='rotate(-60 24.02 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.03)' rx='5' ry='5' transform='rotate(-30 -5.98 65)'/%3E%3C/svg%3E")}@-webkit-keyframes e{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes e{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.weui-slider{padding:15px 18px;-webkit-user-select:none;user-select:none}.weui-slider__inner{position:relative;height:2px;background-color:#e9e9e9}.weui-slider__track{height:2px;background-color:#1aad19;width:0}.weui-slider__handler{position:absolute;left:0;top:50%;width:28px;height:28px;margin-left:-14px;margin-top:-14px;border-radius:50%;background-color:#fff;box-shadow:0 0 4px rgba(0,0,0,.2)}.weui-slider-box{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.weui-slider-box .weui-slider{-webkit-box-flex:1;-webkit-flex:1;flex:1}.weui-slider-box__value{margin-left:.5em;min-width:24px;color:#888;text-align:center;font-size:14px} -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | SmartConfig 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.3 21 | CFBundleVersion 22 | 8 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | Main 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UIRequiresFullScreen 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/SmartConfig-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | // 桥接ESPtouch 6 | #import "ESPTouchTask.h" 7 | #import "ESPTouchResult.h" 8 | #import "ESPTouchDelegate.h" 9 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/SmartConfig.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.network.client 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/View/CustomTextField.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CustomTextField.swift 3 | // SmartConfig 4 | // 5 | // Created by 翟怀楼 on 2017/6/19. 6 | // Copyright © 2017年 翟怀楼. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @IBDesignable 12 | class CustomTextField: UITextField { 13 | 14 | // 设置左边距 15 | @IBInspectable var leftTextPedding: Int = 0 { 16 | didSet { 17 | self.setNeedsDisplay() 18 | } 19 | } 20 | 21 | @IBInspectable var lineColor: UIColor = UIColor.black { 22 | didSet { 23 | self.setNeedsDisplay() 24 | } 25 | } 26 | 27 | override func textRect(forBounds bounds: CGRect) -> CGRect { 28 | return self.newBounds(bounds) 29 | } 30 | 31 | override func editingRect(forBounds bounds: CGRect) -> CGRect { 32 | return self.newBounds(bounds) 33 | } 34 | 35 | fileprivate func newBounds(_ bounds: CGRect) -> CGRect { 36 | 37 | var newBounds = bounds 38 | newBounds.origin.x += CGFloat(leftTextPedding) 39 | return newBounds 40 | } 41 | 42 | override func draw(_ rect: CGRect) { 43 | let height = self.bounds.height 44 | 45 | // get the current drawing context 46 | let context = UIGraphicsGetCurrentContext() 47 | 48 | context?.setStrokeColor(lineColor.cgColor) 49 | context?.setLineWidth(2.5) 50 | 51 | // start a new Path 52 | context?.beginPath() 53 | 54 | context!.move(to: CGPoint(x: self.bounds.origin.x, y: height - 0.5)) 55 | context!.addLine(to: CGPoint(x: self.bounds.size.width, y: height - 0.5)) 56 | // close and stroke (draw) it 57 | context?.closePath() 58 | context?.strokePath() 59 | } 60 | 61 | 62 | 63 | 64 | } 65 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/View/SystemButton.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SystemButton.swift 3 | // demo2 4 | // 5 | // Created by 翟怀楼 on 2017/6/16. 6 | // Copyright © 2017年 翟怀楼. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @IBDesignable 12 | class SystemButton: UIButton { 13 | 14 | /* 当 storyboards 对象创建时回调 */ 15 | required init?(coder aDecoder: NSCoder) { 16 | super.init(coder: aDecoder) 17 | setupViews() 18 | } 19 | 20 | /* 当程序初始化的时候回调 */ 21 | override init(frame: CGRect) { 22 | super.init(frame: frame) 23 | setupViews() 24 | } 25 | 26 | /* 调整视图的 frame */ 27 | override func layoutSubviews() { 28 | super.layoutSubviews() 29 | setupViews() 30 | } 31 | 32 | // 当 @IBDesignable 请求做出改变/* */ 33 | override func prepareForInterfaceBuilder() { 34 | super.prepareForInterfaceBuilder() 35 | setupViews() 36 | } 37 | 38 | /* 自己的设置 */ 39 | func setupViews() { 40 | layer.cornerRadius = 8 41 | tintColor = UIColor.white 42 | // backgroundColor = #colorLiteral(red: 0, green: 0.6274509804, blue: 0.9137254902, alpha: 1) 43 | bounds.size = CGSize(width: 290, height: 50) 44 | } 45 | 46 | } 47 | 48 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | SmartConfig 4 | 5 | Created by 翟怀楼 on 2017/6/20. 6 | Copyright © 2017年 翟怀楼. All rights reserved. 7 | */ 8 | CONFIG_BUTTON_CONFIRM = "Confirm"; 9 | CONFIG_BUTTON_CANCEL = "Cancel"; 10 | 11 | WIFI_CONNECTED = "Connected to WiFi for "; 12 | WIFI_DISCONNECTED = "Not connect to WiFi"; 13 | WIFI_INPUT_PASSWORD = "Please enter Wi-Fi Password"; 14 | 15 | WIFI_CONNECTION = " has WiFi connection"; 16 | 17 | CONFIRM = "OK"; 18 | CANCEL = "Cancel"; 19 | 20 | RESULT_TITLE = "Config Rsult"; 21 | 22 | MINIMAL_SYSTEMS = "Minimal Systems"; 23 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/en.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UITabBarItem"; title = "Other"; ObjectID = "9vy-lu-Vlo"; */ 3 | "9vy-lu-Vlo.title" = "More"; 4 | 5 | /* Class = "UIButton"; normalTitle = "Config"; ObjectID = "Iw2-Ch-Lsx"; */ 6 | "Iw2-Ch-Lsx.normalTitle" = "Config"; 7 | 8 | /* Class = "UINavigationItem"; title = "Pin"; ObjectID = "SDn-vV-goj"; */ 9 | "SDn-vV-goj.title" = "Pin"; 10 | 11 | /* Class = "UIBarButtonItem"; title = "返回"; ObjectID = "T9e-F8-BIA"; */ 12 | "T9e-F8-BIA.title" = "Cancel"; 13 | 14 | /* Class = "UITabBarItem"; title = "Pin"; ObjectID = "TiA-af-1fi"; */ 15 | "TiA-af-1fi.title" = "Pin"; 16 | 17 | /* Class = "UITextField"; placeholder = "请输入 Wi-Fi 密码"; ObjectID = "aNe-Rw-SLf"; */ 18 | "aNe-Rw-SLf.placeholder" = "Please enter Wi-Fi Password"; 19 | 20 | /* Class = "UITabBarItem"; title = "Config"; ObjectID = "awG-vp-lZT"; */ 21 | "awG-vp-lZT.title" = "Config"; 22 | 23 | /* Class = "UINavigationItem"; title = "配置入网"; ObjectID = "bCh-ZE-zOH"; */ 24 | "bCh-ZE-zOH.title" = "Config"; 25 | 26 | /* Class = "UINavigationItem"; title = "Other"; ObjectID = "e9T-jE-NP3"; */ 27 | "e9T-jE-NP3.title" = "More"; 28 | 29 | /* Class = "UILabel"; text = "Open Source License"; ObjectID = "gaD-dp-ehl"; */ 30 | "gaD-dp-ehl.text" = "Open Source License"; 31 | 32 | /* Class = "UILabel"; text = "ESP8266"; ObjectID = "h3j-fQ-t4S"; */ 33 | "h3j-fQ-t4S.text" = "ESP8266"; 34 | 35 | /* Class = "UILabel"; text = "Version"; ObjectID = "iV5-6b-oVK"; */ 36 | "iV5-6b-oVK.text" = "Version"; 37 | 38 | /* Class = "UIBarButtonItem"; title = "取消"; ObjectID = "xT9-mT-4hq"; */ 39 | "xT9-mT-4hq.title" = "Cancel"; 40 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/zh-Hans.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | SmartConfig 4 | 5 | Created by 翟怀楼 on 2017/6/20. 6 | Copyright © 2017年 翟怀楼. All rights reserved. 7 | */ 8 | CONFIG_BUTTON_CONFIRM = "确定"; 9 | CONFIG_BUTTON_CANCEL = "取消"; 10 | 11 | WIFI_CONNECTED = "已连接 Wi-Fi "; 12 | WIFI_DISCONNECTED = "没有连接 Wi-Fi"; 13 | WIFI_INPUT_PASSWORD = "请输入 Wi-Fi 密码"; 14 | 15 | WIFI_CONNECTION = " 已连接 Wi-Fi"; 16 | 17 | CONFIRM = "确定"; 18 | CANCEL = "取消"; 19 | 20 | RESULT_TITLE = "配置结果"; 21 | 22 | MINIMAL_SYSTEMS = "最小系统"; 23 | -------------------------------------------------------------------------------- /SmartConfig/SmartConfig/zh-Hans.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UITabBarItem"; title = "Other"; ObjectID = "9vy-lu-Vlo"; */ 3 | "9vy-lu-Vlo.title" = "更多"; 4 | 5 | /* Class = "UIButton"; normalTitle = "Config"; ObjectID = "Iw2-Ch-Lsx"; */ 6 | "Iw2-Ch-Lsx.normalTitle" = "配置"; 7 | 8 | /* Class = "UINavigationItem"; title = "Pin"; ObjectID = "SDn-vV-goj"; */ 9 | "SDn-vV-goj.title" = "引脚"; 10 | 11 | /* Class = "UIBarButtonItem"; title = "返回"; ObjectID = "T9e-F8-BIA"; */ 12 | "T9e-F8-BIA.title" = "返回"; 13 | 14 | /* Class = "UITabBarItem"; title = "Pin"; ObjectID = "TiA-af-1fi"; */ 15 | "TiA-af-1fi.title" = "引脚"; 16 | 17 | /* Class = "UITextField"; placeholder = "请输入 Wi-Fi 密码"; ObjectID = "aNe-Rw-SLf"; */ 18 | "aNe-Rw-SLf.placeholder" = "请输入 Wi-Fi 密码"; 19 | 20 | /* Class = "UITabBarItem"; title = "Config"; ObjectID = "awG-vp-lZT"; */ 21 | "awG-vp-lZT.title" = "配置"; 22 | 23 | /* Class = "UINavigationItem"; title = "配置入网"; ObjectID = "bCh-ZE-zOH"; */ 24 | "bCh-ZE-zOH.title" = "配置入网"; 25 | 26 | /* Class = "UINavigationItem"; title = "Other"; ObjectID = "e9T-jE-NP3"; */ 27 | "e9T-jE-NP3.title" = "更多"; 28 | 29 | /* Class = "UILabel"; text = "Open Source License"; ObjectID = "gaD-dp-ehl"; */ 30 | "gaD-dp-ehl.text" = "开源组件许可"; 31 | 32 | /* Class = "UILabel"; text = "ESP8266"; ObjectID = "h3j-fQ-t4S"; */ 33 | "h3j-fQ-t4S.text" = "ESP8266"; 34 | 35 | /* Class = "UILabel"; text = "Version"; ObjectID = "iV5-6b-oVK"; */ 36 | "iV5-6b-oVK.text" = "版本"; 37 | 38 | /* Class = "UIBarButtonItem"; title = "取消"; ObjectID = "xT9-mT-4hq"; */ 39 | "xT9-mT-4hq.title" = "取消"; 40 | -------------------------------------------------------------------------------- /images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/images/1.png -------------------------------------------------------------------------------- /images/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/images/2.png -------------------------------------------------------------------------------- /images/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lou-lan/SmartConfig/26ee82131ea4605ac54b3f7452d1ce25d30c21b0/images/3.png --------------------------------------------------------------------------------