作者: xiao, yanzi

iOS开发 – 在状态栏显示FPS,CPU和内存信息

前言
今天在用Instruments分析App的时候,总感觉看起来不太直观。到Github上找了找,发现几乎都是只显示FPS的,而且效果也不是我想要的。于是就自己写了个

源码地址
LHPerformanceStatusBar
效果

%title插图%num

字体颜色会根据阈值进行颜色变化,性能差的时候字体会变成红色,性能一般的时候会变成橘黄色,阈值可配。

集成
CocoaPod集成

pod LHPerformanceStatusBar

使用
– (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[LHPerformanceMonitorService run];
}

原理
FPS的计算
CoreAnimation有一个很好用的类CADisplayLink,这个类会在每一帧绘制之前调用,并且可以获取时间戳。于是,我们只要统计出,在1s内的帧数即可。

 

– (void)envokeDisplayLink:(CADisplayLink *)displayLink{
if (_lastTimestamp == -1) {
_lastTimestamp = displayLink.timestamp;
return;
}
_countPerFrame ++;
NSTimeInterval interval = displayLink.timestamp – _lastTimestamp;
if (interval < 1) {
return;
}
_lastTimestamp = displayLink.timestamp;
CGFloat fps = _countPerFrame / interval;
//…
}

内存和CPU信息的获取
CPU和内存的获取采用了mach头文件中的方法,调用了底层API,采用C方式来获取。

iOS计算FPS

原理:CADisplayLink是在每一帧绘制之前调用,并且可以获取时间戳。

1 – (void)viewDidLoad {
2     [super viewDidLoad];
3
4     _lastTimestamp = -1;
5     _frameCount = 0;
6     CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(calFPS:)];
7     [link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
8 }
9
10 //计算1S内帧数
11 -(void)calFPS:(CADisplayLink *)displayLink
12 {
13     if(_lastTimestamp == -1){
14         _lastTimestamp = displayLink.timestamp;
15         return;
16     }
17
18     _frameCount++;
19
20     NSTimeInterval interval = displayLink.timestamp – _lastTimestamp;
21
22     if(interval < 1){
23         return;
24     }
25
26     _lastTimestamp = displayLink.timestamp;
27
28     CGFloat fps = _frameCount / interval;
29
30     NSLog(@”%f”, fps);
31
32     _frameCount = 0;
33 }

iOS测试fps方式

Measure Graphics Performance

Extensive use of graphics in your iOS app can make your app stand out from your competitors. But unless you use graphics resources responsibly, your app will slow down, reduce battery life, and look mediocre no matter how good the content you are trying to render. For optimal graphic performance:

  • Ensure that the frame rate of animations is sufficient for providing a fluid visual experience without negatively impacting app performance. 
  • Reduce the number of views your app uses. 
  • Reduce the use of opacity, such as in views that exhibit a translucent blur. If you need to use opacity, avoid using it over views that are updated frequently. Otherwise, energy cost is magnified, as both the background view and the translucent view must be updated whenever content changes. 
  • Draw to smaller portions of the screen—only the portions that are changing. To do this, use a href=”” needsToDrawRect: /a or a href=”” getRectsBeingDrawn:count: /a to identify the specific area to update, and pass the result to drawRect:
  • Eliminate drawing when your app or its content is not visible; for example, when your app is in the background, or when its content is obscured by other views, clipped, or offscreen. 
  • Eliminate drawing during window resizing. 

Measure Core Animation Graphics Performance in iOS

The Core Animation profiling template uses the Core Animation and Time Profiler instruments to measure your iOS app’s graphics and CPU performance. This template provides a quick and lightweight starting point for measuring the number of frames per second rendered by your app. It allows you to quickly see where your app renders fewer frames than expected. By correlating what you were doing at the time the sample was taken, you can identify areas of your code that need to be optimized.

NOTE

Use the Core Animation template to profile an app on a physical device. Profiling an app in the iOS Simulator will not produce true real-world results.

Do not use the Core Animation instrument to measure OpenGL ES performance.

To measure frame rate

  1. Connect your iOS device to your Mac.
  2. Launch Instruments.
  3. When the profiling template selection dialog appears, click Core Animation.
  4. Choose your iOS device and app from the target device and process lists.
  5. Click Choose to create a trace document.
  6. Click the Record button () in the toolbar or press Command-R to begin recording.
  7. Use your app normally.
  8. Click the Stop button () or press Command-R again when complete.
  9. Examine the collected data.

    The detail pane shows the frame rate for each recorded sample.

Correlate Interactions with Results

After capturing data with the Core Animation instrument, you may see spikes in the timeline pane where the frame rate of the app becomes appreciably better. In some cases, however, spikes can be caused by changing the device between landscape and normal orientation—and if you don’t know this, you might spend time trying to find what caused the performance increase. One way to correlate interactions with results is to insert flags into the timeline when you performed certain events. See Set Flags.

Debugging Options

Core Animation contains a number of useful debugging options in the display settings area of the inspector pane. You do not need to be running a trace to use these options on your iOS device.

  • Color Blended Layers. Shows blended view layers. Multiple view layers that are drawn on top of each other with blending enabled are highlighted in red. Reducing the amount of red in your app when this option is selected can dramatically improve your app’s performance. Blended view layers often cause slow table scrolling. 
  • Color Hits Green and Misses Red. Marks views in green or red. A view that is able to use a cached rasterization is marked in green. 
  • Color Copied Images. Shows images that are copied by Core Animation in blue. 
  • Color Immediately. Removes the 10 ms delay when performing color-flush operations. 
  • Color Misaligned Images. Places a magenta overlay over images where the source pixels are not aligned to the destination pixels. 
  • Color Offscreen-Rendered Yellow. Places a yellow overlay over content that is rendered offscreen. 
  • Color OpenGL Fast Path Blue. Places a blue overlay over content that is detached from the compositor. 
  • Flash Updated Regions. Colors regions on your iOS device in yellow when those regions are updated by the graphics processor. 

Measure OpenGL Activity in iOS

The OpenGL ES Analysis profiling template uses the OpenGL ES Analyzer and GPU Driver instruments to measure and analyze OpenGL ES activity in your iOS app in order to detect correctness and performance problems. It also recommends how to address found problems.

To measure OpenGL Activity

  1. Connect your iOS device to your Mac.
  2. Launch Instruments.
  3. When the profiling template selection dialog appears, click OpenGL ES Analysis.
  4. Choose your iOS device and app from the target device and process lists.
  5. Click Choose to create a trace document.
  6. Click the Record button () in the toolbar or press Command-R to begin recording.
  7. Use your app normally, exercising your OpenGL ES graphics code.
  8. After a few seconds of measurement, click the Stop button () or press Command-R again.
  9. Examine the collected data.

Errors are listed in the detail pane sorted by their severity. Red squares indicate the most severe problems, and orange triangles indicate less severe problems. A recommendation and the stack trace are displayed in the extended detail area of the inspector pane for the issue selected in the detail pane.

Find Graphics-Related Bottlenecks in iOS or OS X

The GPU Driver profiling template uses the GPU Driver and Time Profiler instruments to measure app performance and provides more than just the number of frames per second your app renders.

To look for graphics-related bottlenecks

  1. Launch Instruments.
  2. When the profiling template selection dialog appears, click GPU Driver.
  3. Choose your device and app from the target device and process lists.
  4. Click Choose to create a trace document.
  5. Click the Record button () in the toolbar or press Command-R to begin recording.
  6. Use your app normally.
  7. Click the Stop button () or press Command-R again when complete.
  8. Press Command-3 to display the extended detail area of the inspector pane.
  9. Examine the collected data.

The individual statistics displayed by the GPU Driver instrument in the timeline pane can be enabled and disabled in the record settings area of the inspector pane.

The detail pane displays all of the gathered information for a specific sample. Select a row of data to view the sample’s statistics in the extended detail area of the inspector pane.

Bottlenecks for an OpenGL app are usually GPU or CPU bottlenecks. GPU bottlenecks occur when the GPU forces the CPU to wait for information because the GPU has too much information to process. CPU bottlenecks occur when the GPU has to wait for information from the CPU before the GPU can process it. CPU bottlenecks can often be fixed by changing the underlying logic of your app to create a better overall flow of information to the GPU. Common bottlenecks include:

  • Geometry limited. If Tiler Utilization is high, examine your vertex shader processes. 
  • Pixel limited. If Rendered Utilization is high, examine your fragment shader processes. 
  • CPU limited. If Tiler Utilization and Rendered Utilization are both low, the performance bottleneck may not be in your OpenGL code. Examine your code’s overall logic.

Appium+Python3+iOS真机环境搭建

Appium 是一个自动化测试开源工具,支持 iOS 平台和 Android 平台上的原生应用,web 应用和混合应用。
1.环境配置
Mac系统自带的Python版本是2.7,当前要用新版,这里我选择的Python版本是3.5。下载安装。
删除掉mac自带的python2.7
sudo rm -R /System/Library/Frameworks/Python.framework/Versions/2.7
加上:
alias python=’/Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5’
保存退出,执行:
source ~/.bash_profile
2,把appium和selenium安装到python3.5的set-packages中
3,appium运行时jdk的安装
访问Oracle官网 http://www.oracle.com
jdk下载的地方https://www.oracle.com/technetwork/java/javase/downloads/jdk11-downloads-5066655.html
下载安装jdk,打开Finder,可以在下图所示的路径中找到安装好的jdk 1.8.0_40.jdk
%title插图%num

Contents下的Home文件夹,是该JDK的根目录

%title插图%num

打开终端配置jdk环境变量:
如果你是*次配置环境变量,可以使用“touch .bash_profile” 创建一个.bash_profile的隐藏配置文件(如果你是为编辑已存在的配置文件,则使用”open -e .bash_profile”命令):
输入如下配置:

%title插图%num

JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home
PATH=$ JAVA_HOME/bin:$ PATH:.
CLASSPATH=$ JAVA_HOME/lib/tools.jar:$ JAVA_HOME/lib/dt.jar:.
export JAVA_HOME
export PATH
export CLASSPATH
然后保存关闭该窗口。
使用”source .bash_profile”使配置生效
输入 echo $ JAVA_HOME 显示刚才配置的路径
测试输入java -version
4,sdk环境变量的配置
在命令行输入 open -e .bash_profile , 打开.bash_profile文件,输入如下配置:
export ANDROID_HOME=/Library/Java/sdk
export PATH=$ {PATH}: $ {ANDROID_HOME}/tools
export PATH=$ {PATH}: $ {ANDROID_HOME}/platform-tools
export PATH=$ {PATH}: $ {ANDROID_HOME}/build-tools

export PATH=${PATH}:/Library/Java/sdk/platform-tools:/Library/Java/sdk/tools
%title插图%num

然后保存并关闭。
在命令行输入source .bash_profile ,使之生效。
5,ios的元素定位工具
a.Appium自带的Inspector工具
b.Macaca的app-inspector工具,具体地址:https://macacajs.github.io/app-inspector/cn/
c.Xcode自带的accessibility-inspector工具
具体地址:http://blog.csdn.net/icetime17/article/details/42211915
d.Appium团队提供的appium-ios-inspector
具体地址:https://github.com/mykola-mokhnach/Appium-iOS-Inspector
e.通过flex插件,具体地址:https://github.com/Flipboard/FLEX

ios-deploy时,终端构建失败

安装ios-deploy时,终端构建失败:
ios-deploy是一个从mac电脑把app打包到手机的工具
安装:sudo npm install -g ios-deploy –unsafe-perm=true

安装出现问题:
** BUILD FAILED **
The following build commands failed:
CompileC /usr/local/lib/node_modules/ios-deploy/build/ios-deploy.build/Release/ios-deploy-lib.build/Objects-normal/x86_64/libios_deploy.o /usr/local/lib/node_modules/ios-deploy/src/ios-deploy-lib/libios_deploy.m normal x86_64 objective-c com.apple.compilers.llvm.clang.1_0.compiler
(1 failure)
npm ERR! code ELIFECYCLE
npm ERR! errno 65
npm ERR! [email protected] preinstall: ./src/scripts/check_reqs.js && xcodebuild`
npm ERR! Exit status 65
npm ERR!
npm ERR! Failed at the [email protected] preinstall script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

解决方式:
需要把macOS,ios,xcode版本号升级为一致,因为用命令安装的时候默认安装*新的ios-deploy,而电脑的配置不相符:

升级之后执行
终端运行:sudo xcode-select –switch /Applications/Xcode.app/Contents/Developer
在执行:sudo npm install -g ios-deploy –unsafe-perm=true
open /Applications/Xcode.app/Contents/Developer

安装成功

appium+iOS元素的定位方式

查找元素的顺序,从快到慢:
查找元素的顺序,从快到慢:
ios_predicate >> accessibility_id >> class_name >>xpath
(论坛比较多的说法是class_name>>accessibility_id,在这里我们姑且认为它们的速度是一样的。)
1,ios_predicate:OS 的 UI 自动化中,使用原生支持的Predicate定位方式是*好,可支持元素的单个属性和多个属性定位,强烈推荐使用
driver.find_element_by_ios_predicate(“value == ‘ClearEmail’”)
driver.find_element_by_ios_predicate(“type == ‘’ AND value == ‘’)
https://www.jianshu.com/p/a6c2d72fe704
2,accessibility_id
替代以前的name定位方式,在 iOS 上,主要使用元素的label或name(两个属性的值都一样)属性进行定位,如该属性为空,也是不能使用该属性。
driver.find_element_by_accessibility_id(‘ClearEmail’)
3、class_name
使用元素的type属性定位,特别注意该属性的唯一性!class_name唯一的情况并不多,一般情况下用不上。
driver.find_element_by_class_name(‘XCUIElementTypeButton’)
4、xpath
由于 iOS 10开始使用的 XCUITest 框架原生不支持,定位速度很慢,所以官方现在不推荐大家使用,也有其他替代的定位方式可使用。
1)使用*对路径定位:
driver.find_element_by_xpath(’/XCUIElementTypeApplication/XCUIElementTypeButton’)
2)使用相对路径定位
driver.find_element_by_xpath(’//XCUIElementTypeButton’)
3)通过元素的索引定位
driver.find_element_by_xpath(’//XCUIElementTypeButton[index]’)
4.通过元素的属性定位
一种属性:
driver.find_element_by_xpath(”//className[@value=‘ClearEmail’]”)
两种属性:
driver.find_element_by_xpath(“//className[@value=‘ClearEmail’][@ visible =true]”)
部分属性(*强大):driver.find_element_by_xpath(“//className[contains(@value,‘ClearEmail’)]”)
5,iOSNsPredicateString
仅支持 iOS 10或以上,可支持元素的单个属性和多个属性定位,推荐使用。
一种属性:MobileBy.iOSNsPredicateString(“type == ‘XCUIElementTypeButton’”)
两种属性:MobileBy.iOSNsPredicateString(“type == ‘XCUIElementTypeButton’ AND label == ‘更多信息’”)

IOS学习之——CoreLocation定位的使用

1 在移动互联网时代,移动app能解决用户的很多生活琐事,比如
2 导航:去任意陌生的地方
3 周边:找餐馆、找酒店、找银行、找电影院
4
5 在上述应用中,都用到了地图和定位功能,在iOS开发中,要想加入这2大功能,必须基于2个框架进行开发
6 Map Kit :用于地图展示
7 Core Location :用于地理定位
8
9 2个热门专业术语
10 LBS :Location Based Service
11 SoLoMo :Social Local Mobile(索罗门)
12
13 CoreLocation框架使用前提
14 导入框架
15
16 导入主头文件
17 #import <CoreLocation/CoreLocation.h>
18
19 CoreLocation框架使用须知
20 CoreLocation框架中所有数据类型的前缀都是CL
21 CoreLocation中使用CLLocationManager对象来做用户定位
22
23 CLLocationManager
24
25 CLLocationManager的常用操作
26 开始用户定位
27 – (void)startUpdatingLocation;
28
29 停止用户定位
30 – (void) stopUpdatingLocation;
31
32 当调用了startUpdatingLocation方法后,就开始不断地定位用户的位置,中途会频繁地调用代理的下面方法
33 – (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;
34 locations参数里面装着CLLocation对象
35
36
37 CLLocation
38
39 CLLocation用来表示某个位置的地理信息,比如经纬度、海拔等等
40 @property(readonly, nonatomic) CLLocationCoordinate2D coordinate;
41 经纬度
42
43 @property(readonly, nonatomic) CLLocationDistance altitude;
44 海拔
45
46 @property(readonly, nonatomic) CLLocationDirection course;
47 路线,航向(取值范围是0.0° ~ 359.9°,0.0°代表真北方向)
48
49 @property(readonly, nonatomic) CLLocationSpeed speed;
50 行走速度(单位是m/s)
51
52 用- (CLLocationDistance)distanceFromLocation:(const CLLocation *)location方法可以计算2个位置之间的距离
53
54
55 CLLocationManager
56
57 @property(assign, nonatomic) CLLocationDistance distanceFilter;
58 每隔多少米定位一次
59
60 @property(assign, nonatomic) CLLocationAccuracy desiredAccuracy;
61 定位精确度(越精确就越耗电)
62
63 CLLocationCoordinate2D
64
65 CLLocationCoordinate2D是一个用来表示经纬度的结构体,定义如下
66 typedef struct {
67         CLLocationDegrees latitude; // 纬度
68         CLLocationDegrees longitude; // 经度
69 } CLLocationCoordinate2D;
70
71 一般用CLLocationCoordinate2DMake函数来创建CLLocationCoordinate2D
72
73
74 用户隐私的保护
75
76 从iOS 6开始,苹果在保护用户隐私方面做了很大的加强,以下操作都必须经过用户批准授权
77 要想获得用户的位置
78 想访问用户的通讯录、日历、相机、相册等等
79
80 当想访问用户的隐私信息时,系统会自动弹出一个对话框让用户授权
81
82 从iOS 8开始,用户定位分两种情况
83 总是使用用户位置:NSLocationAlwaysUsageDescription
84 使用应用时定位:NSLocationWhenInUseDescription
85
86 当想访问用户的隐私信息时,系统会自动弹出一个对话框让用户授权
87
88
89 CLGeocoder
90
91 使用CLGeocoder可以完成“地理编码”和“反地理编码”
92 地理编码:根据给定的地名,获得具体的位置信息(比如经纬度、地址的全称等)
93 反地理编码:根据给定的经纬度,获得具体的位置信息
94
95 地理编码方法
96 – (void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler;
97
98 反地理编码方法
99 – (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;
100
101
102 CLGeocodeCompletionHandler
103
104 当地理\反地理编码完成时,就会调用CLGeocodeCompletionHandler
105 typedef void (^CLGeocodeCompletionHandler)(NSArray *placemarks, NSError *error);
106 这个block传递2个参数
107 error :当编码出错时(比如编码不出具体的信息)有值
108 placemarks :里面装着CLPlacemark对象
109
110 CLPlacemark
111
112 CLPlacemark的字面意思是地标,封装详细的地址位置信息
113 @property (nonatomic, readonly) CLLocation *location;
114 地理位置
115
116 @property (nonatomic, readonly) CLRegion *region;
117 区域
118
119 @property (nonatomic, readonly) NSDictionary *addressDictionary;
120 详细的地址信息
121
122 @property (nonatomic, readonly) NSString *name;
123 地址名称
124
125 @property (nonatomic, readonly) NSString *locality;
126 城市

iOS学习——自动定位

*近在项目中需要做自动定位功能,就是你在参加会议通过扫描二维码签到的时候自动定位并将你的定位信息在签到中上传,这样可以避免我们进行假签到。在这个功能中,主要用到的是系统自带的定位模块,首先我们是需要配置定位功能的参数,然后当我们定位成功时调用特定的方法进行相应操作就可以了,当然,在定位失败时我们也可以进行相应的操作,这些都有对应的一些回调方法,我们只需要重写对应的回调方法就可以实现对应的功能了。

首先,我们用到的系统自带的定位模块是: <CoreLocation/CoreLocation.h> ,定位成功/失败的方法都是通过代理 CLLocationManagerDelegate 来完成的,所以我们在需啊哟进行定位的类中也需要继承自代理,并实现对应的一些方法才能成功完成回调。在定位功能的调用中,主要分为两步:1、定位参数的配置;2、代理回调方法的实现

一 定位参数的配置

定位参数的配置主要是通过系统的定位管理器CLLocationManager进行配置,参数配置的几个要点主要是设置代理,设置寻址精度,然后开启定位。当然,这些参数的配置的前提是我们的手机已经对我们的项目进行了地理位置的授权,所以我们再配置之前需要对当前定位权限进行判断,通过 [CLLocationManager locationServicesEnabled] 方法可以直接得到定位权限是否开启,如果有对应的权限,我们就可以进行对应的配置信息,否则我们无法进行对应的配置,这时候我们可以弹出一个对话框进行提示用户如何开启定位权限,在我们的项目中因为不需要进行提示,所以没有对应的代码模块。

- (void)viewDidLoad {
    [super viewDidLoad];

    //配置定位信息
    [self configLocation];
}

- (void)configLocation{
    self.place = @"";
    //判断定位权限是否打开
    if ([CLLocationManager locationServicesEnabled]) {
        locationManager = [[CLLocationManager alloc] init];
        locationManager.delegate = self;
        //设置寻址精度
        locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        locationManager.distanceFilter = 100.0f;
        //开始定位
        [locationManager startUpdatingLocation];
    } else {
        //如果定位权限没有打开,可以进行相应的提示
        //具体代码省略
    }
}

 二 代理方法的回调

在前面我们说过了,我们的类需要继承CLLocationManagerDelegate代理,并实现其中的一些方法才能在定位成功/失败时能够正确地调用对应的代理方法。主要用到的代理方法有两个,一个是成功时调用,一个是失败时调用,具体代码如下。在定位失败时,我们首先可以弹框提示定位失败的原因,接着我们可以选择重新定位,或者我们也可以选择限制连续定位失败多少次后就不再进行定位了,具体需要实现的方法大家可以根据需要进行配置和开发。

#pragma mark - CLLocationManagerDelegate
//定位成功的回调,在这里我们配置我们的位置信息
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
    [locationManager stopUpdatingLocation];
    CLLocation *currentLoc = [locations lastObject];
    CLGeocoder *geoCoder = [[CLGeocoder alloc] init];
    //利用经纬度进行反编译获取位置信息
    [geoCoder reverseGeocodeLocation:currentLoc completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        if (placemarks.count > 0) {
            //获取当前定位信息
            CLPlacemark *placeMark = [placemarks firstObject];
            if (placeMark) {
                self.place = [NSString stringWithFormat:@"%@%@%@%@",placeMark.administrativeArea,placeMark.locality,placeMark.subLocality,ZYIsNullOrEmpty(placeMark.thoroughfare)?@"":placeMark.thoroughfare];
            }
        }
    }];
}

//定位失败时调用
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
    [locationManager startUpdatingLocation];
}

IOS自动化定位方式

元素属性的介绍
type:元素类型,与className作用一致,如:XCUIElementTypeStaticText
value: 一般不用
name:元素的文本内容,可用作 AccessibilityId定位方式,如:测试420班级群
label:*大多数情况下,与 name 作用一致
enabled:元素是否可点击,一般值为true或者false
visible:元素是够可见,一般值为true或者false

1.findElementByIosNsPredicate

这个定位方式需要用java-client -5.0.版本,4.x的版本没有这个定位方式

driver.findElementByIosNsPredicate(“value ==’11′”).sendKeys(“[email protected]”);

driver.findElementByIosNsPredicate(“name == ‘login_default_icon'”).click();

driver.findElementByIosNsPredicate(“value ==’请输入登录密码'”).sendKeys(“1111”);

driver.findElementByIosNsPredicate(“name == ‘login_default_icon'”).click();

driver.findElement(By.id(“登录”)).click();

仅支持 iOS 10或以上,可支持元素的单个属性和多个属性定位,推荐使用。
一种属性:MobileBy.iOSNsPredicateString(“type == ‘XCUIElementTypeButton'”)
两种属性:MobileBy.iOSNsPredicateString(“type == ‘XCUIElementTypeButton’ AND label == ‘更多信息'”)
具体 iOSNsPredicate语法结构可查看官方文档,或查看的这个帖子:iOS 定位方式 iOSNsPredicateString 详解。

2.

Appium 的定位方式种类
我说的定位方式都是基于我自己亲测过,没使用或比较少用的就在这里不列举了,如有错误的地方,请多多包涵!常用的定位方式(仅限 Android 和 iOS 两种系统)有 className、id、xpath、AccessibilityId、AndroidUIAutomator、iOSNsPredicateString、iOSClassChain、IosUIAutomation等

className
使用元素的className属性定位,支持:Android 和 iOS,推荐使用。
MobileBy.className(“XCUIElementTypeButton”)

id
使用元素的Resource Id属性定位,支持:Android,仅支持 Android 4.3或以上,推荐使用。反正我没有在 iOS 用过,大家有正确使用过的例子,可以分享一下。
MobileBy.id(“package.name:id/android”)

xpath
支持:Android 和 iOS。但由于 iOS 10开始使用的 XCUITest 框架原声不支持,定位速度很慢,所以官方现在不推荐大家使用,也有其他替代的定位方式可使用。
1.使用*对路径定位,如截图所显示的 xpath 路径
MobileBy.xpath(“className/className/className/className”)
2.使用相对路径定位
MobileBy.xpath(“//className”)
3.通过元素的索引定位
MobileBy.xpath(“//className[index]”)
4.通过元素的属性定位
一种属性:MobileBy.xpath(“//className[@label=’更多信息’]”)
两种属性:MobileBy.xpath(“//className[@label=’更多信息’][@isVisible=’1′]”)
部分属性(*强大):MobileBy.xpath(“//className[contains(@label,’更多’)]”)

AccessibilityId
替代以前的name定位方式,推荐使用。
在 Android 上,主要使用元素的content-desc属性,如该属性为空,不能使用此定位方式。
在 iOS 上,主要使用元素的label或name(两个属性的值都一样)属性进行定位,如该属性为空,如该属性为空,也是不能使用该属性。
MobileBy.AccessibilityId(“更多信息”)

AndroidUIAutomator
仅支持 Android 4.2或以上,可支持元素的单个属性和多个属性定位,推荐使用。
一种属性:MobileBy.AndroidUIAutomator(“new UiSelector().text(\”发送\”)”)
两种属性:MobileBy.AndroidUIAutomator(“new UiSelector().text(\”发送\”).clickable(true)”)
元素的所有属性都可用做定位,功能非常强大,且速度很快。

iOSNsPredicateString
仅支持 iOS 10或以上,可支持元素的单个属性和多个属性定位,推荐使用。
一种属性:MobileBy.iOSNsPredicateString(“type == ‘XCUIElementTypeButton'”)
两种属性:MobileBy.iOSNsPredicateString(“type == ‘XCUIElementTypeButton’ AND label == ‘更多信息'”)
具体 iOSNsPredicate语法结构可查看官方文档,或查看的这个帖子:iOS 定位方式 iOSNsPredicateString 详解。

iOSClassChain
仅支持 iOS 10或以上,这是 github 的 Mykola Mokhnach 大神开发,仅限在 WebDriverAgent 框架使用,用于替代 xpath 的,但使用一阵子后,感觉灵活性没有 xpath 和 iOSNsPredicate 好,应该还不完善吧。具体使用方法,请见:https://github.com/appium/appium-xcuitest-driver/pull/391 。
MobileBy.iOSClassChain(‘XCUIElementTypeWindow[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeNavigationBar[1]/XCUIElementTypeOther[1]/XCUIElementTypeButton[2]’)

IosUIAutomation
仅支持 iOS 9.3或以下,是 iOS 旧框架 UIAutomation 的定位方式,现在基本上很少使用,这个定位类型同样可使用 iOS 谓词进行定位,详细可参考:iOSNsPredicate

总结:
以上这个多定位方式,很少说全部用完。根据我的经验,推荐使用:Android:AndroidUIAutomator > className = id = AccessibilityId > xpath。iOS:iOSNsPredicateString > className = AccessibilityId

 

iOS appium元素定位,封装时候使用MobileBy和By结合

iOS:

1 from selenium.webdriver.common.by import By
2 class MobileBy(By):
3     IOS_PREDICATE = ‘-ios predicate string’
4     IOS_UIAUTOMATION = ‘-ios uiautomation’
5     IOS_CLASS_CHAIN = ‘-ios class chain’
6     ANDROID_UIAUTOMATOR = ‘-android uiautomator’
7     ANDROID_VIEWTAG = ‘-android viewtag’
8     ANDROID_DATA_MATCHER = ‘-android datamatcher’
9     ACCESSIBILITY_ID = ‘accessibility id’
10     IMAGE = ‘-image’
11     CUSTOM = ‘-custom’

android:

1 class By(object):
2     “””
3     Set of supported locator strategies.
4     “””
5
6     ID = “id”
7     XPATH = “xpath”
8     LINK_TEXT = “link text”
9     PARTIAL_LINK_TEXT = “partial link text”
10     NAME = “name”
11     TAG_NAME = “tag name”
12     CLASS_NAME = “class name”
13     CSS_SELECTOR = “css selector”

综合封装:

1 def find_element(self, *loc):
2     try:
3         # 元素可见时,返回查找到的元素;以下入参为元组的元素,需要加*
4         WebDriverWait(self.driver, 30).until(lambda driver: driver.find_element(*loc).is_displayed())
5         return self.driver.find_element(*loc)
6
7     except selenium.common.exceptions.NoSuchElementException:
8         # logging.warning(‘Can not find element: %s’ % loc[1])
9         self.log.myloggger(‘Can not find element: %s’ % loc[1], flag=2)
10         raise
11     except selenium.common.exceptions.TimeoutException:
12         self.log.myloggger(‘Can not find element: %s’ % loc[1], flag=2)
13         raise
14
15 def find_elements(self, *loc):
16     try:
17         WebDriverWait(self.driver, 30).until(lambda driver: driver.find_elements(*loc))
18         return self.driver.find_elements(*loc)
19
20     except selenium.common.exceptions.NoSuchElementException:
21         # logging.warning(‘Can not find element: %s’ % loc[1])
22         self.log.myloggger(‘Can not find element: %s’ % loc[1], flag=2)
23         self.get_screenshot()
24         raise
友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速