iOS 测试 wda 成功让我的手机变成了一块砖 o (╥﹏╥) o

cmlanche · 2021年01月12日 · 最后由 cmlanche 回复于 2021年01月29日 · 5491 次阅读

相关资料

wda 的所有接口,我已整理到文档:https://documenter.getpostman.com/view/1837823/TVmMhJNB,对这些 http 接口的 java 封装,我已开源到公司的开源库:https://github.com/tal-tech/wda-java-client,欢迎 star、fork,关于对 wda 的了解和使用,请看我这篇文章:https://testerhome.com/articles/27059

问题总结

  1. 使用 wda 默认的拖拽接口,即/session/{{sessionId}}/wda/dragfromtoforduration,会发现拖动速度很快,以至于有惯性导致滑动过多
  2. 更改 wda 的拖拽接口调用方式,即采用 XCUICoordinate 的(**void**)pressForDuration:(NSTimeInterval)duration thenDragToCoordinate:(XCUICoordinate *)otherCoordinate withVelocity:(XCUIGestureVelocity)velocity thenHoldForDuration:(NSTimeInterval)holdDuration这个方法来拖动,结果是,不管速度设置多大,最终都会导致手机卡主,并且卡死手机,即手机无法正常接收点击、滑动等操作,让你的手机变成一块砖!(我已经成功把自己的手机和公司的手机都变成砖头啦,好在有强制重启,强制重启按键都恢复了)

现在问题来了,在 iOS 上有什么办法能够稳定拖动的方法吗?我看 wda 已经不行了,求解决方案 ~~~

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 11 条回复 时间 点赞

似乎 dragfromtoforduration 这个方法会 hang 住,以前的版本都会有这个问题

恒温 回复

dragfromtoforduration 这个方法不会,下面是这个方法的源码:

+ (id<FBResponsePayload>)handleDragCoordinate:(FBRouteRequest *)request
{
  FBSession *session = request.session;
  CGPoint startPoint = CGPointMake((CGFloat)[request.arguments[@"fromX"] doubleValue], (CGFloat)[request.arguments[@"fromY"] doubleValue]);
  CGPoint endPoint = CGPointMake((CGFloat)[request.arguments[@"toX"] doubleValue], (CGFloat)[request.arguments[@"toY"] doubleValue]);
  NSTimeInterval duration = [request.arguments[@"duration"] doubleValue];
  XCUICoordinate *endCoordinate = [self.class gestureCoordinateWithCoordinate:endPoint application:session.activeApplication shouldApplyOrientationWorkaround:isSDKVersionLessThan(@"11.0")];
  XCUICoordinate *startCoordinate = [self.class gestureCoordinateWithCoordinate:startPoint application:session.activeApplication shouldApplyOrientationWorkaround:isSDKVersionLessThan(@"11.0")];
  [startCoordinate pressForDuration:duration thenDragToCoordinate:endCoordinate];
  return FBResponseWithOK();
}

执行拖动的是 [startCoordinate pressForDuration:duration thenDragToCoordinate:endCoordinate];,但是这个会有惯性,无法控制速度,我发现有个方法叫:- (void)pressForDuration:(NSTimeInterval)duration thenDragToCoordinate:(XCUICoordinate *)otherCoordinate withVelocity:(XCUIGestureVelocity)velocity thenHoldForDuration:(NSTimeInterval)holdDuration;,这个方法可以控制速度,滑动完成后可以 hold 指定时间,如下图所示:

这个方法执行拖动后,会一直 hang 住某个地方,其他滑动惦记都难以被响应

仅楼主可见
Wei Chuang 回复

可以哦

仅楼主可见
Wei Chuang 回复

确实获取不到,超时没响应。可能这个界面元素太多了

Wei Chuang 回复

你把超时时间设置更长一些试试,比如 10 分钟

仅楼主可见
cmlanche 回复

设置超过时间,在 wda 里搜索并设置这个参数即可 FBSnapshotTimeout 或者 customSnapshotTimeout

可以 自定义手势操作 (TouchActions) 的呀

拖拽动作拆解下来, 其实就是 第一次按住不松开, 然后进行移动, 结束移动后再松开

我也用 Golang 实现了 WDA 的接口
拖拽手势 的实现用在了 手势密码

👇 这里有当时的实现代码
https://github.com/electricbubble/gwda-ext-opencv/blob/7052a95b7dbc8420ece25457965916f9c85cb1fa/gesture.go#L26-L40

func (dExt *DriverExt) GesturePassword(pathname string, password ...int) (err error) {
    var rects []image.Rectangle
    if rects, err = dExt.FindAllImageRect(pathname); err != nil {
        return err
    }

    sort.Slice(rects, func(i, j int) bool {
        if rects[i].Min.Y < rects[j].Min.Y {
            return true
        } else if rects[i].Min.Y == rects[j].Min.Y {
            if rects[i].Min.X < rects[j].Min.X {
                return true
            }
        }
        return false
    })

    touchActions := gwda.NewTouchActions(len(password)*2 + 1)
    for i := range password {
        x, y, width, height := dExt.MappingToRectInUIKit(rects[password[i]])
        x = x + width*0.5
        y = y + height*0.5

        if i == 0 {
            touchActions.Press(gwda.NewTouchActionPress().WithXYFloat(x, y)).
                Wait(0.2)
        } else {
            touchActions.MoveTo(gwda.NewTouchActionMoveTo().WithXYFloat(x, y)).
                Wait(0.2)
        }
    }
    touchActions.Release()

    return dExt.PerformTouchActions(touchActions)
}
雷系泡泡 回复

是个好思路,我研究下

12楼 已删除
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册