记 Swift async 替换 Combine 实现用户行为计时. - V2EX
请不要在回答技术问题时复制粘贴 AI 生成的内容
andyJado

记 Swift async 替换 Combine 实现用户行为计时.

  •  
  •   andyJado
    AndyJado Jun 26, 2022 1260 views
    This topic created in 1416 days ago, the information mentioned may be changed or developed.

    前言

    全身心写几个月 swift 了, 第一次不依赖谷歌完全用自己的思路解决的一个小问题, 和大家分享一下, 希望大家能说些难听的话.♀

    背景:

    聊天软件几乎都有输入框, 配合键盘的唤出, 用于区分编辑状态, 十分符合人类直觉.

    微信等聊天软件的通用逻辑是:

    1. 轻点唤醒键盘.
    2. 等键盘完全唤醒, 轻点(或下拉) 撤走键盘.

    可是. 等待键盘的过程, 是一个动画, 用户只能看, 无法干预. 有那么半秒钟, 我的手机不听我的了, 自己玩了.

    简单来说: “不够丝滑”.

    「推敲」是允许你这样做的:

    https://user-images.githubusercontent.com/101876416/175808976-cd1a4760-609a-497c-afa9-c12c14b1a1f1.mov

    解耦出来看这并不难, 但「推敲」的一个核心功能是精准记录单个话语的编辑时长, 如何在暴力驾驶中依然完成精确的编辑计时呢?

    聚焦:

    丝滑的极致是一切不更新到视图上的进程都不上主线程. 丝滑的代价是一切视图上的进程随时能被干预

    最初的实现采用的 Combine 框架, 但我的嗅觉告诉我 Combine 迟早会被弃用, 借这个机会替换掉,只 import swiftUI 和 os.log.

    看见了钉子, 选好锤子, 下面就是砸.

    思路:

    划拉一块内存, 登记为 actor, 叫计时工. 予左手右手各一把章. 用户唤起键盘时左手戳一下, 键盘时他右手戳一下, 用户提交话语的时候双手一拍, 返回总时长.

    实现:

    计时工入职培训:

    **actor** TimingManager { **private** **var** timeStack:[(Date,Date)] = [] **private** **var** aStart: Date? **func** onFocus() { aStart = Date() logger.debug("onFocus()") } **func** endFocus() { **if** **let** left = aStart { timeStack.append((left,Date())) aStart = **nil** logger.debug("endFocus!") } } **func** handClose() -> Int { **guard** !timeStack.isEmpty **else** {**return** 0} logger.debug("\(**self**.timeStack.debugDescription)") **var** sec: Double = 0 **for** hand **in** timeStack { sec += hand.1.timeIntervalSince(hand.0) } clearHand() **return** Int(sec) } **func** clearHand() { timeStack.removeAll() } } 

    计时工的日常工作, 追踪键盘是否抬起.

    .onChange(of: focuing) { focuing **in** **switch** focuing { **case** **true**: Task { **await** viewModel.timeAcotr.onFocus() typerOffset = -340 } **case** **false**: Task { **await** viewModel.timeAcotr.endFocus() typerOffset = 0 } } } 

    计时工的汇报工作:

     **func** submitted() { **if** aword.text == "" { Task { **await** timeAcotr.clearHand() } aword = Aword() } **else** { Task {@MainActor **in** **await** timeAcotr.endFocus() aword.secondSpent += **await** timeAcotr.handClose() withAnimation { wordsPool.append(aword) } aword = Aword) } } } 

    最后

    我觉得作为一个产品「推敲」已经挺棒了的, 至少已经改善我生活了.

    但我甚至不敢在这里 po 个链接.

    agagega
        1
    agagega  
       Jun 26, 2022
    Combine 是 SwiftUI 的核心呀,为什么会被弃用呢
    About     Help     Advertise     Blog     API     FAQ     Solana     3279 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 46ms UTC 14:12 PVG 22:12 LAX 07:12 JFK 10:12
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86