在UIKit中使用Combine验证并提交表单

2024-02-22

我正在使用 Storyboard(UIKit) 构建表单。我有 4 个输入字段,当它有效时,我会将数据提交到 UI 并在 UI 上显示响应。我创建了一个 ViewModel 并在其中添加了验证代码。以下是我的验证代码:

@Published public var firstName = ""
    @Published public var lastName = ""
    @Published public var phoneNumber = ""
    @Published public var emailAddress = ""    
var isFirstNameValidPublisher: AnyPublisher<Bool, Never> {
        $firstName
            .map { name in
                return name.count >= 3
            }
            .eraseToAnyPublisher()
    }
    
    var isLastNameValidPublisher: AnyPublisher<Bool, Never> {
        $lastName
            .map { name in
                return name.count >= 3
            }
            .eraseToAnyPublisher()
    }
    
    var isUserEmailValidPublisher: AnyPublisher<Bool, Never> {
          $emailAddress
              .map { email in
                  let emailPredicate = NSPredicate(format:"SELF MATCHES %@", "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}")
                  return emailPredicate.evaluate(with: email)
              }
              .eraseToAnyPublisher()
      }
      
      var isPhoneNumberValidPublisher: AnyPublisher<Bool, Never> {
          $phoneNumber
              .map { phoneNumber in
                  return phoneNumber.count >= 8
              }
              .eraseToAnyPublisher()
      }
    
    public func isValidForm(firstName: String, lastName: String, phoneNum: String, emailAddress: String, isConsent: Bool) -> AnyPublisher<Bool, Never> {
        self.firstName = firstName
        self.lastName = lastName
        self.phoneNumber = phoneNum
        self.emailAddress = emailAddress
        
        return Publishers.CombineLatest4(
          isFirstNameValidPublisher,
          isLastNameValidPublisher,
          isUserEmailValidPublisher,
          isPhoneNumberValidPublisher)
            .map { isFirstNameValid, isLastNameValid, isPhoneNumberValid, isEmailValid in
                return isFirstNameValid && isLastNameValid && isPhoneNumberValid && isEmailValid && isConsent
            }
            .eraseToAnyPublisher()
    }

我试图在我的 ViewController 中单击提交按钮时使用它,如下所示:

cancellable = dependencies.leadConsumptionUseCase.isValidForm(firstName: firstNameTextView.text, lastName: lastNameTextView.text, phoneNum: phoneNumberTextView.text, emailAddress: emailTextView.text, isConsent: true).collect().sink(receiveCompletion: { completion in
        print("completed")
        print(completion)
    }, receiveValue: { res in
        print("result")
        print(res)
    })

我能够验证 ViewModel 中的字段,但不知怎的,我在 ViewController 中没有得到任何响应。 另外我不知道应该如何以及在哪里添加 api 调用。我已经创建了另一个服务类,其中有一个 api 调用,它将返回作为 AnyCancellable 的响应。 大多数相关示例都使用 SwiftUI,但我没有使用 SwiftUI。

Edit:从 isValidForm 函数调用中删除收集后,我能够获得响应,但现在它会出现多次。因此,我的 api 调用会执行多次。


下面有一个如何使用此代码的工作示例。

isValidForm()现在只返回发布者,它不接受值。您尝试验证的值通过您构建的四个流传入。

正如我所建议的,我已经包括了.print运算符,以便您可以在调试输出中看到每个流如何参与验证。

在操场的主体中,我一次将一个值发送到四个流中。当发送每个值时,isValidForm()发布者发出false值,直到所有字段都已发送。然后它会发出一个true让您知道所有四个字段都有有效值。

import UIKit
import Combine

class Form : ObservableObject {
    @Published public var firstName = ""
    @Published public var lastName = ""
    @Published public var phoneNumber = ""
    @Published public var emailAddress = ""

    var isFirstNameValidPublisher: AnyPublisher<Bool, Never> {
            $firstName
                .map { name in
                    return name.count >= 3
                }
                .eraseToAnyPublisher()
        }
        
        var isLastNameValidPublisher: AnyPublisher<Bool, Never> {
            $lastName
                .map { name in
                    return name.count >= 3
                }
                .eraseToAnyPublisher()
        }
        
        var isUserEmailValidPublisher: AnyPublisher<Bool, Never> {
              $emailAddress
                  .map { email in
                      let emailPredicate = NSPredicate(format:"SELF MATCHES %@", "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}")
                      return emailPredicate.evaluate(with: email)
                  }
                  .eraseToAnyPublisher()
          }
          
          var isPhoneNumberValidPublisher: AnyPublisher<Bool, Never> {
              $phoneNumber
                  .map { phoneNumber in
                      return phoneNumber.count >= 8
                  }
                  .eraseToAnyPublisher()
          }
        
        public func isValidForm() -> AnyPublisher<Bool, Never> {
            return Publishers.CombineLatest4(
                isFirstNameValidPublisher.print("first name"),
              isLastNameValidPublisher.print("last name"),
              isUserEmailValidPublisher.print("email"),
              isPhoneNumberValidPublisher.print("phone"))
                .map { isFirstNameValid, isLastNameValid, isPhoneNumberValid, isEmailValid in
                    return isFirstNameValid && isLastNameValid && isPhoneNumberValid && isEmailValid
                }
                .print("isValidForm")
                .eraseToAnyPublisher()
        }
}

let form = Form()
let validWatcher = form.isValidForm().sink { isValid in
    print("Is the form valid?: \(isValid)")
}
form.firstName = "Scott"
form.lastName = "Thompson"
form.phoneNumber = "(123) 555-1234}"
form.emailAddress = "[email protected] /cdn-cgi/l/email-protection"
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在UIKit中使用Combine验证并提交表单 的相关文章

  • 如何使用 SwiftUI 创建自定义滑块?

    我可以使用 SwiftUI 创建滑块 但无法更改滑块的样式 如下图所示 问题 我无法在 SwiftUI 中找到任何选项来更改滑块样式 注意 我想仅使用 SwiftUI 创建它 我已经在 Swift 中使用 创建了这个滑块 https git
  • 快速重写函数错误

    我有一个结构 struct ErrorResultType ErrorType var description String var code Int 和一个协议 protocol XProtocol func dealError erro
  • 为什么我的自定义类没有出现在 Interface Builder 的下拉列表中?

    我正在使用 Interface Builder 和 Storyboards 来构建我的应用程序 我正在尝试将我的源代码连接到我的UIViewController在 Storyboard 中 但我的类都没有显示在 自定义类 下拉菜单中 这种情
  • 依赖于 pod 的 Swift 通用框架

    我正在开发一个依赖于 Alamofire 的小型 Swift 框架 我将它用作属于同一工作区的应用程序的嵌入式框架 并且它运行良好 当我想构建一个具有总体目标的通用框架时 问题就出现了 然后 当执行脚本生成框架时 它失败并显示消息No su
  • 在 Swift 中动态设置 Dictionary 的属性

    我正在尝试根据字典中的值在类上设置一些属性 目前我正在这样做 let view UIView UIView if let hidden Bool self props hidden as Bool view hidden hidden if
  • CloudKit 和 Core 在设备之间同步数据

    我创建了一个简单的Notes应用程序基于Core data 现在我想在用户设备之间添加同步 以及我读过的所有文章 this https www raywenderlich com 134694 cloudkit tutorial getti
  • 当前图像选择模式会擦除 UI

    我下面有一个非常简单的视图控制器 UI 实际上只是一个带有底部标签栏的按钮 import UIKit class ImageAdderViewController UIViewController override func viewDid
  • 我可以在 Swift 3 项目中使用 Swift 2.3 框架吗?

    在我的项目中 我将所有私有 swift 2 3 文件迁移到 swift 3 我想使用用 swift 2 3 编写的遗留框架 直到它们有 swift 3 版本 我尝试添加 使用旧版 Swift 版本 是 清除 构建我的项目 但我仍然遇到一些麻
  • “不能在集合中使用 in/contains 运算符”

    单击搜索栏时出现此错误 由于未捕获的异常 NSInvalidArgumentException 而终止应用程序 原因 无法在集合中使用 in contains 运算符 Assignment 4 SearchResult studentID
  • SpriteKit - 对多个 SKNode 上运行的多个 SKAction 进行排序

    我非常了解 SKAction API 但在多个节点上运行顺序代码时我无法获得良好的代码 这是示例代码 简化 import SpriteKit class GameScene SKScene weak var node1 SKNode wea
  • Xcode 11 - 在 Catalyst Swift 中禁用调整大小模式

    We are 将我们基于 Swift 的 iOS 应用程序转换为 Mac兼容使用Catalyst在 Xcode 11 中 当用户使用时 我们在 UI 中面临一个问题resize应用程序窗口 那么我们可以禁用调整大小模式并为应用程序窗口提供修
  • 解析迁移到 mLabs 和 Heroku 的错误

    我至少一年前将解析数据库迁移到 Mlabs 从那时起我就一直在开发该应用程序 解析仪表板表示我已成功迁移 Mlab 和 Parse 都收到了数据库的更新 然而 在过去一两周内 该应用程序不再经过登录页面 没有调整代码 这是服务器问题 以下是
  • 如何将 SCNPlane 颜色更改为透明颜色

    我正在开发一个 ARKit 项目 在水平面上点击时需要波纹动画效果 为此 我采用了 UIView 对象并将其作为 SCNPlane 对象材料的内容传递 我已将波纹动画添加到 UIView 对象 一切正常 但我无法将 SCNPlane 颜色更
  • 视频中的图像/文本叠加 swift

    我正在使用 swift 在视频中使用图像叠加来实现水印效果 我正在使用AVFoundation为此 但不知何故我没有成功 以下是我的覆盖图像 文本的代码 let path NSBundle mainBundle pathForResourc
  • UIImageWriteToSavedPhotosAlbum 选择器语法问题

    努力让 UIImageWriteToSavedPhotosAlbum 快速工作https developer apple com library ios documentation UIKit Reference UIKitFunction
  • 如何删除以前的 ViewController

    我是一名学生 对编程还很陌生 我正在尝试在业余时间学习 Objective C Swift 我使用 spriteKit 和 swift 制作了一个游戏 有多个菜单 场景 我正在尝试从一个视图控制器转换到另一个视图控制器 为此 我使用了以下代
  • 电影播放完毕后关闭 AVPlayer

    我正在制作一个简单的 iPad 应用程序 按下按钮即可播放电影 电影播放 电影结束后我想关闭 AVPlayerView 以便它返回主屏幕 目前 当视频结束时 它停留在最后一帧 我现在的 ViewController Swift import
  • 从 firebase swift 读取数据

    我正在尝试从 firebase 数据库检索数据 但是当我运行代码时 它没有显示任何内容 但没有显示错误 我从Firebase手册中得到了这段代码 顺便说一句 我很确定路径是正确的 let ref FIRDatabase database r
  • 从 HealthKit 获取昨天的步数

    我正在构建一个供个人使用的应用程序 目前我正致力于如何从 healthkit 中准确获取昨天的步数 然后从那里将其放入变量中 我知道应该很容易 我有一个 HealthKitManager 类 它从视图内部调用该函数 然后将其附加到同一视图中
  • 如何比双击更快地识别单击?

    我有一个UITableView与我添加单击的行and双击手势 let doubleTap UITapGestureRecognizer target self action doubleTap doubleTap numberOfTapsR

随机推荐

  • Azure Web 应用程序与 Azure 移动应用程序

    我今天创建了一个Azure Web应用程序 它在设置中有一个移动部分 其中包含推送通知 移动身份验证等 您甚至可以下载移动客户端应用程序的源代码 我知道这曾经是移动应用程序 移动服务 的一部分 我创建了一个 Azure 移动应用程序来与 W
  • 识别活动网络接口

    在 NET 应用程序中 如何识别使用哪个网络接口与给定 IP 地址进行通信 我在具有多个网络接口 IPv4 和 v6 的工作站上运行 并且我需要获取用于流向给定数据库服务器的 正确 接口的地址 最简单的方法是 UdpClient u new
  • Allure Framework:TestNG 适配器错误地将 @AfterMethod 放置在报告中

    我正在使用 allure V1 4 8 TestNG 看起来 TestNG 适配器错误地将 AfterMethod 放置在报告中 基本上它将 AfterMethod 从测试用例放入下一个测试用例中 这是简单的代码 Step a test1
  • 从 .Net 应用程序打开 Windows 7 帮助 (helpPane.exe)

    我正在尝试从 Net 表单应用程序打开 Windows 7 帮助到特定书签 例如在打印机安装时 我尝试以与打开控制面板小程序相同的方式打开它 在下面的示例中返回和恢复 ProcessStartInfo startInfo new Proce
  • 当页面滚动到顶部时,Next.js 链接不会呈现

    我有一个像这样的组件 const Milestone props gt const path disabled index rest props if disabled return
  • 生成一定范围内的唯一随机数

    我需要在一定范围内生成随机的唯一数字 我该怎么做 我可以通过以下方式生成随机数 generator arr x rand min max len count arr flag 0 for i 0 i lt len i if flag 1 g
  • 如何在javascript中打印所有百分比超过70%的学生姓名?

    我在用json rule engine https www npmjs com package json rules engine https www npmjs com package json rules engine我有一份学生名单
  • 在 R 中向量化循环

    必须有一种简单的方法来向量化 R 中的以下循环 但我看不到它 w lt numeric 10 z lt rnorm 20 v lt c sample 1 10 10 sample 1 10 10 Random ordering of c 1
  • jQuery AJAX 提交表单

    我有一张带有姓名的表格orderproductForm以及未定义数量的输入 我想做某种 jQuery get 或 ajax 或类似的东西 通过 Ajax 调用页面 并发送表单的所有输入orderproductForm 我想一种方法是做类似的
  • pyside-uic 在哪里?

    我正在尝试使用 Qt Designer 和 pyside uic mydesign ui gt design py 但是 这个程序不存在 我查看了 python 2 7 下的站点包 我看到 pyside lupdate exe pyside
  • 创建项目后如何将 ndk 设置从默认 C++ 工具链更改为 C++14?

    我使用默认的 C 工具链创建了一个 Android 项目 现在 当我尝试包含双簧管上包含 C 14 功能的示例项目的代码片段时 我不断收到错误 因此 我尝试包含代码来创建模板 但现在它使我的代码变得混乱 并转储了我不希望有的声明 我尝试提及
  • 使用 Meteor.settings 功能

    Meteor 最近添加了一个全新的Meteor 设置 http docs meteor com meteor settings meteor settings对象从 v0 5 4 开始 并且以一种极其烦人的方式 没有在他们的文档中正确解释如
  • 如何将一些 XML 元素包含在边界框中?

    我想在此处附上一对复选框和单选按钮 在矩形或 边界框 中 使其看起来像这样 当然 但不那么难看 如何以以下 XML 作为起点来做到这一点
  • GeoViews:具有 matplotlib 后端的 GeoDataFrames 的分类图例

    已安装的软件包 geoviews 1 9 1 matplotlib 3 4 2 我正在尝试做什么 For the Bokeh后端通过添加分类图例GeoViews是通过代理艺术家完成的 如中所述卡特里娜飓风路径示例 https geoview
  • UITableViewCell 的 NSTextAttachment 异步加载图像

    在异步线程或图像缓存库 如 SDwebimage 中动态加载图像 下面的代码是我尝试过的 从网络获取图像后它不会重新绘制 let mutableAttributedString NSMutableAttributedString if le
  • C 库的 C++/CLI 类包装器 - 回调

    我正在使用 C CLI 包装 C 库 C 库设计为从非托管 C 类中使用 这意味着库函数接受 C 对象指针 然后在回调中提供该指针 这使得回调代码能够将请求重定向到调用 C 对象中的适当事件函数 实际功能相当复杂 因此我将问题空间简化为几个
  • 当尝试在 GNU Radio 中使用我的 USRP 时,我收到“未找到 -----> 的设备”错误

    当尝试执行使用 USRP 的 GNU Radio 程序时 我收到错误回溯 该错误 在 Python 中 通常以以下内容结尾 self u uhd usrp source device addr args stream args uhd st
  • 在 PL/SQL 块内的 SQL 中使用嵌套表变量/集合

    我首先创建一个address type object CREATE TYPE address type AS OBJECT line1 VARCHAR2 100 line2 VARCHAR2 100 line3 VARCHAR2 100 c
  • 如何发送格式在运行时确定的 gRPC 消息?

    我主要对用 Java 来做这件事感兴趣 但是看到任何语言的解决方案都会有帮助 根据我正在阅读的各种文档 gRPC 的默认工作流程是 Write a proto file 从该文件生成客户端和 或服务器代码 编写您的程序并将其与生成的代码一起
  • 在UIKit中使用Combine验证并提交表单

    我正在使用 Storyboard UIKit 构建表单 我有 4 个输入字段 当它有效时 我会将数据提交到 UI 并在 UI 上显示响应 我创建了一个 ViewModel 并在其中添加了验证代码 以下是我的验证代码 Published pu