├── .gitignore ├── LICENSE ├── PNG ├── 0.png ├── 1.png └── 2.png ├── README.md ├── SimulateLocation.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── rockerhx.xcuserdatad │ └── xcschemes │ ├── SimulateLocation.xcscheme │ └── xcschememanagement.plist ├── SimulateLocation ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── first.imageset │ │ ├── Contents.json │ │ └── first.pdf │ └── second.imageset │ │ ├── Contents.json │ │ └── second.pdf ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── FirstViewController.swift ├── Info.plist ├── LocationTransform.swift ├── SecondViewController.swift ├── Transform │ ├── transform.html │ └── transform.js ├── WenHuaChanYe.gpx └── ZhongHang.gpx ├── SimulateLocationTests ├── Info.plist └── SimulateLocationTests.swift └── SimulateLocationUITests ├── Info.plist └── SimulateLocationUITests.swift /.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 | # CocoaPods 31 | # 32 | # We recommend against adding the Pods directory to your .gitignore. However 33 | # you should judge for yourself, the pros and cons are mentioned at: 34 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 35 | # 36 | # Pods/ 37 | 38 | # Carthage 39 | # 40 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 41 | # Carthage/Checkouts 42 | 43 | Carthage/Build 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 51 | 52 | fastlane/report.xml 53 | fastlane/screenshots 54 | 55 | #Code Injection 56 | # 57 | # After new code Injection tools there's a generated folder /iOSInjectionProject 58 | # https://github.com/johnno1962/injectionforxcode 59 | 60 | iOSInjectionProject/ 61 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 RockerHX 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 | -------------------------------------------------------------------------------- /PNG/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongdong/SimulateLocation/e0257242d56af31ae61d3c2ccb7d480be2e11eff/PNG/0.png -------------------------------------------------------------------------------- /PNG/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongdong/SimulateLocation/e0257242d56af31ae61d3c2ccb7d480be2e11eff/PNG/1.png -------------------------------------------------------------------------------- /PNG/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongdong/SimulateLocation/e0257242d56af31ae61d3c2ccb7d480be2e11eff/PNG/2.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > 本文只使用有Mac电脑,用iPhone的骚年们。 2 | > **本章是水文,利用Xcode模拟定位打卡很早就有教程了,这里干货只有一行,离开Xcode任然保证模拟定位不变。** 3 | 4 | ### 对象:钉钉等LBS应用 5 | 6 | 近两年很多企业和中小型公司都开始使用钉钉打卡签到。很多苦逼党因为坐公交晚了几分钟,被扣钱,晚了几分钟,全勤没了,所以这里我们可以缓解下代码狗的痛苦 —— 模拟定位(先打卡,再到公司)。已经会连Xcode模拟定位的可以忽略前面的部分内容,直接跳到最后。 7 | 8 | 公司设定打卡范围,100米,500米,1公里都可以,但是基于有模拟定位这个技术,钉钉在打卡选项里加了一项WiFi打卡,定位打卡和WiFi打开可以叠加存在以保证有人打卡作弊(后面讲解如何破解WiFi)。 9 | 10 | ### 开车 11 | 12 | * 一台Mac (安装了Xcode) 13 | * 一台iPhone(越狱不越狱无所谓) 14 | * 一根数据线。 15 | 16 | ### 坐标系统 17 | 18 | 这里普及一下坐标系统: 19 | 目前我们经常接触的无非就是**原始坐标**,**火星坐标**,**二次加密坐标**。 20 | * 原始坐标:手机上获取到的是原始的GPS坐标 —— **WGS-84**。 21 | * 火星坐标:我大天朝自己加了飘逸搞的一套加密坐标,中国国测局(和GFW一样的傻屌组织)—— **GCJ-02**:**谷歌**、**高德**。 22 | * 百度加密坐标:在火星坐标的基础上再次飘逸后的加密坐标 —— **BD-09**:**百度**。 23 | 24 | > 在遥远的东方,有一个天朝。 25 | 天朝有一个测绘局,发明了一种把美国卫星的GPS的地球坐标,进行偏移的算法,计算后,得出了一个火星坐标。 26 | 为了让火星坐标能正确的显示,又给每部导航软件加入了这个算法,可以在大家的地图上还原位置。并且给每部导航收费。美其名国家安全。而且这个算法看上去很牛B的样子,还不可逆。 27 | 所以,只有这个国家的人都在用错误的坐标。正宗的掩耳盗铃。 28 | 民用卫星精度都已经让你出身冷汗了,何况军用卫星。打仗估值也不会用中国的电子地图吧。 29 | 只可惜各种LBS应用,都是个麻烦事哦。 30 | 31 | 还好黄天不负有心人,终于经过大家的模拟,计算,基本还原了[飘逸算法](https://github.com/googollee/eviltransform.git)。 32 | 33 | ### 选技师 34 | 35 | 坐标获取入口: 36 | * [高德](http://lbs.amap.com/console/show/picker) 37 | * [百度](http://api.map.baidu.com/lbsapi/getpoint/index.html) 38 | 39 | 首先,根据各自的喜好,选好你想要模拟的位置,这里以高德地图为例: 40 | 41 | ![高德地图](/PNG/0.png) 42 | 43 | 可以看到右边有显示坐标 : 44 | ``` 45 | 104.06521,30.589833 46 | ``` 47 | 48 | ### 上钟 49 | 50 | iPhone所需要的坐标是**WGS-84**,我们获取的是**GCJ-02**,这里我们利用最新[飘逸还原算法](https://github.com/googollee/eviltransform.git)来转换出你所需要的真实坐标。 51 | 52 | 我所在的定位**四川省成都市ACC中航城市广场**原始坐标为: 53 | ``` 54 | 104.06263069384391,30.593234492328744 55 | ``` 56 | 57 | ### 服务 58 | 59 | 这里我们需要新建一个**gpx**文件,包含坐标用于模拟定位。 60 | ```xml 61 | 62 | 67 |     68 |     69 | 70 | ``` 71 | 根据不同位置不同把转换得到的原始坐标对应到**lat**和**lon**里面即可。 72 | 73 | > 记得先把手机定位打开。 74 | 75 | 真机运行一个新建的空的iOS项目,把上面我们新建的**gpx**文件拖到工程里,配置一下**Scheme**,然后真机运行即可。 76 | ![gpx](/PNG/1.png) 77 | ![Scheme](/PNG/2.png) 78 | 79 | 这个时候千万别点**Stop**,直接**Home**键后台,再打开带定位的应用看看你当前的位置,484超开心。 80 | 还原定位的方法,直接**Stop**即可。 81 | 82 | ### 下钟 83 | 84 | 大保健做完了,可能有的会所还会送你一点小礼品,你要逗得技师开心结束的时候还会送你点小惊喜。 85 | > 辣么,惊喜来了: 86 | > * **破解钉钉WiFi打卡:**把家里的WiFi名称改得和公司打卡的WiFi即可。据我测试,我们公司只配置校验了SSID,没有校验DHCP地址。 87 | > * **随时随地打卡:**按照上面的步骤模拟定位完成之后,不要Stop,直接拔掉数据线(猜测是Xcode开发者模式开了个进程来模拟定位,如果Xcode上没有Stop,那这个进程就不会Kill掉)。 88 | > * **WiFi破解弊端:**公司如果启动了DHCP校验,那就只能靠社工的方法搞到地址,也只能在家里打卡了。 89 | > * **随地打卡弊端:**恢复方法只能重启手机才能还原定位,经测试,微信里地图无法使用,一片空白,所以这里阔以用不用的旧的测试机来专注打卡,我就只能帮你到这里了。 90 | 91 | 中午测试了下摩拜的红包车,如果我的手机定位没有改变,无论骑行多远,骑行距离都是0米,红包也只有一块(一中午四辆红包车均是如此)。看到这里应该不用我告诉你怎么撸红包了吧,撸红包的成本还是相对较高,必须随时背着电脑,如果公司没有开启WiFi打开,你又恰巧背了电脑,那就真的能随时随地打卡了。 92 | -------------------------------------------------------------------------------- /SimulateLocation.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C61074651E82B3B5003EA65B /* WenHuaChanYe.gpx in Resources */ = {isa = PBXBuildFile; fileRef = C61074641E82B3B5003EA65B /* WenHuaChanYe.gpx */; }; 11 | C6412EFF1E76F03900F467FE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6412EFE1E76F03900F467FE /* AppDelegate.swift */; }; 12 | C6412F011E76F03900F467FE /* FirstViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6412F001E76F03900F467FE /* FirstViewController.swift */; }; 13 | C6412F031E76F03900F467FE /* SecondViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6412F021E76F03900F467FE /* SecondViewController.swift */; }; 14 | C6412F061E76F03900F467FE /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C6412F041E76F03900F467FE /* Main.storyboard */; }; 15 | C6412F081E76F03900F467FE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C6412F071E76F03900F467FE /* Assets.xcassets */; }; 16 | C6412F0B1E76F03900F467FE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C6412F091E76F03900F467FE /* LaunchScreen.storyboard */; }; 17 | C6412F161E76F03900F467FE /* SimulateLocationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6412F151E76F03900F467FE /* SimulateLocationTests.swift */; }; 18 | C6412F211E76F03900F467FE /* SimulateLocationUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6412F201E76F03900F467FE /* SimulateLocationUITests.swift */; }; 19 | C6412F2F1E76F05F00F467FE /* ZhongHang.gpx in Resources */ = {isa = PBXBuildFile; fileRef = C6412F2E1E76F05F00F467FE /* ZhongHang.gpx */; }; 20 | C6412F321E7705AD00F467FE /* LocationTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6412F311E7705AD00F467FE /* LocationTransform.swift */; }; 21 | C6904EB61EAE3DD800F4EF40 /* transform.html in Resources */ = {isa = PBXBuildFile; fileRef = C6904EB41EAE3DD800F4EF40 /* transform.html */; }; 22 | C6904EB71EAE3DD800F4EF40 /* transform.js in Resources */ = {isa = PBXBuildFile; fileRef = C6904EB51EAE3DD800F4EF40 /* transform.js */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXContainerItemProxy section */ 26 | C6412F121E76F03900F467FE /* PBXContainerItemProxy */ = { 27 | isa = PBXContainerItemProxy; 28 | containerPortal = C6412EF31E76F03900F467FE /* Project object */; 29 | proxyType = 1; 30 | remoteGlobalIDString = C6412EFA1E76F03900F467FE; 31 | remoteInfo = SimulateLocation; 32 | }; 33 | C6412F1D1E76F03900F467FE /* PBXContainerItemProxy */ = { 34 | isa = PBXContainerItemProxy; 35 | containerPortal = C6412EF31E76F03900F467FE /* Project object */; 36 | proxyType = 1; 37 | remoteGlobalIDString = C6412EFA1E76F03900F467FE; 38 | remoteInfo = SimulateLocation; 39 | }; 40 | /* End PBXContainerItemProxy section */ 41 | 42 | /* Begin PBXFileReference section */ 43 | C61074641E82B3B5003EA65B /* WenHuaChanYe.gpx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = WenHuaChanYe.gpx; sourceTree = ""; }; 44 | C6412EFB1E76F03900F467FE /* SimulateLocation.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SimulateLocation.app; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | C6412EFE1E76F03900F467FE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 46 | C6412F001E76F03900F467FE /* FirstViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstViewController.swift; sourceTree = ""; }; 47 | C6412F021E76F03900F467FE /* SecondViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecondViewController.swift; sourceTree = ""; }; 48 | C6412F051E76F03900F467FE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 49 | C6412F071E76F03900F467FE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 50 | C6412F0A1E76F03900F467FE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 51 | C6412F0C1E76F03900F467FE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 52 | C6412F111E76F03900F467FE /* SimulateLocationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SimulateLocationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | C6412F151E76F03900F467FE /* SimulateLocationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimulateLocationTests.swift; sourceTree = ""; }; 54 | C6412F171E76F03900F467FE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 55 | C6412F1C1E76F03900F467FE /* SimulateLocationUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SimulateLocationUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | C6412F201E76F03900F467FE /* SimulateLocationUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimulateLocationUITests.swift; sourceTree = ""; }; 57 | C6412F221E76F03900F467FE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 58 | C6412F2E1E76F05F00F467FE /* ZhongHang.gpx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = ZhongHang.gpx; sourceTree = ""; }; 59 | C6412F311E7705AD00F467FE /* LocationTransform.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationTransform.swift; sourceTree = ""; }; 60 | C6904EB41EAE3DD800F4EF40 /* transform.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = transform.html; sourceTree = ""; }; 61 | C6904EB51EAE3DD800F4EF40 /* transform.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = transform.js; sourceTree = ""; }; 62 | /* End PBXFileReference section */ 63 | 64 | /* Begin PBXFrameworksBuildPhase section */ 65 | C6412EF81E76F03900F467FE /* Frameworks */ = { 66 | isa = PBXFrameworksBuildPhase; 67 | buildActionMask = 2147483647; 68 | files = ( 69 | ); 70 | runOnlyForDeploymentPostprocessing = 0; 71 | }; 72 | C6412F0E1E76F03900F467FE /* Frameworks */ = { 73 | isa = PBXFrameworksBuildPhase; 74 | buildActionMask = 2147483647; 75 | files = ( 76 | ); 77 | runOnlyForDeploymentPostprocessing = 0; 78 | }; 79 | C6412F191E76F03900F467FE /* Frameworks */ = { 80 | isa = PBXFrameworksBuildPhase; 81 | buildActionMask = 2147483647; 82 | files = ( 83 | ); 84 | runOnlyForDeploymentPostprocessing = 0; 85 | }; 86 | /* End PBXFrameworksBuildPhase section */ 87 | 88 | /* Begin PBXGroup section */ 89 | C6412EF21E76F03900F467FE = { 90 | isa = PBXGroup; 91 | children = ( 92 | C6412EFD1E76F03900F467FE /* SimulateLocation */, 93 | C6412F141E76F03900F467FE /* SimulateLocationTests */, 94 | C6412F1F1E76F03900F467FE /* SimulateLocationUITests */, 95 | C6412EFC1E76F03900F467FE /* Products */, 96 | ); 97 | sourceTree = ""; 98 | }; 99 | C6412EFC1E76F03900F467FE /* Products */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | C6412EFB1E76F03900F467FE /* SimulateLocation.app */, 103 | C6412F111E76F03900F467FE /* SimulateLocationTests.xctest */, 104 | C6412F1C1E76F03900F467FE /* SimulateLocationUITests.xctest */, 105 | ); 106 | name = Products; 107 | sourceTree = ""; 108 | }; 109 | C6412EFD1E76F03900F467FE /* SimulateLocation */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | C6412EFE1E76F03900F467FE /* AppDelegate.swift */, 113 | C6412F001E76F03900F467FE /* FirstViewController.swift */, 114 | C6412F021E76F03900F467FE /* SecondViewController.swift */, 115 | C6412F311E7705AD00F467FE /* LocationTransform.swift */, 116 | C6412F301E76F06500F467FE /* Resources */, 117 | ); 118 | path = SimulateLocation; 119 | sourceTree = ""; 120 | }; 121 | C6412F141E76F03900F467FE /* SimulateLocationTests */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | C6412F151E76F03900F467FE /* SimulateLocationTests.swift */, 125 | C6412F171E76F03900F467FE /* Info.plist */, 126 | ); 127 | path = SimulateLocationTests; 128 | sourceTree = ""; 129 | }; 130 | C6412F1F1E76F03900F467FE /* SimulateLocationUITests */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | C6412F201E76F03900F467FE /* SimulateLocationUITests.swift */, 134 | C6412F221E76F03900F467FE /* Info.plist */, 135 | ); 136 | path = SimulateLocationUITests; 137 | sourceTree = ""; 138 | }; 139 | C6412F301E76F06500F467FE /* Resources */ = { 140 | isa = PBXGroup; 141 | children = ( 142 | C6904EB31EAE3DD800F4EF40 /* Transform */, 143 | C6412F041E76F03900F467FE /* Main.storyboard */, 144 | C6412F071E76F03900F467FE /* Assets.xcassets */, 145 | C6412F091E76F03900F467FE /* LaunchScreen.storyboard */, 146 | C6412F0C1E76F03900F467FE /* Info.plist */, 147 | C6412F2E1E76F05F00F467FE /* ZhongHang.gpx */, 148 | C61074641E82B3B5003EA65B /* WenHuaChanYe.gpx */, 149 | ); 150 | name = Resources; 151 | sourceTree = ""; 152 | }; 153 | C6904EB31EAE3DD800F4EF40 /* Transform */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | C6904EB41EAE3DD800F4EF40 /* transform.html */, 157 | C6904EB51EAE3DD800F4EF40 /* transform.js */, 158 | ); 159 | path = Transform; 160 | sourceTree = ""; 161 | }; 162 | /* End PBXGroup section */ 163 | 164 | /* Begin PBXNativeTarget section */ 165 | C6412EFA1E76F03900F467FE /* SimulateLocation */ = { 166 | isa = PBXNativeTarget; 167 | buildConfigurationList = C6412F251E76F03900F467FE /* Build configuration list for PBXNativeTarget "SimulateLocation" */; 168 | buildPhases = ( 169 | C6412EF71E76F03900F467FE /* Sources */, 170 | C6412EF81E76F03900F467FE /* Frameworks */, 171 | C6412EF91E76F03900F467FE /* Resources */, 172 | ); 173 | buildRules = ( 174 | ); 175 | dependencies = ( 176 | ); 177 | name = SimulateLocation; 178 | productName = SimulateLocation; 179 | productReference = C6412EFB1E76F03900F467FE /* SimulateLocation.app */; 180 | productType = "com.apple.product-type.application"; 181 | }; 182 | C6412F101E76F03900F467FE /* SimulateLocationTests */ = { 183 | isa = PBXNativeTarget; 184 | buildConfigurationList = C6412F281E76F03900F467FE /* Build configuration list for PBXNativeTarget "SimulateLocationTests" */; 185 | buildPhases = ( 186 | C6412F0D1E76F03900F467FE /* Sources */, 187 | C6412F0E1E76F03900F467FE /* Frameworks */, 188 | C6412F0F1E76F03900F467FE /* Resources */, 189 | ); 190 | buildRules = ( 191 | ); 192 | dependencies = ( 193 | C6412F131E76F03900F467FE /* PBXTargetDependency */, 194 | ); 195 | name = SimulateLocationTests; 196 | productName = SimulateLocationTests; 197 | productReference = C6412F111E76F03900F467FE /* SimulateLocationTests.xctest */; 198 | productType = "com.apple.product-type.bundle.unit-test"; 199 | }; 200 | C6412F1B1E76F03900F467FE /* SimulateLocationUITests */ = { 201 | isa = PBXNativeTarget; 202 | buildConfigurationList = C6412F2B1E76F03900F467FE /* Build configuration list for PBXNativeTarget "SimulateLocationUITests" */; 203 | buildPhases = ( 204 | C6412F181E76F03900F467FE /* Sources */, 205 | C6412F191E76F03900F467FE /* Frameworks */, 206 | C6412F1A1E76F03900F467FE /* Resources */, 207 | ); 208 | buildRules = ( 209 | ); 210 | dependencies = ( 211 | C6412F1E1E76F03900F467FE /* PBXTargetDependency */, 212 | ); 213 | name = SimulateLocationUITests; 214 | productName = SimulateLocationUITests; 215 | productReference = C6412F1C1E76F03900F467FE /* SimulateLocationUITests.xctest */; 216 | productType = "com.apple.product-type.bundle.ui-testing"; 217 | }; 218 | /* End PBXNativeTarget section */ 219 | 220 | /* Begin PBXProject section */ 221 | C6412EF31E76F03900F467FE /* Project object */ = { 222 | isa = PBXProject; 223 | attributes = { 224 | LastSwiftUpdateCheck = 0820; 225 | LastUpgradeCheck = 0820; 226 | ORGANIZATIONNAME = RockerHX; 227 | TargetAttributes = { 228 | C6412EFA1E76F03900F467FE = { 229 | CreatedOnToolsVersion = 8.2.1; 230 | DevelopmentTeam = 8TY7SD6QGK; 231 | ProvisioningStyle = Automatic; 232 | }; 233 | C6412F101E76F03900F467FE = { 234 | CreatedOnToolsVersion = 8.2.1; 235 | ProvisioningStyle = Automatic; 236 | TestTargetID = C6412EFA1E76F03900F467FE; 237 | }; 238 | C6412F1B1E76F03900F467FE = { 239 | CreatedOnToolsVersion = 8.2.1; 240 | ProvisioningStyle = Automatic; 241 | TestTargetID = C6412EFA1E76F03900F467FE; 242 | }; 243 | }; 244 | }; 245 | buildConfigurationList = C6412EF61E76F03900F467FE /* Build configuration list for PBXProject "SimulateLocation" */; 246 | compatibilityVersion = "Xcode 3.2"; 247 | developmentRegion = English; 248 | hasScannedForEncodings = 0; 249 | knownRegions = ( 250 | en, 251 | Base, 252 | ); 253 | mainGroup = C6412EF21E76F03900F467FE; 254 | productRefGroup = C6412EFC1E76F03900F467FE /* Products */; 255 | projectDirPath = ""; 256 | projectRoot = ""; 257 | targets = ( 258 | C6412EFA1E76F03900F467FE /* SimulateLocation */, 259 | C6412F101E76F03900F467FE /* SimulateLocationTests */, 260 | C6412F1B1E76F03900F467FE /* SimulateLocationUITests */, 261 | ); 262 | }; 263 | /* End PBXProject section */ 264 | 265 | /* Begin PBXResourcesBuildPhase section */ 266 | C6412EF91E76F03900F467FE /* Resources */ = { 267 | isa = PBXResourcesBuildPhase; 268 | buildActionMask = 2147483647; 269 | files = ( 270 | C6412F0B1E76F03900F467FE /* LaunchScreen.storyboard in Resources */, 271 | C6412F2F1E76F05F00F467FE /* ZhongHang.gpx in Resources */, 272 | C6412F081E76F03900F467FE /* Assets.xcassets in Resources */, 273 | C6904EB61EAE3DD800F4EF40 /* transform.html in Resources */, 274 | C6412F061E76F03900F467FE /* Main.storyboard in Resources */, 275 | C61074651E82B3B5003EA65B /* WenHuaChanYe.gpx in Resources */, 276 | C6904EB71EAE3DD800F4EF40 /* transform.js in Resources */, 277 | ); 278 | runOnlyForDeploymentPostprocessing = 0; 279 | }; 280 | C6412F0F1E76F03900F467FE /* Resources */ = { 281 | isa = PBXResourcesBuildPhase; 282 | buildActionMask = 2147483647; 283 | files = ( 284 | ); 285 | runOnlyForDeploymentPostprocessing = 0; 286 | }; 287 | C6412F1A1E76F03900F467FE /* Resources */ = { 288 | isa = PBXResourcesBuildPhase; 289 | buildActionMask = 2147483647; 290 | files = ( 291 | ); 292 | runOnlyForDeploymentPostprocessing = 0; 293 | }; 294 | /* End PBXResourcesBuildPhase section */ 295 | 296 | /* Begin PBXSourcesBuildPhase section */ 297 | C6412EF71E76F03900F467FE /* Sources */ = { 298 | isa = PBXSourcesBuildPhase; 299 | buildActionMask = 2147483647; 300 | files = ( 301 | C6412F031E76F03900F467FE /* SecondViewController.swift in Sources */, 302 | C6412EFF1E76F03900F467FE /* AppDelegate.swift in Sources */, 303 | C6412F011E76F03900F467FE /* FirstViewController.swift in Sources */, 304 | C6412F321E7705AD00F467FE /* LocationTransform.swift in Sources */, 305 | ); 306 | runOnlyForDeploymentPostprocessing = 0; 307 | }; 308 | C6412F0D1E76F03900F467FE /* Sources */ = { 309 | isa = PBXSourcesBuildPhase; 310 | buildActionMask = 2147483647; 311 | files = ( 312 | C6412F161E76F03900F467FE /* SimulateLocationTests.swift in Sources */, 313 | ); 314 | runOnlyForDeploymentPostprocessing = 0; 315 | }; 316 | C6412F181E76F03900F467FE /* Sources */ = { 317 | isa = PBXSourcesBuildPhase; 318 | buildActionMask = 2147483647; 319 | files = ( 320 | C6412F211E76F03900F467FE /* SimulateLocationUITests.swift in Sources */, 321 | ); 322 | runOnlyForDeploymentPostprocessing = 0; 323 | }; 324 | /* End PBXSourcesBuildPhase section */ 325 | 326 | /* Begin PBXTargetDependency section */ 327 | C6412F131E76F03900F467FE /* PBXTargetDependency */ = { 328 | isa = PBXTargetDependency; 329 | target = C6412EFA1E76F03900F467FE /* SimulateLocation */; 330 | targetProxy = C6412F121E76F03900F467FE /* PBXContainerItemProxy */; 331 | }; 332 | C6412F1E1E76F03900F467FE /* PBXTargetDependency */ = { 333 | isa = PBXTargetDependency; 334 | target = C6412EFA1E76F03900F467FE /* SimulateLocation */; 335 | targetProxy = C6412F1D1E76F03900F467FE /* PBXContainerItemProxy */; 336 | }; 337 | /* End PBXTargetDependency section */ 338 | 339 | /* Begin PBXVariantGroup section */ 340 | C6412F041E76F03900F467FE /* Main.storyboard */ = { 341 | isa = PBXVariantGroup; 342 | children = ( 343 | C6412F051E76F03900F467FE /* Base */, 344 | ); 345 | name = Main.storyboard; 346 | sourceTree = ""; 347 | }; 348 | C6412F091E76F03900F467FE /* LaunchScreen.storyboard */ = { 349 | isa = PBXVariantGroup; 350 | children = ( 351 | C6412F0A1E76F03900F467FE /* Base */, 352 | ); 353 | name = LaunchScreen.storyboard; 354 | sourceTree = ""; 355 | }; 356 | /* End PBXVariantGroup section */ 357 | 358 | /* Begin XCBuildConfiguration section */ 359 | C6412F231E76F03900F467FE /* Debug */ = { 360 | isa = XCBuildConfiguration; 361 | buildSettings = { 362 | ALWAYS_SEARCH_USER_PATHS = NO; 363 | CLANG_ANALYZER_NONNULL = YES; 364 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 365 | CLANG_CXX_LIBRARY = "libc++"; 366 | CLANG_ENABLE_MODULES = YES; 367 | CLANG_ENABLE_OBJC_ARC = YES; 368 | CLANG_WARN_BOOL_CONVERSION = YES; 369 | CLANG_WARN_CONSTANT_CONVERSION = YES; 370 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 371 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 372 | CLANG_WARN_EMPTY_BODY = YES; 373 | CLANG_WARN_ENUM_CONVERSION = YES; 374 | CLANG_WARN_INFINITE_RECURSION = YES; 375 | CLANG_WARN_INT_CONVERSION = YES; 376 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 377 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 378 | CLANG_WARN_UNREACHABLE_CODE = YES; 379 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 380 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 381 | COPY_PHASE_STRIP = NO; 382 | DEBUG_INFORMATION_FORMAT = dwarf; 383 | ENABLE_STRICT_OBJC_MSGSEND = YES; 384 | ENABLE_TESTABILITY = YES; 385 | GCC_C_LANGUAGE_STANDARD = gnu99; 386 | GCC_DYNAMIC_NO_PIC = NO; 387 | GCC_NO_COMMON_BLOCKS = YES; 388 | GCC_OPTIMIZATION_LEVEL = 0; 389 | GCC_PREPROCESSOR_DEFINITIONS = ( 390 | "DEBUG=1", 391 | "$(inherited)", 392 | ); 393 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 394 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 395 | GCC_WARN_UNDECLARED_SELECTOR = YES; 396 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 397 | GCC_WARN_UNUSED_FUNCTION = YES; 398 | GCC_WARN_UNUSED_VARIABLE = YES; 399 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 400 | MTL_ENABLE_DEBUG_INFO = YES; 401 | ONLY_ACTIVE_ARCH = YES; 402 | SDKROOT = iphoneos; 403 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 404 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 405 | TARGETED_DEVICE_FAMILY = "1,2"; 406 | }; 407 | name = Debug; 408 | }; 409 | C6412F241E76F03900F467FE /* Release */ = { 410 | isa = XCBuildConfiguration; 411 | buildSettings = { 412 | ALWAYS_SEARCH_USER_PATHS = NO; 413 | CLANG_ANALYZER_NONNULL = YES; 414 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 415 | CLANG_CXX_LIBRARY = "libc++"; 416 | CLANG_ENABLE_MODULES = YES; 417 | CLANG_ENABLE_OBJC_ARC = YES; 418 | CLANG_WARN_BOOL_CONVERSION = YES; 419 | CLANG_WARN_CONSTANT_CONVERSION = YES; 420 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 421 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 422 | CLANG_WARN_EMPTY_BODY = YES; 423 | CLANG_WARN_ENUM_CONVERSION = YES; 424 | CLANG_WARN_INFINITE_RECURSION = YES; 425 | CLANG_WARN_INT_CONVERSION = YES; 426 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 427 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 428 | CLANG_WARN_UNREACHABLE_CODE = YES; 429 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 430 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 431 | COPY_PHASE_STRIP = NO; 432 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 433 | ENABLE_NS_ASSERTIONS = NO; 434 | ENABLE_STRICT_OBJC_MSGSEND = YES; 435 | GCC_C_LANGUAGE_STANDARD = gnu99; 436 | GCC_NO_COMMON_BLOCKS = YES; 437 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 438 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 439 | GCC_WARN_UNDECLARED_SELECTOR = YES; 440 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 441 | GCC_WARN_UNUSED_FUNCTION = YES; 442 | GCC_WARN_UNUSED_VARIABLE = YES; 443 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 444 | MTL_ENABLE_DEBUG_INFO = NO; 445 | SDKROOT = iphoneos; 446 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 447 | TARGETED_DEVICE_FAMILY = "1,2"; 448 | VALIDATE_PRODUCT = YES; 449 | }; 450 | name = Release; 451 | }; 452 | C6412F261E76F03900F467FE /* Debug */ = { 453 | isa = XCBuildConfiguration; 454 | buildSettings = { 455 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 456 | DEVELOPMENT_TEAM = 8TY7SD6QGK; 457 | INFOPLIST_FILE = SimulateLocation/Info.plist; 458 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 459 | PRODUCT_BUNDLE_IDENTIFIER = cc.caver.HXKit.SimulateLocation; 460 | PRODUCT_NAME = "$(TARGET_NAME)"; 461 | SWIFT_VERSION = 3.0; 462 | TARGETED_DEVICE_FAMILY = 1; 463 | }; 464 | name = Debug; 465 | }; 466 | C6412F271E76F03900F467FE /* Release */ = { 467 | isa = XCBuildConfiguration; 468 | buildSettings = { 469 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 470 | DEVELOPMENT_TEAM = 8TY7SD6QGK; 471 | INFOPLIST_FILE = SimulateLocation/Info.plist; 472 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 473 | PRODUCT_BUNDLE_IDENTIFIER = cc.caver.HXKit.SimulateLocation; 474 | PRODUCT_NAME = "$(TARGET_NAME)"; 475 | SWIFT_VERSION = 3.0; 476 | TARGETED_DEVICE_FAMILY = 1; 477 | }; 478 | name = Release; 479 | }; 480 | C6412F291E76F03900F467FE /* Debug */ = { 481 | isa = XCBuildConfiguration; 482 | buildSettings = { 483 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 484 | BUNDLE_LOADER = "$(TEST_HOST)"; 485 | INFOPLIST_FILE = SimulateLocationTests/Info.plist; 486 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 487 | PRODUCT_BUNDLE_IDENTIFIER = cc.caver.HXKit.SimulateLocationTests; 488 | PRODUCT_NAME = "$(TARGET_NAME)"; 489 | SWIFT_VERSION = 3.0; 490 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SimulateLocation.app/SimulateLocation"; 491 | }; 492 | name = Debug; 493 | }; 494 | C6412F2A1E76F03900F467FE /* Release */ = { 495 | isa = XCBuildConfiguration; 496 | buildSettings = { 497 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 498 | BUNDLE_LOADER = "$(TEST_HOST)"; 499 | INFOPLIST_FILE = SimulateLocationTests/Info.plist; 500 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 501 | PRODUCT_BUNDLE_IDENTIFIER = cc.caver.HXKit.SimulateLocationTests; 502 | PRODUCT_NAME = "$(TARGET_NAME)"; 503 | SWIFT_VERSION = 3.0; 504 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SimulateLocation.app/SimulateLocation"; 505 | }; 506 | name = Release; 507 | }; 508 | C6412F2C1E76F03900F467FE /* Debug */ = { 509 | isa = XCBuildConfiguration; 510 | buildSettings = { 511 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 512 | INFOPLIST_FILE = SimulateLocationUITests/Info.plist; 513 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 514 | PRODUCT_BUNDLE_IDENTIFIER = cc.caver.HXKit.SimulateLocationUITests; 515 | PRODUCT_NAME = "$(TARGET_NAME)"; 516 | SWIFT_VERSION = 3.0; 517 | TEST_TARGET_NAME = SimulateLocation; 518 | }; 519 | name = Debug; 520 | }; 521 | C6412F2D1E76F03900F467FE /* Release */ = { 522 | isa = XCBuildConfiguration; 523 | buildSettings = { 524 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 525 | INFOPLIST_FILE = SimulateLocationUITests/Info.plist; 526 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 527 | PRODUCT_BUNDLE_IDENTIFIER = cc.caver.HXKit.SimulateLocationUITests; 528 | PRODUCT_NAME = "$(TARGET_NAME)"; 529 | SWIFT_VERSION = 3.0; 530 | TEST_TARGET_NAME = SimulateLocation; 531 | }; 532 | name = Release; 533 | }; 534 | /* End XCBuildConfiguration section */ 535 | 536 | /* Begin XCConfigurationList section */ 537 | C6412EF61E76F03900F467FE /* Build configuration list for PBXProject "SimulateLocation" */ = { 538 | isa = XCConfigurationList; 539 | buildConfigurations = ( 540 | C6412F231E76F03900F467FE /* Debug */, 541 | C6412F241E76F03900F467FE /* Release */, 542 | ); 543 | defaultConfigurationIsVisible = 0; 544 | defaultConfigurationName = Release; 545 | }; 546 | C6412F251E76F03900F467FE /* Build configuration list for PBXNativeTarget "SimulateLocation" */ = { 547 | isa = XCConfigurationList; 548 | buildConfigurations = ( 549 | C6412F261E76F03900F467FE /* Debug */, 550 | C6412F271E76F03900F467FE /* Release */, 551 | ); 552 | defaultConfigurationIsVisible = 0; 553 | defaultConfigurationName = Release; 554 | }; 555 | C6412F281E76F03900F467FE /* Build configuration list for PBXNativeTarget "SimulateLocationTests" */ = { 556 | isa = XCConfigurationList; 557 | buildConfigurations = ( 558 | C6412F291E76F03900F467FE /* Debug */, 559 | C6412F2A1E76F03900F467FE /* Release */, 560 | ); 561 | defaultConfigurationIsVisible = 0; 562 | defaultConfigurationName = Release; 563 | }; 564 | C6412F2B1E76F03900F467FE /* Build configuration list for PBXNativeTarget "SimulateLocationUITests" */ = { 565 | isa = XCConfigurationList; 566 | buildConfigurations = ( 567 | C6412F2C1E76F03900F467FE /* Debug */, 568 | C6412F2D1E76F03900F467FE /* Release */, 569 | ); 570 | defaultConfigurationIsVisible = 0; 571 | defaultConfigurationName = Release; 572 | }; 573 | /* End XCConfigurationList section */ 574 | }; 575 | rootObject = C6412EF31E76F03900F467FE /* Project object */; 576 | } 577 | -------------------------------------------------------------------------------- /SimulateLocation.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SimulateLocation.xcodeproj/xcuserdata/rockerhx.xcuserdatad/xcschemes/SimulateLocation.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 89 | 90 | 91 | 97 | 99 | 105 | 106 | 107 | 108 | 110 | 111 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /SimulateLocation.xcodeproj/xcuserdata/rockerhx.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SimulateLocation.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | C6412EFA1E76F03900F467FE 16 | 17 | primary 18 | 19 | 20 | C6412F101E76F03900F467FE 21 | 22 | primary 23 | 24 | 25 | C6412F1B1E76F03900F467FE 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /SimulateLocation/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SimulateLocation 4 | // 5 | // Created by RockerHX on 2017/3/13. 6 | // Copyright © 2017年 RockerHX. 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 location = LocationTransform.gcj2wgs(gcjLat: 30.5907848, gcjLng: 104.06513393) 21 | let location = LocationTransform.gcj2wgs(gcjLat: 30.581237, gcjLng: 104.065644) 22 | print(location) 23 | 24 | return true 25 | } 26 | 27 | func applicationWillResignActive(_ application: UIApplication) { 28 | // 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. 29 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 30 | } 31 | 32 | func applicationDidEnterBackground(_ application: UIApplication) { 33 | // 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. 34 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 35 | } 36 | 37 | func applicationWillEnterForeground(_ application: UIApplication) { 38 | // 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. 39 | } 40 | 41 | func applicationDidBecomeActive(_ application: UIApplication) { 42 | // 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. 43 | } 44 | 45 | func applicationWillTerminate(_ application: UIApplication) { 46 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 47 | } 48 | 49 | 50 | } 51 | 52 | -------------------------------------------------------------------------------- /SimulateLocation/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /SimulateLocation/Assets.xcassets/first.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "first.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /SimulateLocation/Assets.xcassets/first.imageset/first.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongdong/SimulateLocation/e0257242d56af31ae61d3c2ccb7d480be2e11eff/SimulateLocation/Assets.xcassets/first.imageset/first.pdf -------------------------------------------------------------------------------- /SimulateLocation/Assets.xcassets/second.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "second.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /SimulateLocation/Assets.xcassets/second.imageset/second.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongdong/SimulateLocation/e0257242d56af31ae61d3c2ccb7d480be2e11eff/SimulateLocation/Assets.xcassets/second.imageset/second.pdf -------------------------------------------------------------------------------- /SimulateLocation/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 | -------------------------------------------------------------------------------- /SimulateLocation/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | Helvetica 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 36 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /SimulateLocation/FirstViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FirstViewController.swift 3 | // SimulateLocation 4 | // 5 | // Created by RockerHX on 2017/3/13. 6 | // Copyright © 2017年 RockerHX. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class FirstViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view, typically from a nib. 16 | } 17 | 18 | override func didReceiveMemoryWarning() { 19 | super.didReceiveMemoryWarning() 20 | // Dispose of any resources that can be recreated. 21 | } 22 | 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /SimulateLocation/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UIStatusBarTintParameters 32 | 33 | UINavigationBar 34 | 35 | Style 36 | UIBarStyleDefault 37 | Translucent 38 | 39 | 40 | 41 | UISupportedInterfaceOrientations 42 | 43 | UIInterfaceOrientationPortrait 44 | 45 | UISupportedInterfaceOrientations~ipad 46 | 47 | UIInterfaceOrientationPortrait 48 | UIInterfaceOrientationPortraitUpsideDown 49 | UIInterfaceOrientationLandscapeLeft 50 | UIInterfaceOrientationLandscapeRight 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /SimulateLocation/LocationTransform.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LocationTransform.swift 3 | // SimulateLocation 4 | // 5 | // Created by RockerHX on 2017/3/14. 6 | // Copyright © 2017年 RockerHX. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | * Struct transform coordinate between earth(WGS-84) and mars in china(GCJ-02). 13 | */ 14 | public struct LocationTransform { 15 | 16 | static let EARTH_R: Double = 6378137.0 17 | 18 | static func isOutOfChina(lat: Double, lng: Double) -> Bool { 19 | 20 | if lng < 72.004 || lng > 137.8347 { 21 | return true 22 | } 23 | if lat < 0.8293 || lat > 55.8271 { 24 | return true 25 | } 26 | return false 27 | } 28 | 29 | static func transform(x: Double, y: Double) -> (lat: Double, lng: Double) { 30 | 31 | let xy = x * y 32 | let absX = sqrt(fabs(x)) 33 | let xPi = x * Double.pi 34 | let yPi = y * Double.pi 35 | let d = 20.0 * sin(6.0 * xPi) + 20.0 * sin(2.0 * xPi) 36 | 37 | var lat = d 38 | var lng = d 39 | 40 | lat += 20.0 * sin(yPi) + 40.0 * sin(yPi / 3.0) 41 | lng += 20.0 * sin(xPi) + 40.0 * sin(xPi / 3.0) 42 | 43 | lat += 160.0 * sin(yPi / 12.0) + 320 * sin(yPi / 30.0) 44 | lng += 150.0 * sin(xPi / 12.0) + 300 * sin(xPi / 30.0) 45 | 46 | lat *= 2.0 / 3.0 47 | lng *= 2.0 / 3.0 48 | 49 | lat += -100 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * xy + 0.2 * absX 50 | lng += 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * xy + 0.1 * absX 51 | 52 | return (lat, lng) 53 | } 54 | 55 | static func delta(lat: Double, lng: Double) -> (dLat: Double, dLng: Double) { 56 | let ee = 0.00669342162296594323 57 | let radLat = lat / 180.0 * Double.pi 58 | var magic = sin(radLat) 59 | magic = 1 - ee * magic * magic 60 | let sqrtMagic = sqrt(magic) 61 | var (dLat, dLng) = transform(x: lng - 105.0, y: lat - 35.0) 62 | dLat = (dLat * 180.0) / ((EARTH_R * (1 - ee)) / (magic * sqrtMagic) * Double.pi) 63 | dLng = (dLng * 180.0) / (EARTH_R / sqrtMagic * cos(radLat) * Double.pi) 64 | return (dLat, dLng) 65 | } 66 | 67 | /** 68 | * wgs2gcj convert WGS-84 coordinate(wgsLat, wgsLng) to GCJ-02 coordinate(gcjLat, gcjLng). 69 | */ 70 | public static func wgs2gcj(wgsLat: Double, wgsLng: Double) -> (gcjLat: Double, gcjLng: Double) { 71 | if isOutOfChina(lat: wgsLat, lng: wgsLng) { 72 | return (wgsLat, wgsLng) 73 | } 74 | let (dLat, dLng) = delta(lat: wgsLat, lng: wgsLng) 75 | return (wgsLat + dLat, wgsLng + dLng) 76 | } 77 | 78 | /** 79 | * gcj2wgs convert GCJ-02 coordinate(gcjLat, gcjLng) to WGS-84 coordinate(wgsLat, wgsLng). 80 | * The output WGS-84 coordinate's accuracy is 1m to 2m. If you want more exactly result, use gcj2wgs_exact. 81 | */ 82 | public static func gcj2wgs(gcjLat: Double, gcjLng: Double) -> (wgsLat: Double, wgsLng: Double) { 83 | if isOutOfChina(lat: gcjLat, lng: gcjLng) { 84 | return (gcjLat, gcjLng) 85 | } 86 | let (dLat, dLng) = delta(lat: gcjLat, lng: gcjLng) 87 | return (gcjLat - dLat, gcjLng - dLng) 88 | } 89 | 90 | /** 91 | * gcj2wgs_exact convert GCJ-02 coordinate(gcjLat, gcjLng) to WGS-84 coordinate(wgsLat, wgsLng). 92 | * The output WGS-84 coordinate's accuracy is less than 0.5m, but much slower than gcj2wgs. 93 | */ 94 | public static func gcj2wgs_exact(gcjLat: Double, gcjLng: Double) -> (wgsLat: Double, wgsLng: Double) { 95 | let initDelta = 0.01, threshold = 0.000001 96 | var (dLat, dLng) = (initDelta, initDelta) 97 | var (mLat, mLng) = (gcjLat - dLat, gcjLng - dLng) 98 | var (pLat, pLng) = (gcjLat + dLat, gcjLng + dLng) 99 | var (wgsLat, wgsLng) = (gcjLat, gcjLng) 100 | for _ in 0 ..< 30 { 101 | (wgsLat, wgsLng) = ((mLat + pLat) / 2, (mLng + pLng) / 2) 102 | let (tmpLat, tmpLng) = wgs2gcj(wgsLat: wgsLat, wgsLng: wgsLng) 103 | (dLat, dLng) = (tmpLat - gcjLat, tmpLng - gcjLng) 104 | if (fabs(dLat) < threshold) && (fabs(dLng) < threshold) { 105 | return (wgsLat, wgsLng) 106 | } 107 | if dLat > 0 { 108 | pLat = wgsLat 109 | } else { 110 | mLat = wgsLat 111 | } 112 | if dLng > 0 { 113 | pLng = wgsLng 114 | } else { 115 | mLng = wgsLng 116 | } 117 | } 118 | return (wgsLat, wgsLng) 119 | } 120 | 121 | /** 122 | * Distance calculate the distance between point(latA, lngA) and point(latB, lngB), unit in meter. 123 | */ 124 | public static func Distance(latA: Double, lngA: Double, latB: Double, lngB: Double) -> Double { 125 | let arcLatA = latA * Double.pi / 180 126 | let arcLatB = latB * Double.pi / 180 127 | let x = cos(arcLatA) * cos(arcLatB) * cos((lngA-lngB) * Double.pi/180) 128 | let y = sin(arcLatA) * sin(arcLatB) 129 | var s = x + y 130 | if s > 1 { 131 | s = 1 132 | } 133 | if s < -1 { 134 | s = -1 135 | } 136 | let alpha = acos(s) 137 | let distance = alpha * EARTH_R 138 | return distance 139 | } 140 | } 141 | 142 | extension LocationTransform { 143 | 144 | public static func gcj2bd(gcjLat: Double, gcjLng: Double) -> (bdLat: Double, bdLng: Double) { 145 | if isOutOfChina(lat: gcjLat, lng: gcjLng) { 146 | return (gcjLat, gcjLng) 147 | } 148 | let x = gcjLng, y = gcjLat 149 | let z = sqrt(x * x + y * y) + 0.00002 * sin(y * Double.pi) 150 | let theta = atan2(y, x) + 0.000003 * cos(x * Double.pi) 151 | let bdLng = z * cos(theta) + 0.0065 152 | let bdLat = z * sin(theta) + 0.006 153 | return (bdLat, bdLng) 154 | } 155 | 156 | public static func bd2gcj(bdLat: Double, bdLng: Double) -> (gcjLat: Double, gcjLng: Double) { 157 | if isOutOfChina(lat: bdLat, lng: bdLng) { 158 | return (bdLat, bdLng) 159 | } 160 | let x = bdLng - 0.0065, y = bdLat - 0.006 161 | let z = sqrt(x * x + y * y) - 0.00002 * sin(y * Double.pi) 162 | let theta = atan2(y, x) - 0.000003 * cos(x * Double.pi) 163 | let gcjLng = z * cos(theta) 164 | let gcjLat = z * sin(theta) 165 | return (gcjLat, gcjLng) 166 | } 167 | 168 | public static func wgs2bd(wgsLat: Double, wgsLng: Double) -> (bdLat: Double, bdLng: Double) { 169 | let (gcjLat, gcjLng) = wgs2gcj(wgsLat: wgsLat, wgsLng: wgsLng) 170 | return gcj2bd(gcjLat: gcjLat, gcjLng: gcjLng) 171 | } 172 | 173 | public static func bd2wgs(bdLat: Double, bdLng: Double) -> (wgsLat: Double, wgsLng: Double) { 174 | let (gcjLat, gcjLng) = bd2gcj(bdLat: bdLat, bdLng: bdLng) 175 | return gcj2wgs(gcjLat: gcjLat, gcjLng: gcjLng) 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /SimulateLocation/SecondViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SecondViewController.swift 3 | // SimulateLocation 4 | // 5 | // Created by RockerHX on 2017/3/13. 6 | // Copyright © 2017年 RockerHX. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SecondViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view, typically from a nib. 16 | } 17 | 18 | override func didReceiveMemoryWarning() { 19 | super.didReceiveMemoryWarning() 20 | // Dispose of any resources that can be recreated. 21 | } 22 | 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /SimulateLocation/Transform/transform.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | 14 | 高德坐标拾取系统 15 | 百度坐标拾取系统 16 | 17 |
18 |

lat

19 |

lon

20 |
21 | 22 |
23 |

24 |

25 |
26 |
27 |

lat:

28 |

lon:

29 |
30 | 31 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /SimulateLocation/Transform/transform.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var exports; 4 | if (typeof module === "object" && exports) { 5 | exports = module.exports; 6 | } else if (typeof window !== "undefined") { 7 | exports = window["eviltransform"] = {}; 8 | } 9 | 10 | var earthR = 6378137.0; 11 | 12 | function outOfChina(lat, lng) { 13 | if ((lng < 72.004) || (lng > 137.8347)) { 14 | return true; 15 | } 16 | if ((lat < 0.8293) || (lat > 55.8271)) { 17 | return true; 18 | } 19 | return false; 20 | } 21 | 22 | function transform(x, y) { 23 | var xy = x * y; 24 | var absX = Math.sqrt(Math.abs(x)); 25 | var xPi = x * Math.PI; 26 | var yPi = y * Math.PI; 27 | var d = 20.0*Math.sin(6.0*xPi) + 20.0*Math.sin(2.0*xPi); 28 | 29 | var lat = d; 30 | var lng = d; 31 | 32 | lat += 20.0*Math.sin(yPi) + 40.0*Math.sin(yPi/3.0); 33 | lng += 20.0*Math.sin(xPi) + 40.0*Math.sin(xPi/3.0); 34 | 35 | lat += 160.0*Math.sin(yPi/12.0) + 320*Math.sin(yPi/30.0); 36 | lng += 150.0*Math.sin(xPi/12.0) + 300.0*Math.sin(xPi/30.0); 37 | 38 | lat *= 2.0 / 3.0; 39 | lng *= 2.0 / 3.0; 40 | 41 | lat += -100.0 + 2.0*x + 3.0*y + 0.2*y*y + 0.1*xy + 0.2*absX; 42 | lng += 300.0 + x + 2.0*y + 0.1*x*x + 0.1*xy + 0.1*absX; 43 | 44 | return {lat: lat, lng: lng} 45 | } 46 | 47 | function delta(lat, lng) { 48 | var ee = 0.00669342162296594323; 49 | var d = transform(lng-105.0, lat-35.0); 50 | var radLat = lat / 180.0 * Math.PI; 51 | var magic = Math.sin(radLat); 52 | magic = 1 - ee*magic*magic; 53 | var sqrtMagic = Math.sqrt(magic); 54 | d.lat = (d.lat * 180.0) / ((earthR * (1 - ee)) / (magic * sqrtMagic) * Math.PI); 55 | d.lng = (d.lng * 180.0) / (earthR / sqrtMagic * Math.cos(radLat) * Math.PI); 56 | return d; 57 | } 58 | 59 | function wgs2gcj(wgsLat, wgsLng) { 60 | if (outOfChina(wgsLat, wgsLng)) { 61 | return {lat: wgsLat, lng: wgsLng}; 62 | } 63 | var d = delta(wgsLat, wgsLng); 64 | return {lat: wgsLat + d.lat, lng: wgsLng + d.lng}; 65 | } 66 | exports.wgs2gcj = wgs2gcj; 67 | 68 | function gcj2wgs(gcjLat, gcjLng) { 69 | if (outOfChina(gcjLat, gcjLng)) { 70 | return {lat: gcjLat, lng: gcjLng}; 71 | } 72 | var d = delta(gcjLat, gcjLng); 73 | return {lat: gcjLat - d.lat, lng: gcjLng - d.lng}; 74 | } 75 | exports.gcj2wgs = gcj2wgs; 76 | 77 | function gcj2wgs_exact(gcjLat, gcjLng) { 78 | // newCoord = oldCoord = gcjCoord 79 | var newLat = gcjLat, newLng = gcjLng; 80 | var oldLat = newLat, oldLng = newLng; 81 | var threshold = 1e-6; // ~0.55 m equator & latitude 82 | 83 | for (var i = 0; i < 30; i++) { 84 | // oldCoord = newCoord 85 | oldLat = newLat; 86 | oldLng = newLng; 87 | // newCoord = gcjCoord - wgs_to_gcj_delta(newCoord) 88 | var tmp = wgs2gcj(newLat, newLng); 89 | // approx difference using gcj-space difference 90 | newLat -= gcjLat - tmp.lat; 91 | newLng -= gcjLng - tmp.lng; 92 | // diffchk 93 | if (Math.max(Math.abs(oldLat - newLat), Math.abs(oldLng - newLng)) < threshold) { 94 | break; 95 | } 96 | } 97 | return {lat: newLat, lng: newLng}; 98 | } 99 | exports.gcj2wgs_exact = gcj2wgs_exact; 100 | 101 | function distance(latA, lngA, latB, lngB) { 102 | var pi180 = Math.PI / 180; 103 | var arcLatA = latA * pi180; 104 | var arcLatB = latB * pi180; 105 | var x = Math.cos(arcLatA) * Math.cos(arcLatB) * Math.cos((lngA-lngB)*pi180); 106 | var y = Math.sin(arcLatA) * Math.sin(arcLatB); 107 | var s = x + y; 108 | if (s > 1) { 109 | s = 1; 110 | } 111 | if (s < -1) { 112 | s = -1; 113 | } 114 | var alpha = Math.acos(s); 115 | var distance = alpha * earthR; 116 | return distance; 117 | } 118 | exports.distance = distance; 119 | 120 | function gcj2bd(gcjLat, gcjLng) { 121 | if (outOfChina(gcjLat, gcjLng)) { 122 | return {lat: gcjLat, lng: gcjLng}; 123 | } 124 | 125 | var x = gcjLng, y = gcjLat; 126 | var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * Math.PI); 127 | var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * Math.PI); 128 | var bdLng = z * Math.cos(theta) + 0.0065; 129 | var bdLat = z * Math.sin(theta) + 0.006; 130 | return {lat: bdLat, lng: bdLng}; 131 | } 132 | exports.gcj2bd = gcj2bd; 133 | 134 | function bd2gcj(bdLat, bdLng) { 135 | if (outOfChina(bdLat, bdLng)) { 136 | return {lat: bdLat, lng: bdLng}; 137 | } 138 | 139 | var x = bdLng - 0.0065, y = bdLat - 0.006; 140 | var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * Math.PI); 141 | var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * Math.PI); 142 | var gcjLng = z * Math.cos(theta); 143 | var gcjLat = z * Math.sin(theta); 144 | return {lat: gcjLat, lng: gcjLng}; 145 | } 146 | exports.bd2gcj = bd2gcj; 147 | 148 | function wgs2bd(wgsLat, wgsLng) { 149 | var gcj = wgs2gcj(wgsLat, wgsLng); 150 | return gcj2bd(gcj.lat, gcj.lng); 151 | } 152 | exports.wgs2bd = wgs2bd; 153 | 154 | function bd2wgs(bdLat, bdLng) { 155 | var gcj = bd2gcj(bdLat, bdLng); 156 | return gcj2wgs(gcj.lat, gcj.lng); 157 | } 158 | exports.bd2wgs = bd2wgs; -------------------------------------------------------------------------------- /SimulateLocation/WenHuaChanYe.gpx: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SimulateLocation/ZhongHang.gpx: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /SimulateLocationTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /SimulateLocationTests/SimulateLocationTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SimulateLocationTests.swift 3 | // SimulateLocationTests 4 | // 5 | // Created by RockerHX on 2017/3/13. 6 | // Copyright © 2017年 RockerHX. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import SimulateLocation 11 | 12 | class SimulateLocationTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /SimulateLocationUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /SimulateLocationUITests/SimulateLocationUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SimulateLocationUITests.swift 3 | // SimulateLocationUITests 4 | // 5 | // Created by RockerHX on 2017/3/13. 6 | // Copyright © 2017年 RockerHX. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class SimulateLocationUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | } 37 | --------------------------------------------------------------------------------