├── README.md ├── iOSUITests.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── dyw.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── dyw.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── iOSUITests.xcscheme │ └── xcschememanagement.plist ├── iOSUITests ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── HomeTableView.h ├── HomeTableView.m ├── HomeViewController.h ├── HomeViewController.m ├── Info.plist ├── InformationViewController.h ├── InformationViewController.m ├── LoginManager.h ├── LoginManager.m ├── LoginViewController.h ├── LoginViewController.m ├── MineViewController.h ├── MineViewController.m ├── TabBarController.h ├── TabBarController.m └── main.m ├── iOSUITestsTests ├── Info.plist └── iOSUITestsTests.m └── iOSUITestsUITests ├── Info.plist └── iOSUITestsUITests.m /README.md: -------------------------------------------------------------------------------- 1 | #iOS UITests(UI自动化测试 实现) 2 | [博客地址http://www.jianshu.com/p/cf445a2f5f5b](http://www.jianshu.com/p/cf445a2f5f5b) 3 | [toc] 4 | 5 | ###简介 6 | 1.UI Tests是一个自动测试UI与交互的Testing组件,它可以通过编写代码、或者是记录开发者的操作过程并代码化,来实现自动点击某个按钮、视图,或者自动输入文字等功能。 7 | 2.在实际的开发过程中,随着项目越做越大,功能越来越多,仅仅靠人工操作的方式来覆盖所有测试用例是非常困难的,尤其是加入新功能以后,旧的功能也要重新测试一遍,这导致了测试需要花非常多的时间来进行回归测试,这里产生了大量重复的工作,而这些重复的工作有些是可以自动完成的,这时候UI Tests就可以帮助解决这个问题了. 8 | ![home.gif](http://upload-images.jianshu.io/upload_images/1760826-580849733a553b26.gif?imageMogr2/auto-orient/strip) 9 | 10 | ###最低要求 11 | Xcode7 12 | iOS 9 13 | ###使用 14 | 1.添加**UI Teste Targets** 15 | [新工程]() 创建工程的时候勾选 **Inclide UI Tests** 16 | 17 | ![Paste_Image.png](http://upload-images.jianshu.io/upload_images/1760826-0b1d6f54bb5edd2a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 18 | 19 | [现有的工程]() 新建一个 **Targets** 选择 **iOS UI Testing Bundle** 20 | 21 | ![Paste_Image.png](http://upload-images.jianshu.io/upload_images/1760826-adafbffe2b8cd29a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 22 | 23 | 24 | ![Paste_Image.png](http://upload-images.jianshu.io/upload_images/1760826-ac390e78bfb2aaeb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 25 | 26 | [添加完成]() 添加完成可以看到**UITests**如图: 27 | 28 | ![Paste_Image.png](http://upload-images.jianshu.io/upload_images/1760826-c5ceeecce273bc02.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 29 | 30 | 31 | ------- 32 | ### 自动化测试代码的编写 33 | #####方法1.自己看着界面编写 34 | 参考文章下面的代码演示 35 | [iOS UITests(自动化测试)常用类参考文档](http://www.jianshu.com/p/3b43e56c0a13) 36 | [参考Demo](https://github.com/ywdonga/iOSUITestsDemo) 37 | #####方法2.录制后修改 38 | 1.点击`UITests`类 下面的 红色的录制按钮 39 | ![Paste_Image.png](http://upload-images.jianshu.io/upload_images/1760826-0dc157d624c8746b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 40 | 然后APP会启动,你只需要对APP进行界面操作,系统就会在你光标最后停留的位置开始生成与你操作对应的代码,然后你稍作修改就可以用了。 41 | 看大大大图 42 | ![recode.gif](http://upload-images.jianshu.io/upload_images/1760826-058e1ba88a3a6ae7.gif?imageMogr2/auto-orient/strip) 43 | 自动生成的代码 44 | ![Paste_Image.png](http://upload-images.jianshu.io/upload_images/1760826-b6bd698545175cf7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 45 | 稍作修改,把里面的Unicode编码 转成中文,如下 46 | ![Paste_Image.png](http://upload-images.jianshu.io/upload_images/1760826-526fcb0d0dc4c55a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 47 | 这样就可以直接运行了 48 | 49 | 50 | ###运行自动化测试 51 | 1.` command + U` 运行UITests类中 每一个以`test`开头的方法 如:'- (void)allTestExample' '- (void)testHome' 个人感觉是没有顺序的 52 | ![Paste_Image.png](http://upload-images.jianshu.io/upload_images/1760826-7608eeda2f77a639.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 53 | 2.点击每一个以`test`开头的方法前面的 播放 按钮(运行单个方法) 54 | ![Paste_Image.png](http://upload-images.jianshu.io/upload_images/1760826-4dcd3633dda515a0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 55 | ###涉及到的新类 56 | ###[iOS UITests(自动化测试)常用类参考文档](http://www.jianshu.com/p/3b43e56c0a13) 57 | 58 | > 59 | >XCUIApplication - 启动程序 60 | ------ 61 | >#####1.简介 62 | 这个类掌管应用程序的生命周期,代表被测应用继承 63 | >XCUIElement - 元素 64 | ------- 65 | >#####1.简介 66 | >继承NSObject,实现协议XCUIElementAttributes, XCUIElementTypeQueryProvider 67 | 可以表示系统的各种UI元素 68 | >XCUIElementQuery - 查找元素 69 | ------- 70 | >用于定位用户界面元素的查询 71 | 72 | ###[iOS UITests(自动化测试)常用类参考文档](http://www.jianshu.com/p/3b43e56c0a13) 73 | 74 | ------- 75 | 76 | ###[代码演示](https://github.com/ywdonga/iOSUITestsDemo) 77 | [https://github.com/ywdonga/iOSUITestsDemo](https://github.com/ywdonga/iOSUITestsDemo) 78 | 为了更好的演示 我用storyboard搭建了一个可以简单跳转的界面 79 | ![Jietu20170317-093727.png](http://upload-images.jianshu.io/upload_images/1760826-9e09b8e6028041e1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 80 | ####1.我们从首页的测试开始(未登录的首页) 81 | 测试首页我们首先得判断是否已经登录,因为已登录和未登录是无法进入 我的、资讯 这两个界面的。在选择这两个页面的时候会直接弹出登录界面,测试流程就会有差异。所以就得先判断当前状态是否是已登录状态。 82 | >**1.1 判断登录状态** 83 | 因为我们不能访问原有APP的任何变量,所以只能通过某个界面特有的元素Element 来进行判断。在这里我们看到 如果未登录的话 点击‘我的’ 一定会跳转到‘登录’界面,而在登录界面有一个‘登录’Label. 在这里 我就通过 登录界面中的一个 文字为‘登录’的Label元素 作为判断对象(当然你可以根据自己的想法去定,但是一定要确保元素的唯一性)。 84 | 流程如下 85 | ![Paste_Image.png](http://upload-images.jianshu.io/upload_images/1760826-561308b49ef1fa61.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 86 | ``` 87 | /** 判断是否在登陆界面 */ 88 | - (BOOL)isLogin{ 89 | BOOL isLogin; 90 | //进入我的界面 91 | XCUIElementQuery *tabBarsQuery = self.app.tabBars; 92 | XCUIElement *tableBarButton = tabBarsQuery.buttons[@"我的"]; 93 | !tableBarButton.exists?:[tableBarButton tap]; 94 | //获取标志性Element loginLabel 95 | XCUIElement *loginLabel = self.app.staticTexts[@"loginLabel"]; 96 | //判断是否登陆 97 | if(loginLabel.exists){//进入登陆界面(当前状态未登陆) 98 | XCUIElement *cancerButton = self.app.buttons[@"取消"]; 99 | !cancerButton.exists?:[cancerButton tap]; 100 | isLogin = NO; 101 | }else{//进入我的页面(当前状态已经登陆) 102 | tableBarButton = tabBarsQuery.buttons[@"首页"]; 103 | !tableBarButton.exists?:[tableBarButton tap]; 104 | isLogin = YES; 105 | } 106 | return isLogin; 107 | } 108 | ``` 109 | 上面代码中为何定义了一个变量(`BOOL isLogin`)去接收登录状态,为何不直接用 ‘登录’元素是否存在(`loginLabel.exists`)作为结果直接返回呢? 110 | 原因在于,在判断登录时,我们进入到其他界面了,为了不影响后面的测试流程,我们在判断完后最好要回到'首页'。然而在我们回到首页时候,登录元素在首页是找到不到的,'loginLabel.exists'直接为`NO`了。 111 | 112 | >**1.2 退出登录** 113 | >判断完登录状态后,就会出现两种情况了,登录/未登录,由于我们现在的目的是测试未登录的首页,那么如果是已经登录了就先退出登陆 114 | ![logOut.gif](http://upload-images.jianshu.io/upload_images/1760826-5114fbb153f13ffc.gif?imageMogr2/auto-orient/strip) 115 | 流程就是 116 | 判断是否登陆 ->已经登陆 去‘我的’界面找到‘退出登陆’按钮,点击退出登陆 117 | 118 | ``` 119 | - (void)testLogOut{ 120 | //判断是否登陆 121 | if([self isLogin]){ 122 | NSLog(@"--> 开始退出登陆"); 123 | //进入我的页面 124 | XCUIElement *tableBarButton = self.app.tabBars.buttons[@"我的"]; 125 | !tableBarButton.exists?:[tableBarButton tap]; 126 | 127 | //向上滑一点 避免小屏幕看不到按钮 128 | XCUIElement *tableView = [self.app.tables elementAtIndex:0]; 129 | [tableView swipeUp]; 130 | 131 | XCUIElementQuery *tablesQuery = self.app.tables; 132 | [tablesQuery.buttons[@"退出登陆"] tap]; 133 | 134 | //弹窗点击 135 | [self alertViewTap]; 136 | 137 | //判断是否登陆成功 138 | XCTAssert(![self isLogin], @"退出登陆失败,快查查原因"); 139 | 140 | NSLog(@"---> 成功退出登陆"); 141 | }else{ 142 | NSLog(@"---> 本来就没有登陆"); 143 | } 144 | } 145 | ``` 146 | >**1.3 测试未登陆首页** 147 | >未登录首页测试,目前我写的Demo只是对首页的每个元素进行查找和简单的操作 148 | >如图 149 | >![home.gif](http://upload-images.jianshu.io/upload_images/1760826-528934e49b401326.gif?imageMogr2/auto-orient/strip) 150 | 151 | 152 | ``` 153 | - (void)testHome{ 154 | //判断是否登陆 155 | if([self isLogin]){ 156 | [self testLogOut];//退出登陆 157 | } 158 | //UISegmentedControl (可见文字) 159 | XCUIElement *segmentedButton = self.app.segmentedControls.buttons[@"Second"]; 160 | !segmentedButton.exists?:[segmentedButton tap]; 161 | 162 | segmentedButton = self.app.segmentedControls.buttons[@"First"]; 163 | !segmentedButton.exists?:[segmentedButton tap]; 164 | 165 | //UITabBarController 166 | XCUIElementQuery *tabBarsQuery = self.app.tabBars; 167 | XCUIElement *tableBarButton = tabBarsQuery.buttons[@"我的"]; 168 | !tableBarButton.exists?:[tableBarButton tap]; 169 | 170 | tableBarButton = self.app.buttons[@"取消"]; 171 | !tableBarButton.exists?:[tableBarButton tap]; 172 | 173 | //UISlider (通过标签) 174 | XCUIElement *slider1 = self.app.sliders[@"slider1"]; 175 | !slider1.exists?:[slider1 adjustToNormalizedSliderPosition:0]; 176 | !slider1.exists?:[slider1 adjustToNormalizedSliderPosition:1]; 177 | 178 | //UISwitch (通过标签) 179 | XCUIElement *switch1 = self.app.switches[@"switch1"]; 180 | !switch1.exists?:[switch1 tap]; 181 | !switch1.exists?:[switch1 tap]; 182 | 183 | //UIStepper (通过顺序) 184 | XCUIElement *stepper = [self.app.steppers elementAtIndex:0]; 185 | XCUIElement *incrementButton = stepper.buttons[@"Increment"]; 186 | [incrementButton tap]; 187 | [incrementButton tap]; 188 | [incrementButton tap]; 189 | 190 | XCUIElement *decrementButton = stepper.buttons[@"Decrement"]; 191 | [decrementButton tap]; 192 | [decrementButton tap]; 193 | [decrementButton tap]; 194 | 195 | //tableview (通过顺序) 196 | XCUIElement *tableview = [self.app.tables elementAtIndex:0]; 197 | [tableview swipeDown]; 198 | [tableview swipeUp]; 199 | [tableview swipeDown]; 200 | 201 | //cells 202 | XCUIElementQuery *cellQuery = tableview.cells; 203 | 204 | for (int i=0; i<5; i++) { 205 | //cell (通过顺序) 206 | [self cellTapAtIndex:i withCells:cellQuery]; 207 | //UIAlertView 208 | [self alertViewTap]; 209 | } 210 | } 211 | ``` 212 | 213 | >**1.4 登录测试(多账号)** 214 | >这里我们准备了多个账号,只有最后一个是对的,然后依次登录,如果全部登录失败就会进入断言 215 | >`XCTAssert((loginIndex准备一个账号数组 填入所有账号 217 | 218 | 219 | ``` 220 | - (NSArray *)accountArr{ 221 | if(!_accountArr.count){ 222 | _accountArr = @[ 223 | @{@"name":@"zhangsan", @"pwd":@"123456"},//账号1 224 | @{@"name":@"lisis", @"pwd":@"123456"},//账号2 225 | @{@"name":@"wangmazi", @"pwd":@"123456"},//账号3 226 | @{@"name":@"iss", @"pwd":@"123456"},//账号4 227 | ]; 228 | } 229 | return _accountArr; 230 | } 231 | ``` 232 | 效果图 233 | ![login.gif](http://upload-images.jianshu.io/upload_images/1760826-cc228fc3418b23f3.gif?imageMogr2/auto-orient/strip) 234 | 代码 235 | ``` 236 | - (void)testLogin{ 237 | if([self isLogin]){ 238 | NSLog(@"--> 测试登陆 已经是登陆状态"); 239 | return; 240 | } 241 | NSLog(@"---> 开始测试登陆"); 242 | //UITabBarController 243 | XCUIElementQuery *tabBarsQuery = self.app.tabBars; 244 | XCUIElement *tableBarButton = tabBarsQuery.buttons[@"我的"]; 245 | !tableBarButton.exists?:[tableBarButton tap]; 246 | 247 | XCTAssert((loginIndex 账号%@ 密码%@ 登陆失败", userName, pwd); 287 | //换个账号 重新登陆 288 | loginIndex ++; 289 | [self testLogin]; 290 | }else{//登陆成功 291 | 292 | NSLog(@"---> 账号%@ 密码%@ 登陆成功", userName, pwd); 293 | 294 | XCUIElement *tableBarButton = tabBarsQuery.buttons[@"我的"]; 295 | !tableBarButton.exists?:[tableBarButton tap]; 296 | 297 | tableBarButton = tabBarsQuery.buttons[@"首页"]; 298 | !tableBarButton.exists?:[tableBarButton tap]; 299 | 300 | NSLog(@"---> 登陆测试完成"); 301 | } 302 | } 303 | ``` 304 | 305 | >**1.5 资讯页面测试** 306 | >测试之前必须是已登录状态,才可以顺利进入'资讯'页面,所以得先判断是否登录,如果没有登录的话 必须先登录 307 | > 308 | ![info.gif](http://upload-images.jianshu.io/upload_images/1760826-1651cc4cae69d6f0.gif?imageMogr2/auto-orient/strip) 309 | 310 | 311 | ``` 312 | - (void)testInformation{ 313 | NSInteger loginCount = 0; 314 | if([self isLogin]){//已经登陆 315 | NSLog(@"---> 开始测试资讯页面"); 316 | XCUIElement *information = self.app.tabBars.buttons[@"资讯"]; 317 | !information.exists?:[information tap]; 318 | //点击 319 | XCUIElement *button = self.app.buttons[@"标签2"]; 320 | [button tap]; 321 | button = self.app.buttons[@"标签3"]; 322 | [button tap]; 323 | button = self.app.buttons[@"标签4"]; 324 | [button tap]; 325 | button = self.app.buttons[@"标签5"]; 326 | [button tap]; 327 | button = self.app.buttons[@"标签6"]; 328 | [button tap]; 329 | button = self.app.buttons[@"标签1"]; 330 | [button tap]; 331 | //滑动 332 | XCUIElement *swipeView = [self.app.scrollViews elementAtIndex:0]; 333 | [swipeView swipeRight]; 334 | [swipeView swipeLeft]; 335 | [swipeView swipeLeft]; 336 | [swipeView swipeLeft]; 337 | [swipeView swipeLeft]; 338 | [swipeView swipeLeft]; 339 | [swipeView swipeLeft]; 340 | 341 | NSLog(@"---> 资讯页面测试完成"); 342 | }else{//未登陆 343 | XCTAssert((loginCount 在资讯页面发现未登录 开始第 %@ 次登陆", @(loginCount)); 345 | loginCount ++; 346 | //发起登陆 347 | [self testLogin]; 348 | //继续测试资讯 349 | [self testInformation]; 350 | } 351 | } 352 | ``` 353 | 354 | ###参考 355 | [iOS UITests(自动化测试)常用类参考文档](http://www.jianshu.com/p/3b43e56c0a13) 356 | [iOS 官方文档](https://developer.apple.com/reference/xctest/xcuiapplication?language=objc) 357 | [本文Demo地址](https://github.com/ywdonga/iOSUITestsDemo) 358 | 359 | 360 | 361 | -------------------------------------------------------------------------------- /iOSUITests.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 589A85381E79135100AB3A53 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 589A85371E79135100AB3A53 /* main.m */; }; 11 | 589A853B1E79135100AB3A53 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 589A853A1E79135100AB3A53 /* AppDelegate.m */; }; 12 | 589A85411E79135100AB3A53 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 589A853F1E79135100AB3A53 /* Main.storyboard */; }; 13 | 589A85431E79135100AB3A53 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 589A85421E79135100AB3A53 /* Assets.xcassets */; }; 14 | 589A85461E79135100AB3A53 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 589A85441E79135100AB3A53 /* LaunchScreen.storyboard */; }; 15 | 589A85511E79135100AB3A53 /* iOSUITestsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 589A85501E79135100AB3A53 /* iOSUITestsTests.m */; }; 16 | 589A855C1E79135100AB3A53 /* iOSUITestsUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 589A855B1E79135100AB3A53 /* iOSUITestsUITests.m */; }; 17 | 589A856B1E79156500AB3A53 /* TabBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = 589A856A1E79156500AB3A53 /* TabBarController.m */; }; 18 | 589A856E1E79158100AB3A53 /* LoginViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 589A856D1E79158100AB3A53 /* LoginViewController.m */; }; 19 | 589A85711E79159A00AB3A53 /* HomeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 589A85701E79159A00AB3A53 /* HomeViewController.m */; }; 20 | 589A85741E7915BE00AB3A53 /* MineViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 589A85731E7915BE00AB3A53 /* MineViewController.m */; }; 21 | 589A85771E7915DB00AB3A53 /* InformationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 589A85761E7915DB00AB3A53 /* InformationViewController.m */; }; 22 | 589A85801E791DA900AB3A53 /* LoginManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 589A857F1E791DA900AB3A53 /* LoginManager.m */; }; 23 | 589A85831E7928B200AB3A53 /* HomeTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 589A85821E7928B200AB3A53 /* HomeTableView.m */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXContainerItemProxy section */ 27 | 589A854D1E79135100AB3A53 /* PBXContainerItemProxy */ = { 28 | isa = PBXContainerItemProxy; 29 | containerPortal = 589A852B1E79135100AB3A53 /* Project object */; 30 | proxyType = 1; 31 | remoteGlobalIDString = 589A85321E79135100AB3A53; 32 | remoteInfo = iOSUITests; 33 | }; 34 | 589A85581E79135100AB3A53 /* PBXContainerItemProxy */ = { 35 | isa = PBXContainerItemProxy; 36 | containerPortal = 589A852B1E79135100AB3A53 /* Project object */; 37 | proxyType = 1; 38 | remoteGlobalIDString = 589A85321E79135100AB3A53; 39 | remoteInfo = iOSUITests; 40 | }; 41 | /* End PBXContainerItemProxy section */ 42 | 43 | /* Begin PBXFileReference section */ 44 | 589A85331E79135100AB3A53 /* iOSUITests.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iOSUITests.app; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 589A85371E79135100AB3A53 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 46 | 589A85391E79135100AB3A53 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 47 | 589A853A1E79135100AB3A53 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 48 | 589A85401E79135100AB3A53 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 49 | 589A85421E79135100AB3A53 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 50 | 589A85451E79135100AB3A53 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 51 | 589A85471E79135100AB3A53 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 52 | 589A854C1E79135100AB3A53 /* iOSUITestsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = iOSUITestsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 589A85501E79135100AB3A53 /* iOSUITestsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = iOSUITestsTests.m; sourceTree = ""; }; 54 | 589A85521E79135100AB3A53 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 55 | 589A85571E79135100AB3A53 /* iOSUITestsUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = iOSUITestsUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | 589A855B1E79135100AB3A53 /* iOSUITestsUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = iOSUITestsUITests.m; sourceTree = ""; }; 57 | 589A855D1E79135100AB3A53 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 58 | 589A85691E79156500AB3A53 /* TabBarController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TabBarController.h; sourceTree = ""; }; 59 | 589A856A1E79156500AB3A53 /* TabBarController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TabBarController.m; sourceTree = ""; }; 60 | 589A856C1E79158100AB3A53 /* LoginViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoginViewController.h; sourceTree = ""; }; 61 | 589A856D1E79158100AB3A53 /* LoginViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LoginViewController.m; sourceTree = ""; }; 62 | 589A856F1E79159A00AB3A53 /* HomeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HomeViewController.h; sourceTree = ""; }; 63 | 589A85701E79159A00AB3A53 /* HomeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HomeViewController.m; sourceTree = ""; }; 64 | 589A85721E7915BE00AB3A53 /* MineViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MineViewController.h; sourceTree = ""; }; 65 | 589A85731E7915BE00AB3A53 /* MineViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MineViewController.m; sourceTree = ""; }; 66 | 589A85751E7915DB00AB3A53 /* InformationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InformationViewController.h; sourceTree = ""; }; 67 | 589A85761E7915DB00AB3A53 /* InformationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InformationViewController.m; sourceTree = ""; }; 68 | 589A857E1E791DA900AB3A53 /* LoginManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoginManager.h; sourceTree = ""; }; 69 | 589A857F1E791DA900AB3A53 /* LoginManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LoginManager.m; sourceTree = ""; }; 70 | 589A85811E7928B200AB3A53 /* HomeTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HomeTableView.h; sourceTree = ""; }; 71 | 589A85821E7928B200AB3A53 /* HomeTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HomeTableView.m; sourceTree = ""; }; 72 | /* End PBXFileReference section */ 73 | 74 | /* Begin PBXFrameworksBuildPhase section */ 75 | 589A85301E79135100AB3A53 /* Frameworks */ = { 76 | isa = PBXFrameworksBuildPhase; 77 | buildActionMask = 2147483647; 78 | files = ( 79 | ); 80 | runOnlyForDeploymentPostprocessing = 0; 81 | }; 82 | 589A85491E79135100AB3A53 /* Frameworks */ = { 83 | isa = PBXFrameworksBuildPhase; 84 | buildActionMask = 2147483647; 85 | files = ( 86 | ); 87 | runOnlyForDeploymentPostprocessing = 0; 88 | }; 89 | 589A85541E79135100AB3A53 /* Frameworks */ = { 90 | isa = PBXFrameworksBuildPhase; 91 | buildActionMask = 2147483647; 92 | files = ( 93 | ); 94 | runOnlyForDeploymentPostprocessing = 0; 95 | }; 96 | /* End PBXFrameworksBuildPhase section */ 97 | 98 | /* Begin PBXGroup section */ 99 | 589A852A1E79135100AB3A53 = { 100 | isa = PBXGroup; 101 | children = ( 102 | 589A85351E79135100AB3A53 /* iOSUITests */, 103 | 589A854F1E79135100AB3A53 /* iOSUITestsTests */, 104 | 589A855A1E79135100AB3A53 /* iOSUITestsUITests */, 105 | 589A85341E79135100AB3A53 /* Products */, 106 | ); 107 | sourceTree = ""; 108 | }; 109 | 589A85341E79135100AB3A53 /* Products */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | 589A85331E79135100AB3A53 /* iOSUITests.app */, 113 | 589A854C1E79135100AB3A53 /* iOSUITestsTests.xctest */, 114 | 589A85571E79135100AB3A53 /* iOSUITestsUITests.xctest */, 115 | ); 116 | name = Products; 117 | sourceTree = ""; 118 | }; 119 | 589A85351E79135100AB3A53 /* iOSUITests */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | 589A85391E79135100AB3A53 /* AppDelegate.h */, 123 | 589A853A1E79135100AB3A53 /* AppDelegate.m */, 124 | 589A857D1E791D9500AB3A53 /* Manager */, 125 | 589A85781E79168B00AB3A53 /* Root */, 126 | 589A857A1E7916A200AB3A53 /* Login */, 127 | 589A85791E79169900AB3A53 /* Home */, 128 | 589A857C1E7916CA00AB3A53 /* Information */, 129 | 589A857B1E7916AC00AB3A53 /* Mine */, 130 | 589A853F1E79135100AB3A53 /* Main.storyboard */, 131 | 589A85361E79135100AB3A53 /* Supporting Files */, 132 | ); 133 | path = iOSUITests; 134 | sourceTree = ""; 135 | }; 136 | 589A85361E79135100AB3A53 /* Supporting Files */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | 589A85421E79135100AB3A53 /* Assets.xcassets */, 140 | 589A85441E79135100AB3A53 /* LaunchScreen.storyboard */, 141 | 589A85471E79135100AB3A53 /* Info.plist */, 142 | 589A85371E79135100AB3A53 /* main.m */, 143 | ); 144 | name = "Supporting Files"; 145 | sourceTree = ""; 146 | }; 147 | 589A854F1E79135100AB3A53 /* iOSUITestsTests */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | 589A85501E79135100AB3A53 /* iOSUITestsTests.m */, 151 | 589A85521E79135100AB3A53 /* Info.plist */, 152 | ); 153 | path = iOSUITestsTests; 154 | sourceTree = ""; 155 | }; 156 | 589A855A1E79135100AB3A53 /* iOSUITestsUITests */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | 589A855B1E79135100AB3A53 /* iOSUITestsUITests.m */, 160 | 589A855D1E79135100AB3A53 /* Info.plist */, 161 | ); 162 | path = iOSUITestsUITests; 163 | sourceTree = ""; 164 | }; 165 | 589A85781E79168B00AB3A53 /* Root */ = { 166 | isa = PBXGroup; 167 | children = ( 168 | 589A85691E79156500AB3A53 /* TabBarController.h */, 169 | 589A856A1E79156500AB3A53 /* TabBarController.m */, 170 | ); 171 | name = Root; 172 | sourceTree = ""; 173 | }; 174 | 589A85791E79169900AB3A53 /* Home */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | 589A856F1E79159A00AB3A53 /* HomeViewController.h */, 178 | 589A85701E79159A00AB3A53 /* HomeViewController.m */, 179 | 589A85811E7928B200AB3A53 /* HomeTableView.h */, 180 | 589A85821E7928B200AB3A53 /* HomeTableView.m */, 181 | ); 182 | name = Home; 183 | sourceTree = ""; 184 | }; 185 | 589A857A1E7916A200AB3A53 /* Login */ = { 186 | isa = PBXGroup; 187 | children = ( 188 | 589A856C1E79158100AB3A53 /* LoginViewController.h */, 189 | 589A856D1E79158100AB3A53 /* LoginViewController.m */, 190 | ); 191 | name = Login; 192 | sourceTree = ""; 193 | }; 194 | 589A857B1E7916AC00AB3A53 /* Mine */ = { 195 | isa = PBXGroup; 196 | children = ( 197 | 589A85721E7915BE00AB3A53 /* MineViewController.h */, 198 | 589A85731E7915BE00AB3A53 /* MineViewController.m */, 199 | ); 200 | name = Mine; 201 | sourceTree = ""; 202 | }; 203 | 589A857C1E7916CA00AB3A53 /* Information */ = { 204 | isa = PBXGroup; 205 | children = ( 206 | 589A85751E7915DB00AB3A53 /* InformationViewController.h */, 207 | 589A85761E7915DB00AB3A53 /* InformationViewController.m */, 208 | ); 209 | name = Information; 210 | sourceTree = ""; 211 | }; 212 | 589A857D1E791D9500AB3A53 /* Manager */ = { 213 | isa = PBXGroup; 214 | children = ( 215 | 589A857E1E791DA900AB3A53 /* LoginManager.h */, 216 | 589A857F1E791DA900AB3A53 /* LoginManager.m */, 217 | ); 218 | name = Manager; 219 | sourceTree = ""; 220 | }; 221 | /* End PBXGroup section */ 222 | 223 | /* Begin PBXNativeTarget section */ 224 | 589A85321E79135100AB3A53 /* iOSUITests */ = { 225 | isa = PBXNativeTarget; 226 | buildConfigurationList = 589A85601E79135100AB3A53 /* Build configuration list for PBXNativeTarget "iOSUITests" */; 227 | buildPhases = ( 228 | 589A852F1E79135100AB3A53 /* Sources */, 229 | 589A85301E79135100AB3A53 /* Frameworks */, 230 | 589A85311E79135100AB3A53 /* Resources */, 231 | ); 232 | buildRules = ( 233 | ); 234 | dependencies = ( 235 | ); 236 | name = iOSUITests; 237 | productName = iOSUITests; 238 | productReference = 589A85331E79135100AB3A53 /* iOSUITests.app */; 239 | productType = "com.apple.product-type.application"; 240 | }; 241 | 589A854B1E79135100AB3A53 /* iOSUITestsTests */ = { 242 | isa = PBXNativeTarget; 243 | buildConfigurationList = 589A85631E79135100AB3A53 /* Build configuration list for PBXNativeTarget "iOSUITestsTests" */; 244 | buildPhases = ( 245 | 589A85481E79135100AB3A53 /* Sources */, 246 | 589A85491E79135100AB3A53 /* Frameworks */, 247 | 589A854A1E79135100AB3A53 /* Resources */, 248 | ); 249 | buildRules = ( 250 | ); 251 | dependencies = ( 252 | 589A854E1E79135100AB3A53 /* PBXTargetDependency */, 253 | ); 254 | name = iOSUITestsTests; 255 | productName = iOSUITestsTests; 256 | productReference = 589A854C1E79135100AB3A53 /* iOSUITestsTests.xctest */; 257 | productType = "com.apple.product-type.bundle.unit-test"; 258 | }; 259 | 589A85561E79135100AB3A53 /* iOSUITestsUITests */ = { 260 | isa = PBXNativeTarget; 261 | buildConfigurationList = 589A85661E79135100AB3A53 /* Build configuration list for PBXNativeTarget "iOSUITestsUITests" */; 262 | buildPhases = ( 263 | 589A85531E79135100AB3A53 /* Sources */, 264 | 589A85541E79135100AB3A53 /* Frameworks */, 265 | 589A85551E79135100AB3A53 /* Resources */, 266 | ); 267 | buildRules = ( 268 | ); 269 | dependencies = ( 270 | 589A85591E79135100AB3A53 /* PBXTargetDependency */, 271 | ); 272 | name = iOSUITestsUITests; 273 | productName = iOSUITestsUITests; 274 | productReference = 589A85571E79135100AB3A53 /* iOSUITestsUITests.xctest */; 275 | productType = "com.apple.product-type.bundle.ui-testing"; 276 | }; 277 | /* End PBXNativeTarget section */ 278 | 279 | /* Begin PBXProject section */ 280 | 589A852B1E79135100AB3A53 /* Project object */ = { 281 | isa = PBXProject; 282 | attributes = { 283 | LastUpgradeCheck = 0820; 284 | ORGANIZATIONNAME = dyw; 285 | TargetAttributes = { 286 | 589A85321E79135100AB3A53 = { 287 | CreatedOnToolsVersion = 8.2.1; 288 | DevelopmentTeam = T5PFJRPNYQ; 289 | ProvisioningStyle = Automatic; 290 | }; 291 | 589A854B1E79135100AB3A53 = { 292 | CreatedOnToolsVersion = 8.2.1; 293 | DevelopmentTeam = T5PFJRPNYQ; 294 | ProvisioningStyle = Automatic; 295 | TestTargetID = 589A85321E79135100AB3A53; 296 | }; 297 | 589A85561E79135100AB3A53 = { 298 | CreatedOnToolsVersion = 8.2.1; 299 | DevelopmentTeam = T5PFJRPNYQ; 300 | ProvisioningStyle = Automatic; 301 | TestTargetID = 589A85321E79135100AB3A53; 302 | }; 303 | }; 304 | }; 305 | buildConfigurationList = 589A852E1E79135100AB3A53 /* Build configuration list for PBXProject "iOSUITests" */; 306 | compatibilityVersion = "Xcode 3.2"; 307 | developmentRegion = English; 308 | hasScannedForEncodings = 0; 309 | knownRegions = ( 310 | en, 311 | Base, 312 | ); 313 | mainGroup = 589A852A1E79135100AB3A53; 314 | productRefGroup = 589A85341E79135100AB3A53 /* Products */; 315 | projectDirPath = ""; 316 | projectRoot = ""; 317 | targets = ( 318 | 589A85321E79135100AB3A53 /* iOSUITests */, 319 | 589A854B1E79135100AB3A53 /* iOSUITestsTests */, 320 | 589A85561E79135100AB3A53 /* iOSUITestsUITests */, 321 | ); 322 | }; 323 | /* End PBXProject section */ 324 | 325 | /* Begin PBXResourcesBuildPhase section */ 326 | 589A85311E79135100AB3A53 /* Resources */ = { 327 | isa = PBXResourcesBuildPhase; 328 | buildActionMask = 2147483647; 329 | files = ( 330 | 589A85461E79135100AB3A53 /* LaunchScreen.storyboard in Resources */, 331 | 589A85431E79135100AB3A53 /* Assets.xcassets in Resources */, 332 | 589A85411E79135100AB3A53 /* Main.storyboard in Resources */, 333 | ); 334 | runOnlyForDeploymentPostprocessing = 0; 335 | }; 336 | 589A854A1E79135100AB3A53 /* Resources */ = { 337 | isa = PBXResourcesBuildPhase; 338 | buildActionMask = 2147483647; 339 | files = ( 340 | ); 341 | runOnlyForDeploymentPostprocessing = 0; 342 | }; 343 | 589A85551E79135100AB3A53 /* Resources */ = { 344 | isa = PBXResourcesBuildPhase; 345 | buildActionMask = 2147483647; 346 | files = ( 347 | ); 348 | runOnlyForDeploymentPostprocessing = 0; 349 | }; 350 | /* End PBXResourcesBuildPhase section */ 351 | 352 | /* Begin PBXSourcesBuildPhase section */ 353 | 589A852F1E79135100AB3A53 /* Sources */ = { 354 | isa = PBXSourcesBuildPhase; 355 | buildActionMask = 2147483647; 356 | files = ( 357 | 589A856E1E79158100AB3A53 /* LoginViewController.m in Sources */, 358 | 589A856B1E79156500AB3A53 /* TabBarController.m in Sources */, 359 | 589A85831E7928B200AB3A53 /* HomeTableView.m in Sources */, 360 | 589A853B1E79135100AB3A53 /* AppDelegate.m in Sources */, 361 | 589A85741E7915BE00AB3A53 /* MineViewController.m in Sources */, 362 | 589A85711E79159A00AB3A53 /* HomeViewController.m in Sources */, 363 | 589A85801E791DA900AB3A53 /* LoginManager.m in Sources */, 364 | 589A85771E7915DB00AB3A53 /* InformationViewController.m in Sources */, 365 | 589A85381E79135100AB3A53 /* main.m in Sources */, 366 | ); 367 | runOnlyForDeploymentPostprocessing = 0; 368 | }; 369 | 589A85481E79135100AB3A53 /* Sources */ = { 370 | isa = PBXSourcesBuildPhase; 371 | buildActionMask = 2147483647; 372 | files = ( 373 | 589A85511E79135100AB3A53 /* iOSUITestsTests.m in Sources */, 374 | ); 375 | runOnlyForDeploymentPostprocessing = 0; 376 | }; 377 | 589A85531E79135100AB3A53 /* Sources */ = { 378 | isa = PBXSourcesBuildPhase; 379 | buildActionMask = 2147483647; 380 | files = ( 381 | 589A855C1E79135100AB3A53 /* iOSUITestsUITests.m in Sources */, 382 | ); 383 | runOnlyForDeploymentPostprocessing = 0; 384 | }; 385 | /* End PBXSourcesBuildPhase section */ 386 | 387 | /* Begin PBXTargetDependency section */ 388 | 589A854E1E79135100AB3A53 /* PBXTargetDependency */ = { 389 | isa = PBXTargetDependency; 390 | target = 589A85321E79135100AB3A53 /* iOSUITests */; 391 | targetProxy = 589A854D1E79135100AB3A53 /* PBXContainerItemProxy */; 392 | }; 393 | 589A85591E79135100AB3A53 /* PBXTargetDependency */ = { 394 | isa = PBXTargetDependency; 395 | target = 589A85321E79135100AB3A53 /* iOSUITests */; 396 | targetProxy = 589A85581E79135100AB3A53 /* PBXContainerItemProxy */; 397 | }; 398 | /* End PBXTargetDependency section */ 399 | 400 | /* Begin PBXVariantGroup section */ 401 | 589A853F1E79135100AB3A53 /* Main.storyboard */ = { 402 | isa = PBXVariantGroup; 403 | children = ( 404 | 589A85401E79135100AB3A53 /* Base */, 405 | ); 406 | name = Main.storyboard; 407 | sourceTree = ""; 408 | }; 409 | 589A85441E79135100AB3A53 /* LaunchScreen.storyboard */ = { 410 | isa = PBXVariantGroup; 411 | children = ( 412 | 589A85451E79135100AB3A53 /* Base */, 413 | ); 414 | name = LaunchScreen.storyboard; 415 | sourceTree = ""; 416 | }; 417 | /* End PBXVariantGroup section */ 418 | 419 | /* Begin XCBuildConfiguration section */ 420 | 589A855E1E79135100AB3A53 /* Debug */ = { 421 | isa = XCBuildConfiguration; 422 | buildSettings = { 423 | ALWAYS_SEARCH_USER_PATHS = NO; 424 | CLANG_ANALYZER_NONNULL = YES; 425 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 426 | CLANG_CXX_LIBRARY = "libc++"; 427 | CLANG_ENABLE_MODULES = YES; 428 | CLANG_ENABLE_OBJC_ARC = YES; 429 | CLANG_WARN_BOOL_CONVERSION = YES; 430 | CLANG_WARN_CONSTANT_CONVERSION = YES; 431 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 432 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 433 | CLANG_WARN_EMPTY_BODY = YES; 434 | CLANG_WARN_ENUM_CONVERSION = YES; 435 | CLANG_WARN_INFINITE_RECURSION = YES; 436 | CLANG_WARN_INT_CONVERSION = YES; 437 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 438 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 439 | CLANG_WARN_UNREACHABLE_CODE = YES; 440 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 441 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 442 | COPY_PHASE_STRIP = NO; 443 | DEBUG_INFORMATION_FORMAT = dwarf; 444 | ENABLE_STRICT_OBJC_MSGSEND = YES; 445 | ENABLE_TESTABILITY = YES; 446 | GCC_C_LANGUAGE_STANDARD = gnu99; 447 | GCC_DYNAMIC_NO_PIC = NO; 448 | GCC_NO_COMMON_BLOCKS = YES; 449 | GCC_OPTIMIZATION_LEVEL = 0; 450 | GCC_PREPROCESSOR_DEFINITIONS = ( 451 | "DEBUG=1", 452 | "$(inherited)", 453 | ); 454 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 455 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 456 | GCC_WARN_UNDECLARED_SELECTOR = YES; 457 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 458 | GCC_WARN_UNUSED_FUNCTION = YES; 459 | GCC_WARN_UNUSED_VARIABLE = YES; 460 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 461 | MTL_ENABLE_DEBUG_INFO = YES; 462 | ONLY_ACTIVE_ARCH = YES; 463 | SDKROOT = iphoneos; 464 | TARGETED_DEVICE_FAMILY = "1,2"; 465 | }; 466 | name = Debug; 467 | }; 468 | 589A855F1E79135100AB3A53 /* Release */ = { 469 | isa = XCBuildConfiguration; 470 | buildSettings = { 471 | ALWAYS_SEARCH_USER_PATHS = NO; 472 | CLANG_ANALYZER_NONNULL = YES; 473 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 474 | CLANG_CXX_LIBRARY = "libc++"; 475 | CLANG_ENABLE_MODULES = YES; 476 | CLANG_ENABLE_OBJC_ARC = YES; 477 | CLANG_WARN_BOOL_CONVERSION = YES; 478 | CLANG_WARN_CONSTANT_CONVERSION = YES; 479 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 480 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 481 | CLANG_WARN_EMPTY_BODY = YES; 482 | CLANG_WARN_ENUM_CONVERSION = YES; 483 | CLANG_WARN_INFINITE_RECURSION = YES; 484 | CLANG_WARN_INT_CONVERSION = YES; 485 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 486 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 487 | CLANG_WARN_UNREACHABLE_CODE = YES; 488 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 489 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 490 | COPY_PHASE_STRIP = NO; 491 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 492 | ENABLE_NS_ASSERTIONS = NO; 493 | ENABLE_STRICT_OBJC_MSGSEND = YES; 494 | GCC_C_LANGUAGE_STANDARD = gnu99; 495 | GCC_NO_COMMON_BLOCKS = YES; 496 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 497 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 498 | GCC_WARN_UNDECLARED_SELECTOR = YES; 499 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 500 | GCC_WARN_UNUSED_FUNCTION = YES; 501 | GCC_WARN_UNUSED_VARIABLE = YES; 502 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 503 | MTL_ENABLE_DEBUG_INFO = NO; 504 | SDKROOT = iphoneos; 505 | TARGETED_DEVICE_FAMILY = "1,2"; 506 | VALIDATE_PRODUCT = YES; 507 | }; 508 | name = Release; 509 | }; 510 | 589A85611E79135100AB3A53 /* Debug */ = { 511 | isa = XCBuildConfiguration; 512 | buildSettings = { 513 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 514 | DEVELOPMENT_TEAM = T5PFJRPNYQ; 515 | INFOPLIST_FILE = iOSUITests/Info.plist; 516 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 517 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 518 | PRODUCT_BUNDLE_IDENTIFIER = com.iss.iOSUITests; 519 | PRODUCT_NAME = "$(TARGET_NAME)"; 520 | }; 521 | name = Debug; 522 | }; 523 | 589A85621E79135100AB3A53 /* Release */ = { 524 | isa = XCBuildConfiguration; 525 | buildSettings = { 526 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 527 | DEVELOPMENT_TEAM = T5PFJRPNYQ; 528 | INFOPLIST_FILE = iOSUITests/Info.plist; 529 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 530 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 531 | PRODUCT_BUNDLE_IDENTIFIER = com.iss.iOSUITests; 532 | PRODUCT_NAME = "$(TARGET_NAME)"; 533 | }; 534 | name = Release; 535 | }; 536 | 589A85641E79135100AB3A53 /* Debug */ = { 537 | isa = XCBuildConfiguration; 538 | buildSettings = { 539 | BUNDLE_LOADER = "$(TEST_HOST)"; 540 | DEVELOPMENT_TEAM = T5PFJRPNYQ; 541 | INFOPLIST_FILE = iOSUITestsTests/Info.plist; 542 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 543 | PRODUCT_BUNDLE_IDENTIFIER = com.iss.iOSUITestsTests; 544 | PRODUCT_NAME = "$(TARGET_NAME)"; 545 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/iOSUITests.app/iOSUITests"; 546 | }; 547 | name = Debug; 548 | }; 549 | 589A85651E79135100AB3A53 /* Release */ = { 550 | isa = XCBuildConfiguration; 551 | buildSettings = { 552 | BUNDLE_LOADER = "$(TEST_HOST)"; 553 | DEVELOPMENT_TEAM = T5PFJRPNYQ; 554 | INFOPLIST_FILE = iOSUITestsTests/Info.plist; 555 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 556 | PRODUCT_BUNDLE_IDENTIFIER = com.iss.iOSUITestsTests; 557 | PRODUCT_NAME = "$(TARGET_NAME)"; 558 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/iOSUITests.app/iOSUITests"; 559 | }; 560 | name = Release; 561 | }; 562 | 589A85671E79135100AB3A53 /* Debug */ = { 563 | isa = XCBuildConfiguration; 564 | buildSettings = { 565 | DEVELOPMENT_TEAM = T5PFJRPNYQ; 566 | INFOPLIST_FILE = iOSUITestsUITests/Info.plist; 567 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 568 | PRODUCT_BUNDLE_IDENTIFIER = com.iss.iOSUITestsUITests; 569 | PRODUCT_NAME = "$(TARGET_NAME)"; 570 | TEST_TARGET_NAME = iOSUITests; 571 | }; 572 | name = Debug; 573 | }; 574 | 589A85681E79135100AB3A53 /* Release */ = { 575 | isa = XCBuildConfiguration; 576 | buildSettings = { 577 | DEVELOPMENT_TEAM = T5PFJRPNYQ; 578 | INFOPLIST_FILE = iOSUITestsUITests/Info.plist; 579 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 580 | PRODUCT_BUNDLE_IDENTIFIER = com.iss.iOSUITestsUITests; 581 | PRODUCT_NAME = "$(TARGET_NAME)"; 582 | TEST_TARGET_NAME = iOSUITests; 583 | }; 584 | name = Release; 585 | }; 586 | /* End XCBuildConfiguration section */ 587 | 588 | /* Begin XCConfigurationList section */ 589 | 589A852E1E79135100AB3A53 /* Build configuration list for PBXProject "iOSUITests" */ = { 590 | isa = XCConfigurationList; 591 | buildConfigurations = ( 592 | 589A855E1E79135100AB3A53 /* Debug */, 593 | 589A855F1E79135100AB3A53 /* Release */, 594 | ); 595 | defaultConfigurationIsVisible = 0; 596 | defaultConfigurationName = Release; 597 | }; 598 | 589A85601E79135100AB3A53 /* Build configuration list for PBXNativeTarget "iOSUITests" */ = { 599 | isa = XCConfigurationList; 600 | buildConfigurations = ( 601 | 589A85611E79135100AB3A53 /* Debug */, 602 | 589A85621E79135100AB3A53 /* Release */, 603 | ); 604 | defaultConfigurationIsVisible = 0; 605 | defaultConfigurationName = Release; 606 | }; 607 | 589A85631E79135100AB3A53 /* Build configuration list for PBXNativeTarget "iOSUITestsTests" */ = { 608 | isa = XCConfigurationList; 609 | buildConfigurations = ( 610 | 589A85641E79135100AB3A53 /* Debug */, 611 | 589A85651E79135100AB3A53 /* Release */, 612 | ); 613 | defaultConfigurationIsVisible = 0; 614 | defaultConfigurationName = Release; 615 | }; 616 | 589A85661E79135100AB3A53 /* Build configuration list for PBXNativeTarget "iOSUITestsUITests" */ = { 617 | isa = XCConfigurationList; 618 | buildConfigurations = ( 619 | 589A85671E79135100AB3A53 /* Debug */, 620 | 589A85681E79135100AB3A53 /* Release */, 621 | ); 622 | defaultConfigurationIsVisible = 0; 623 | defaultConfigurationName = Release; 624 | }; 625 | /* End XCConfigurationList section */ 626 | }; 627 | rootObject = 589A852B1E79135100AB3A53 /* Project object */; 628 | } 629 | -------------------------------------------------------------------------------- /iOSUITests.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iOSUITests.xcodeproj/project.xcworkspace/xcuserdata/dyw.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ywdonga/iOSUITestsDemo/9f760966717479d0119e485aaecb09a4ffa1de19/iOSUITests.xcodeproj/project.xcworkspace/xcuserdata/dyw.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /iOSUITests.xcodeproj/xcuserdata/dyw.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /iOSUITests.xcodeproj/xcuserdata/dyw.xcuserdatad/xcschemes/iOSUITests.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 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /iOSUITests.xcodeproj/xcuserdata/dyw.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | iOSUITests.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 589A85321E79135100AB3A53 16 | 17 | primary 18 | 19 | 20 | 589A854B1E79135100AB3A53 21 | 22 | primary 23 | 24 | 25 | 589A85561E79135100AB3A53 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /iOSUITests/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // iOSUITests 4 | // 5 | // Created by dyw on 2017/3/15. 6 | // Copyright © 2017年 dyw. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /iOSUITests/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // iOSUITests 4 | // 5 | // Created by dyw on 2017/3/15. 6 | // Copyright © 2017年 dyw. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // 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. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // 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. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // 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. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 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 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /iOSUITests/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 | } -------------------------------------------------------------------------------- /iOSUITests/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 | -------------------------------------------------------------------------------- /iOSUITests/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 | 41 | 54 | 67 | 80 | 93 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 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 | 323 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 357 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 391 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 425 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 459 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 497 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 531 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 565 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 599 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 633 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 667 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 701 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 810 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | 905 | 906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | 936 | 937 | 938 | 939 | 940 | 941 | 942 | 943 | 944 | 945 | 946 | 947 | 948 | 949 | 950 | 951 | 952 | 953 | 954 | 955 | 956 | 957 | 958 | 959 | 960 | 961 | 962 | 963 | 964 | 965 | 966 | 967 | 968 | 969 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 | 982 | 983 | 984 | 995 | 1003 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | 1028 | 1029 | 1030 | 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | 1037 | 1038 | 1039 | 1040 | 1041 | 1042 | 1043 | 1044 | 1045 | 1046 | 1047 | 1048 | 1049 | 1050 | 1051 | 1052 | 1053 | 1054 | 1055 | 1056 | 1057 | 1058 | 1059 | 1060 | 1061 | 1062 | 1063 | 1064 | 1065 | 1066 | 1067 | 1068 | 1069 | 1070 | 1071 | 1072 | 1073 | 1074 | 1075 | 1076 | 1077 | 1078 | 1079 | 1080 | 1081 | 1082 | 1083 | 1084 | 1085 | 1086 | 1087 | 1088 | 1089 | 1090 | 1091 | 1092 | 1093 | 1094 | 1095 | 1096 | 1097 | 1098 | 1099 | 1100 | 1101 | 1102 | 1103 | 1104 | 1105 | 1106 | 1107 | 1108 | 1109 | 1110 | 1111 | 1112 | 1113 | 1114 | 1115 | 1116 | 1117 | 1118 | 1119 | 1120 | -------------------------------------------------------------------------------- /iOSUITests/HomeTableView.h: -------------------------------------------------------------------------------- 1 | // 2 | // HomeTableView.h 3 | // iOSUITests 4 | // 5 | // Created by dyw on 2017/3/15. 6 | // Copyright © 2017年 dyw. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface HomeTableView : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /iOSUITests/HomeTableView.m: -------------------------------------------------------------------------------- 1 | // 2 | // HomeTableView.m 3 | // iOSUITests 4 | // 5 | // Created by dyw on 2017/3/15. 6 | // Copyright © 2017年 dyw. All rights reserved. 7 | // 8 | 9 | #import "HomeTableView.h" 10 | 11 | @interface HomeTableView () 12 | 13 | @end 14 | 15 | @implementation HomeTableView 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | 20 | // Uncomment the following line to preserve selection between presentations. 21 | // self.clearsSelectionOnViewWillAppear = NO; 22 | 23 | // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 24 | // self.navigationItem.rightBarButtonItem = self.editButtonItem; 25 | } 26 | 27 | - (void)didReceiveMemoryWarning { 28 | [super didReceiveMemoryWarning]; 29 | // Dispose of any resources that can be recreated. 30 | } 31 | 32 | #pragma mark - Table view data source 33 | 34 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 35 | return [super numberOfSectionsInTableView:tableView]; 36 | } 37 | 38 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 39 | return [super tableView:tableView numberOfRowsInSection:section]; 40 | } 41 | 42 | 43 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 44 | UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath]; 45 | cell.textLabel.text = [NSString stringWithFormat:@"我是第->%@ 行", @(indexPath.row)]; 46 | return cell; 47 | } 48 | 49 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 50 | UIAlertView *alt = [[UIAlertView alloc] initWithTitle:nil message:[NSString stringWithFormat:@"当前点击了第->%@ 行", @(indexPath.row)] delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil]; 51 | [alt show]; 52 | } 53 | 54 | 55 | /* 56 | // Override to support conditional editing of the table view. 57 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { 58 | // Return NO if you do not want the specified item to be editable. 59 | return YES; 60 | } 61 | */ 62 | 63 | /* 64 | // Override to support editing the table view. 65 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 66 | if (editingStyle == UITableViewCellEditingStyleDelete) { 67 | // Delete the row from the data source 68 | [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; 69 | } else if (editingStyle == UITableViewCellEditingStyleInsert) { 70 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 71 | } 72 | } 73 | */ 74 | 75 | /* 76 | // Override to support rearranging the table view. 77 | - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { 78 | } 79 | */ 80 | 81 | /* 82 | // Override to support conditional rearranging of the table view. 83 | - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { 84 | // Return NO if you do not want the item to be re-orderable. 85 | return YES; 86 | } 87 | */ 88 | 89 | /* 90 | #pragma mark - Navigation 91 | 92 | // In a storyboard-based application, you will often want to do a little preparation before navigation 93 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 94 | // Get the new view controller using [segue destinationViewController]. 95 | // Pass the selected object to the new view controller. 96 | } 97 | */ 98 | 99 | @end 100 | -------------------------------------------------------------------------------- /iOSUITests/HomeViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // HomeViewController.h 3 | // iOSUITests 4 | // 5 | // Created by dyw on 2017/3/15. 6 | // Copyright © 2017年 dyw. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface HomeViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /iOSUITests/HomeViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // HomeViewController.m 3 | // iOSUITests 4 | // 5 | // Created by dyw on 2017/3/15. 6 | // Copyright © 2017年 dyw. All rights reserved. 7 | // 8 | 9 | #import "HomeViewController.h" 10 | 11 | @interface HomeViewController () 12 | @property (weak, nonatomic) IBOutlet UILabel *secmentInfoLabel; 13 | @property (weak, nonatomic) IBOutlet UIActivityIndicatorView *a1; 14 | @property (weak, nonatomic) IBOutlet UIActivityIndicatorView *a2; 15 | @property (weak, nonatomic) IBOutlet UIProgressView *prView; 16 | 17 | @end 18 | 19 | @implementation HomeViewController 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | // Do any additional setup after loading the view. 24 | } 25 | 26 | - (void)didReceiveMemoryWarning { 27 | [super didReceiveMemoryWarning]; 28 | // Dispose of any resources that can be recreated. 29 | } 30 | 31 | /* 32 | #pragma mark - Navigation 33 | 34 | // In a storyboard-based application, you will often want to do a little preparation before navigation 35 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 36 | // Get the new view controller using [segue destinationViewController]. 37 | // Pass the selected object to the new view controller. 38 | } 39 | */ 40 | - (IBAction)segmentedValueChange:(UISegmentedControl *)sender { 41 | self.secmentInfoLabel.text = sender.selectedSegmentIndex?@"Segmented右边":@"Segmented左边"; 42 | } 43 | 44 | - (IBAction)swichValueChange:(UISwitch *)sender { 45 | sender.isOn?[self.a1 startAnimating]: [self.a1 stopAnimating]; 46 | sender.isOn?[self.a2 startAnimating]: [self.a2 stopAnimating]; 47 | } 48 | 49 | - (IBAction)stepperValueChange:(UIStepper *)sender { 50 | 51 | self.prView.progress = sender.value/10.0; 52 | } 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /iOSUITests/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 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /iOSUITests/InformationViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // InformationViewController.h 3 | // iOSUITests 4 | // 5 | // Created by dyw on 2017/3/15. 6 | // Copyright © 2017年 dyw. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface InformationViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /iOSUITests/InformationViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // InformationViewController.m 3 | // iOSUITests 4 | // 5 | // Created by dyw on 2017/3/15. 6 | // Copyright © 2017年 dyw. All rights reserved. 7 | // 8 | 9 | #import "InformationViewController.h" 10 | 11 | #define WW [UIScreen mainScreen].bounds.size.width 12 | 13 | @interface InformationViewController () 14 | 15 | @property (weak, nonatomic) IBOutlet UIView *buttonBackView; 16 | @property (weak, nonatomic) IBOutlet UIScrollView *scrollView; 17 | 18 | 19 | @end 20 | 21 | @implementation InformationViewController 22 | 23 | - (void)viewDidLoad { 24 | [super viewDidLoad]; 25 | // Do any additional setup after loading the view. 26 | 27 | } 28 | 29 | - (void)didReceiveMemoryWarning { 30 | [super didReceiveMemoryWarning]; 31 | // Dispose of any resources that can be recreated. 32 | } 33 | 34 | /* 35 | #pragma mark - Navigation 36 | 37 | // In a storyboard-based application, you will often want to do a little preparation before navigation 38 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 39 | // Get the new view controller using [segue destinationViewController]. 40 | // Pass the selected object to the new view controller. 41 | } 42 | */ 43 | #pragma mark - UIScrollView Delegate 44 | //减速停止了时执行,手触摸时执行执行 45 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{ 46 | CGFloat offSetX = scrollView.contentOffset.x; 47 | NSInteger page = offSetX/WW + 1; 48 | for (UIButton *btn in self.buttonBackView.subviews) { 49 | btn.selected = (btn.tag == page); 50 | } 51 | } 52 | 53 | 54 | - (IBAction)buttonClick:(UIButton *)sender { 55 | for (UIButton *btn in self.buttonBackView.subviews) { 56 | btn.selected = NO; 57 | } 58 | sender.selected = YES; 59 | [self.scrollView setContentOffset:CGPointMake((sender.tag-1)*WW, 0) animated:YES]; 60 | } 61 | 62 | 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /iOSUITests/LoginManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // LoginManager.h 3 | // iOSUITests 4 | // 5 | // Created by dyw on 2017/3/15. 6 | // Copyright © 2017年 dyw. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface LoginManager : NSObject 13 | 14 | + (void)setLogin:(BOOL)isLogin; 15 | + (BOOL)getLogin; 16 | 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /iOSUITests/LoginManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // LoginManager.m 3 | // iOSUITests 4 | // 5 | // Created by dyw on 2017/3/15. 6 | // Copyright © 2017年 dyw. All rights reserved. 7 | // 8 | 9 | #import "LoginManager.h" 10 | 11 | #define LoginKey @"LoginKey" 12 | 13 | @implementation LoginManager 14 | 15 | + (void)setLogin:(BOOL)isLogin{ 16 | NSUserDefaults *df = [NSUserDefaults standardUserDefaults]; 17 | [df setBool:isLogin forKey:LoginKey]; 18 | } 19 | 20 | + (BOOL)getLogin{ 21 | NSUserDefaults *df = [NSUserDefaults standardUserDefaults]; 22 | return [df boolForKey:LoginKey]; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /iOSUITests/LoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // LoginViewController.h 3 | // iOSUITests 4 | // 5 | // Created by dyw on 2017/3/15. 6 | // Copyright © 2017年 dyw. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface LoginViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /iOSUITests/LoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // LoginViewController.m 3 | // iOSUITests 4 | // 5 | // Created by dyw on 2017/3/15. 6 | // Copyright © 2017年 dyw. All rights reserved. 7 | // 8 | 9 | #import "LoginViewController.h" 10 | #import "LoginManager.h" 11 | 12 | #define TestName @"iss" 13 | #define TestPwd @"123456" 14 | 15 | @interface LoginViewController () 16 | @property (weak, nonatomic) IBOutlet UITextField *nameTextField; 17 | @property (weak, nonatomic) IBOutlet UITextField *pwdTextField; 18 | 19 | @end 20 | 21 | @implementation LoginViewController 22 | 23 | #pragma mark - life cycle 24 | - (void)viewDidLoad { 25 | [super viewDidLoad]; 26 | // Do any additional setup after loading the view. 27 | self.nameTextField.autocorrectionType = UITextAutocorrectionTypeNo; 28 | self.pwdTextField.autocorrectionType = UITextAutocorrectionTypeNo; 29 | } 30 | 31 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 32 | [self.view endEditing:YES]; 33 | } 34 | 35 | #pragma mark - private methods 36 | 37 | #pragma mark - public methods 38 | 39 | #pragma mark - request methods 40 | 41 | #pragma mark - UITableViewDataSource 42 | 43 | #pragma mark - UITableViewDelegate 44 | 45 | #pragma mark - Custom Delegate 46 | 47 | #pragma mark - event response 48 | - (IBAction)cancerButtonClick:(id)sender { 49 | [[UIApplication sharedApplication].keyWindow endEditing:YES]; 50 | [self dismissViewControllerAnimated:YES completion:nil]; 51 | } 52 | 53 | - (IBAction)loginButtonClick:(id)sender { 54 | if([self.nameTextField.text isEqualToString:TestName] && [self.pwdTextField.text isEqualToString:TestPwd]){ 55 | [LoginManager setLogin:YES]; 56 | [self dismissViewControllerAnimated:YES completion:nil]; 57 | return; 58 | } 59 | UIAlertView *alt = [[UIAlertView alloc] initWithTitle:nil message:@"账号或者密码错误" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil]; 60 | [alt show]; 61 | } 62 | 63 | #pragma mark - getters and setters 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /iOSUITests/MineViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MineViewController.h 3 | // iOSUITests 4 | // 5 | // Created by dyw on 2017/3/15. 6 | // Copyright © 2017年 dyw. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MineViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /iOSUITests/MineViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MineViewController.m 3 | // iOSUITests 4 | // 5 | // Created by dyw on 2017/3/15. 6 | // Copyright © 2017年 dyw. All rights reserved. 7 | // 8 | 9 | #import "MineViewController.h" 10 | #import "LoginManager.h" 11 | 12 | @interface MineViewController () 13 | 14 | 15 | @end 16 | 17 | @implementation MineViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | 22 | // Uncomment the following line to preserve selection between presentations. 23 | // self.clearsSelectionOnViewWillAppear = NO; 24 | 25 | // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 26 | // self.navigationItem.rightBarButtonItem = self.editButtonItem; 27 | } 28 | 29 | - (void)didReceiveMemoryWarning { 30 | [super didReceiveMemoryWarning]; 31 | // Dispose of any resources that can be recreated. 32 | } 33 | 34 | #pragma mark - Table view data source 35 | 36 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 37 | return [super numberOfSectionsInTableView:tableView]; 38 | } 39 | 40 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 41 | return [super tableView:tableView numberOfRowsInSection:section]; 42 | } 43 | 44 | /* 45 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 46 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:<#@"reuseIdentifier"#> forIndexPath:indexPath]; 47 | 48 | // Configure the cell... 49 | 50 | return cell; 51 | } 52 | */ 53 | 54 | /* 55 | // Override to support conditional editing of the table view. 56 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { 57 | // Return NO if you do not want the specified item to be editable. 58 | return YES; 59 | } 60 | */ 61 | 62 | /* 63 | // Override to support editing the table view. 64 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 65 | if (editingStyle == UITableViewCellEditingStyleDelete) { 66 | // Delete the row from the data source 67 | [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; 68 | } else if (editingStyle == UITableViewCellEditingStyleInsert) { 69 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 70 | } 71 | } 72 | */ 73 | 74 | /* 75 | // Override to support rearranging the table view. 76 | - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { 77 | } 78 | */ 79 | 80 | /* 81 | // Override to support conditional rearranging of the table view. 82 | - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { 83 | // Return NO if you do not want the item to be re-orderable. 84 | return YES; 85 | } 86 | */ 87 | 88 | /* 89 | #pragma mark - Navigation 90 | 91 | // In a storyboard-based application, you will often want to do a little preparation before navigation 92 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 93 | // Get the new view controller using [segue destinationViewController]. 94 | // Pass the selected object to the new view controller. 95 | } 96 | */ 97 | - (IBAction)buttonclick:(id)sender { 98 | [LoginManager setLogin:NO]; 99 | UIAlertView *alt = [[UIAlertView alloc] initWithTitle:nil message:@"成功注销" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil]; 100 | [alt show]; 101 | } 102 | 103 | - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ 104 | NSNotification * notice = [NSNotification notificationWithName:@"logOut" object:nil userInfo:nil]; 105 | [[NSNotificationCenter defaultCenter]postNotification:notice]; 106 | } 107 | 108 | 109 | @end 110 | -------------------------------------------------------------------------------- /iOSUITests/TabBarController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TabBarController.h 3 | // iOSUITests 4 | // 5 | // Created by dyw on 2017/3/15. 6 | // Copyright © 2017年 dyw. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TabBarController : UITabBarController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /iOSUITests/TabBarController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TabBarController.m 3 | // iOSUITests 4 | // 5 | // Created by dyw on 2017/3/15. 6 | // Copyright © 2017年 dyw. All rights reserved. 7 | // 8 | 9 | #import "TabBarController.h" 10 | #import "LoginManager.h" 11 | 12 | @interface TabBarController () 13 | 14 | 15 | @end 16 | 17 | @implementation TabBarController 18 | 19 | #pragma mark - life cycle 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | // Do any additional setup after loading the view. 23 | self.delegate = self; 24 | 25 | //添加当前类对象为一个观察者,name和object设置为nil,表示接收一切通知 26 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(logOut) name:@"logOut" object:nil]; 27 | } 28 | 29 | - (void)didReceiveMemoryWarning { 30 | [super didReceiveMemoryWarning]; 31 | // Dispose of any resources that can be recreated. 32 | } 33 | 34 | - (void)dealloc{ 35 | [[NSNotificationCenter defaultCenter] removeObserver:@"logOut"]; 36 | } 37 | 38 | #pragma mark - private methods 39 | - (void)logOut{ 40 | self.selectedIndex = 0; 41 | } 42 | 43 | #pragma mark - public methods 44 | 45 | #pragma mark - request methods 46 | 47 | #pragma mark - UITableViewDataSource 48 | 49 | #pragma mark - UITableViewDelegate 50 | 51 | #pragma mark - TabBarController Delegate 52 | - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController { 53 | //判断是否登陆 未登陆跳转到登陆界面 54 | if(![LoginManager getLogin]){ 55 | [self performSegueWithIdentifier:@"prLoginViewController" sender:nil]; 56 | return NO; 57 | } 58 | return YES; 59 | } 60 | 61 | 62 | #pragma mark - event response 63 | 64 | #pragma mark - getters and setters 65 | 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /iOSUITests/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // iOSUITests 4 | // 5 | // Created by dyw on 2017/3/15. 6 | // Copyright © 2017年 dyw. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /iOSUITestsTests/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 | -------------------------------------------------------------------------------- /iOSUITestsTests/iOSUITestsTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // iOSUITestsTests.m 3 | // iOSUITestsTests 4 | // 5 | // Created by dyw on 2017/3/15. 6 | // Copyright © 2017年 dyw. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface iOSUITestsTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation iOSUITestsTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /iOSUITestsUITests/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 | -------------------------------------------------------------------------------- /iOSUITestsUITests/iOSUITestsUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // iOSUITestsUITests.m 3 | // iOSUITestsUITests 4 | // 5 | // Created by dyw on 2017/3/15. 6 | // Copyright © 2017年 dyw. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define MaxLoginNumber 2 //最多循环登录次数 12 | static NSInteger loginIndex = 0;//当前登录账号的下标 13 | 14 | @interface iOSUITestsUITests : XCTestCase 15 | 16 | /** 当前测试的APP */ 17 | @property (nonatomic, strong) XCUIApplication *app; 18 | /** 测试账号集合 */ 19 | @property (nonatomic, strong) NSArray *accountArr; 20 | 21 | @end 22 | 23 | @implementation iOSUITestsUITests 24 | 25 | - (void)setUp { 26 | [super setUp]; 27 | 28 | XCUIApplication *app = [[XCUIApplication alloc] init]; 29 | //关闭应用 30 | [app terminate]; 31 | //重新启动引用 32 | [app launch]; 33 | //启动参数 34 | NSArray *args = [app launchArguments]; 35 | for(int i=0;i 测试登陆 已经是登陆状态"); 150 | return; 151 | } 152 | NSLog(@"---> 开始测试登陆"); 153 | //UITabBarController 154 | XCUIElementQuery *tabBarsQuery = self.app.tabBars; 155 | XCUIElement *tableBarButton = tabBarsQuery.buttons[@"我的"]; 156 | !tableBarButton.exists?:[tableBarButton tap]; 157 | 158 | XCTAssert((loginIndex 账号%@ 密码%@ 登陆失败", userName, pwd); 198 | //换个账号 重新登陆 199 | loginIndex ++; 200 | [self testLogin]; 201 | }else{//登陆成功 202 | 203 | NSLog(@"---> 账号%@ 密码%@ 登陆成功", userName, pwd); 204 | 205 | XCUIElement *tableBarButton = tabBarsQuery.buttons[@"我的"]; 206 | !tableBarButton.exists?:[tableBarButton tap]; 207 | 208 | tableBarButton = tabBarsQuery.buttons[@"首页"]; 209 | !tableBarButton.exists?:[tableBarButton tap]; 210 | 211 | NSLog(@"---> 登陆测试完成"); 212 | } 213 | } 214 | 215 | #pragma mark - 退出登陆 216 | - (void)testLogOut{ 217 | //判断是否登陆 218 | if([self isLogin]){ 219 | NSLog(@"--> 开始退出登陆"); 220 | //进入我的页面 221 | XCUIElement *tableBarButton = self.app.tabBars.buttons[@"我的"]; 222 | !tableBarButton.exists?:[tableBarButton tap]; 223 | 224 | //向上滑一点 避免小屏幕看不到按钮 225 | XCUIElement *tableView = [self.app.tables elementAtIndex:0]; 226 | [tableView swipeUp]; 227 | 228 | XCUIElementQuery *tablesQuery = self.app.tables; 229 | [tablesQuery.buttons[@"退出登陆"] tap]; 230 | 231 | //弹窗点击 232 | [self alertViewTap]; 233 | 234 | //判断是否登陆成功 235 | XCTAssert(![self isLogin], @"退出登陆失败,快查查原因"); 236 | 237 | NSLog(@"---> 成功退出登陆"); 238 | }else{ 239 | NSLog(@"---> 本来就没有登陆"); 240 | } 241 | } 242 | 243 | 244 | #pragma mark - 资讯 245 | - (void)testInformation{ 246 | NSInteger loginCount = 0; 247 | if([self isLogin]){//已经登陆 248 | NSLog(@"---> 开始测试资讯页面"); 249 | XCUIElement *information = self.app.tabBars.buttons[@"资讯"]; 250 | !information.exists?:[information tap]; 251 | //点击 252 | XCUIElement *button = self.app.buttons[@"标签2"]; 253 | [button tap]; 254 | button = self.app.buttons[@"标签3"]; 255 | [button tap]; 256 | button = self.app.buttons[@"标签4"]; 257 | [button tap]; 258 | button = self.app.buttons[@"标签5"]; 259 | [button tap]; 260 | button = self.app.buttons[@"标签6"]; 261 | [button tap]; 262 | button = self.app.buttons[@"标签1"]; 263 | [button tap]; 264 | //滑动 265 | XCUIElement *swipeView = [self.app.scrollViews elementAtIndex:0]; 266 | [swipeView swipeRight]; 267 | [swipeView swipeLeft]; 268 | [swipeView swipeLeft]; 269 | [swipeView swipeLeft]; 270 | [swipeView swipeLeft]; 271 | [swipeView swipeLeft]; 272 | [swipeView swipeLeft]; 273 | 274 | NSLog(@"---> 资讯页面测试完成"); 275 | }else{//未登陆 276 | XCTAssert((loginCount 在资讯页面发现未登录 开始第 %@ 次登陆", @(loginCount)); 278 | loginCount ++; 279 | //发起登陆 280 | [self testLogin]; 281 | //继续测试资讯 282 | [self testInformation]; 283 | } 284 | } 285 | 286 | #pragma mark - 我的 287 | - (void)testMine{ 288 | NSInteger loginCount = 0; 289 | if([self isLogin]){//已经登陆 290 | NSLog(@"---> 开始测试我的页面"); 291 | XCUIElement *information = self.app.tabBars.buttons[@"我的"]; 292 | !information.exists?:[information tap]; 293 | 294 | XCUIElement *tableView = [self.app.tables elementAtIndex:0]; 295 | [tableView swipeDown]; 296 | [tableView swipeUp]; 297 | [tableView swipeDown]; 298 | [tableView swipeUp]; 299 | 300 | NSLog(@"---> 我的页面测试完成"); 301 | }else{//未登陆 302 | XCTAssert((loginCount 在我的页面发现未登录 开始第 %@ 次登陆", @(loginCount)); 304 | loginCount ++; 305 | //发起登陆 306 | [self testLogin]; 307 | //继续测试我的 308 | [self testMine]; 309 | } 310 | } 311 | 312 | 313 | 314 | #pragma mark -辅助方法 315 | /** 隐藏键盘 */ 316 | - (void)hindKeyBoard{ 317 | XCUIElement *element = [[self.app childrenMatchingType:XCUIElementTypeWindow] elementBoundByIndex:0]; 318 | [element tap]; 319 | } 320 | /** 判断是否在登陆界面 */ 321 | - (BOOL)isLogin{ 322 | BOOL isLogin; 323 | //进入我的界面 324 | XCUIElementQuery *tabBarsQuery = self.app.tabBars; 325 | XCUIElement *tableBarButton = tabBarsQuery.buttons[@"我的"]; 326 | !tableBarButton.exists?:[tableBarButton tap]; 327 | //获取标志性Element loginLabel 328 | XCUIElement *loginLabel = self.app.staticTexts[@"loginLabel"]; 329 | //判断是否登陆 330 | if(loginLabel.exists){//进入登陆界面(当前状态未登陆) 331 | XCUIElement *cancerButton = self.app.buttons[@"取消"]; 332 | !cancerButton.exists?:[cancerButton tap]; 333 | isLogin = NO; 334 | }else{//进入我的页面(当前状态已经登陆) 335 | tableBarButton = tabBarsQuery.buttons[@"首页"]; 336 | !tableBarButton.exists?:[tableBarButton tap]; 337 | isLogin = YES; 338 | } 339 | return isLogin; 340 | } 341 | 342 | /** cell点击 */ 343 | - (void)cellTapAtIndex:(NSInteger)index withCells:(XCUIElementQuery *)cellQuery{ 344 | XCUIElement *cellElement = [cellQuery elementAtIndex:index]; 345 | !cellElement.exists?:[cellElement tap]; 346 | } 347 | 348 | /** 弹窗点击 */ 349 | - (void)alertViewTap{ 350 | sleep(0.5); 351 | XCUIElement *alertView = [self.app.alerts elementAtIndex:0]; 352 | XCUIElement *alertButton = alertView.buttons[@"确定"]; 353 | !alertButton.exists?:[alertButton tap]; 354 | } 355 | 356 | - (XCUIApplication *)app{ 357 | if(!_app){ 358 | _app = [[XCUIApplication alloc] init]; 359 | } 360 | return _app; 361 | } 362 | 363 | - (NSArray *)accountArr{ 364 | if(!_accountArr.count){ 365 | _accountArr = @[ 366 | @{@"name":@"zhangsan", @"pwd":@"123456"},//账号1 367 | @{@"name":@"lisis", @"pwd":@"123456"},//账号2 368 | @{@"name":@"wangmazi", @"pwd":@"123456"},//账号3 369 | @{@"name":@"iss", @"pwd":@"123456"},//账号4 370 | ]; 371 | } 372 | return _accountArr; 373 | } 374 | 375 | @end 376 | --------------------------------------------------------------------------------