Swift - 解码/编码具有不同类型的泛型数组

2023-12-26

如何解码/编码不同泛型类型的数组?

我有一个数据结构,它具有符合协议的属性Connection,因此我使用泛型:

// Data structure which saves two objects, which conform to the Connection protocol
struct Configuration<F: Connection, T: Connection>: Codable {
    var from: F
    var to: T
    private var id: String = UUID.init().uuidString

    enum CodingKeys: String, CodingKey {
        case from, to, id
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.from = try container.decode(F.self, forKey: .from)
        self.to = try container.decode(T.self, forKey: .to)
        self.id = try container.decode(String.self, forKey: .id)
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(from, forKey: .from)
        try container.encode(to, forKey: .to)
        try container.encode(id, forKey: .id)
    }
}

protocol Connection: Codable {
    var path: String { get set }
}


// Two implementations of the Connection protocol
struct SFTPConnection: Connection, Codable {
    var path: String
    var user: String
    var sshKey: String
}

struct FTPConnection: Connection, Codable {
    var path: String
    var user: String
    var password: String
}

当我知道连接类型时,这很好用F and T是。但我有一些情况,我想加载配置,但不知道哪种类型F and T are.

public static func load<F: Connection, T: Connection>(for key: String) throws -> Configuration<F, T>? {
    // Load from UserDefaults
    guard let configurationData = defaults.object(forKey: key) as? Data else {
        return nil
    }

    // Decode
    guard let configuration = try? PropertyListDecoder().decode(Configuration<F, T>.self, from: configurationData) else {
        return nil
    }

    return configuration
}

// OR

func loadAll<F:Connection, T: Connection>() -> [String: Configuration<F, T>]? {
    return UserDefaults.standard.dictionaryRepresentation() as? [String: Configuration<F, T>]
}

在上述情况下F and T可以是任何未知类型,符合Connection协议。所以上面的函数不起作用,因为我需要指定一个特定的类型F and T当调用该函数时,我不知道。

在第二个函数中,F实际上可能有不同的类型。这就是困难所在。我想我需要以某种方式存储类型F and T也在用户默认值中,然后在decode and encode函数(从而丢弃泛型)。但我不知道如何优雅地做到这一点。

我将不胜感激任何关于如何解决这个问题的想法!


以下解决方案解决了我在使用泛型时遇到的所有问题,并且不知道泛型的具体类型Connection。解决问题的关键是

  1. 保存 a 的类型Connection实施本身的实施和
  2. Using superEncoder and superDecoder编码/解码from and to特性。

这是解决方案:

import Foundation

protocol Connection: Codable {
    var type: ConnectionType { get }
    var path: String { get set }
}


struct LocalConnection: Connection {
    let type: ConnectionType = ConnectionType.local

    var path: String
}


struct SFTPConnection : Connection {
    let type: ConnectionType = ConnectionType.sftp

    var path: String
    var user: String
    var sshKey: String

    init(path: String, user: String, sshKey: String) {
        self.path = path
        self.user = user
        self.sshKey = sshKey
    }
}


struct FTPConnection: Connection {
    let type: ConnectionType = ConnectionType.ftp

    var path: String
    var user: String
    var password: String
}


struct TFTPConnection: Connection {
    let type: ConnectionType = ConnectionType.tftp

    var path: String
}




enum ConnectionType : Int, Codable {
    case local
    case sftp
    case ftp
    case tftp

    func getType() -> Connection.Type {
        switch self {
        case .local: return LocalConnection.self
        case .sftp: return SFTPConnection.self
        case .ftp: return FTPConnection.self
        case .tftp: return TFTPConnection.self
        }
    }
}




struct Configuration {
    var from : Connection
    var to : Connection
    private var id = UUID.init().uuidString

    var fromType : ConnectionType { return from.type }
    var toType : ConnectionType { return to.type }

    init(from: Connection, to: Connection) {
        self.from = from
        self.to = to
    }
}


extension Configuration : Codable {

    enum CodingKeys: String, CodingKey {
        case id, from, to, fromType, toType
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)

        self.id = try container.decode(String.self, forKey: .id)

        var type : ConnectionType

        type = try container.decode(ConnectionType.self, forKey: .fromType)
        let fromDecoder = try container.superDecoder(forKey: .from)
        self.from = try type.getType().init(from: fromDecoder)

        type = try container.decode(ConnectionType.self, forKey: .toType)
        let toDecoder = try container.superDecoder(forKey: .to)
        self.to = try type.getType().init(from: toDecoder)
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)

        try container.encode(self.id, forKey: .id)

        try container.encode(self.fromType, forKey: .fromType)
        let fromContainer = container.superEncoder(forKey: .from)
        try from.encode(to: fromContainer)

        try container.encode(self.toType, forKey: .toType)
        let toContainer = container.superEncoder(forKey: .to)
        try to.encode(to: toContainer)
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Swift - 解码/编码具有不同类型的泛型数组 的相关文章

  • 搜索结果中的 Swift 搜索结果控制器连接到另一个视图控制器

    Problem 我有一个表格视图 用户可以滚动查找某些内容或使用搜索栏 搜索栏不是使用 StoryBoard 创建的 我的观点有一个UISearchController处理搜索栏和搜索结果更新 我遇到的问题是 自从我SearchResult
  • 从方案加载 url 第一次未处理 - appdelegate 与 viewcontroller

    我的应用程序已成功打开并将参数 从 URL 方案 即 myApp sometextToPrint 设置为AppDelegate类 但每当我想处理它们时 当从该 URL 打开应用程序时 它就会在第一次失败 我在前台检查器中有一个应用程序 它调
  • 获取 iOS Swift 中 UIViewController 的所有列表

    有没有办法获取 iOS Swift 项目中的所有 UIViewController 我想获取所有 UIViewController 的数组并检查特定的 UIViewController 是否存在 我必须找到项目中是否存在特定的 UIView
  • Swift 3 Web 视图

    所以我刚刚更新到新的Xcode8 and Swift3但现在我的网络视图不起作用 这是我使用的代码 UIWebView loadRequest webView NSURLRequest URL NSURL string http hardw
  • 使用 CommonCrypto 的 Swift AES 加密

    我正在开发一个 iOS 应用程序代码7 1 with 斯威夫特2 1我正在尝试进行简单的加密AES 128 位 and PKCS7填充使用通用加密库 该代码有效 但每次我尝试投射NSData反对NSString然后对于 String 我得到
  • 你能用 Swift 计算一个字符串吗?

    我有一个变量 并且有一个以字符串形式存储在其中的函数 var x func myFunction y Int println y 有没有办法评估字符串并运行函数 No 没有等效的eval https developer mozilla or
  • UTF-8、PHP 和 XML Mysql

    我在解决这个问题时遇到了很大的问题 我有一个编码 latin1 swedish ci 的 mysql 数据库和一个存储名称和地址的表 我正在尝试输出 UTF 8 XML 文件 但在使用以下字符串时遇到问题 Otiv gen它被输出为Otiv
  • 当 SwiftUI 中列表数据源为空时,如何在视图中心显示文本消息?

    struct LandmarkList View var body some View NavigationView List landmarkData landmark in LandmarkRow landmark landmark 我
  • 如何通过反射访问Generic.List的索引?

    好的 我有一个类 我将一个对象作为属性传递 我传递的对象是List
  • Swift MKAnnotationView 旋转

    我试图在坐标更改时旋转我的自定义注释 我可以成功地更改坐标 但尝试了一切方法来旋转它 但没有成功 基本思想是有一个平面并通过旋转设置其方向 这是我的代码 import UIKit import MapKit class CustomPoin
  • 在 iOS Cocoa 静态库项目中使用 Objective-C 代码,在 iOS 应用程序项目中使用 Swift 代码

    我正在寻找一个简单的过程 用于将共享库项目中的 Objective C 代码与应用程序项目中的 Swift 代码相结合 但到目前为止 此序列尚未成功 启动Xcode 6 1 1 创建工作区测试 创建iOS Cocoa Touch静态库项目T
  • 将 swift 结构体转换为 json 字符串

    我正在尝试将我的 swift 结构转换为 json 格式 类似这样的问题似乎有不少 但到目前为止 没有一个解决方案对我有用 这是我的结构 struct Rec Codable var name String var time Int var
  • Swift 中的条件导入

    我有一个在各种应用程序中使用的日志功能 由于我在整个应用程序中使用它 因此也可以方便地进行 Crashlytics 日志记录调用 然而 并非每个应用程序都使用 Crashlytics 在 Objective C 中 您可以使用预处理器条件来
  • Swift 1.2 和 Swift 2.0 中的字符串长度[重复]

    这个问题在这里已经有答案了 在以前版本的 Swift 中 我有以下代码 func myfunc mystr String if mystr utf16Count gt 3 使用最新版本的 Swift 1 2 我现在收到以下错误 utf16C
  • 如何显示启动图像

    我是 iOS 新手 我的 Xcode 版本是 7 2 1 我尝试使用 Swift 在 iOS9 上运行 我的问题是我对如何创建启动屏幕图像感到非常困惑 我发现有很多方法可以为不同版本的 iOS 创建启动屏幕图像 有人可以向我解释一下如何设置
  • 在 Swift 中使用显式对象类型迭代数组

    我有一个数组 let individualScores 75 43 103 87 12 我这样迭代 for score in individualScores 但是 有没有办法显式声明对象类型呢 我认为以后使用自定义对象或其他原因它会派上用
  • Swift - 带循环的多个链 http 请求

    两天以来 我感觉我正在搜索整个网络来解决多个 http 请求的问题 所以我的工作流程如下所示 将图像上传到服务器 响应 XML 格式和任务 ID 使用任务 ID 向服务器发出 GET 请求 以检查该任务的状态 响应 XML 格式 其中状态可
  • 如何在 iOS 11 上的 Swift 中获取 FLAC 文件元数据?

    我需要获取 FLAC 文件的元数据 我尝试了以下代码 let item AVPlayerItem url URL fileURLWithPath path let commonMetadata item asset commonMetada
  • Xcode 6.3 和 Swift:Unicode 实用程序(例如 UCKeyTranslate)不可用?

    我有以下测试代码 import Cocoa import Carbon let x kUCKeyActionDisplay 在 Xcode 6 2 中没有问题 但在 Xcode 6 3 中此代码会引发错误 错误信息是 Use of unre
  • 将 Unmanaged 与 nil 进行比较

    代码是从这篇博客文章复制的 http matthewpalmer net blog 2014 06 21 example ios keychain swift save query http matthewpalmer net blog 2

随机推荐

  • 要包含或包含自动生成的依赖项?

    我喜欢用g MM自动构建我的依赖项的功能 我这样做的方法如下 include ALLOBJ o d d cxx echo making dependencies for lt g MM CXXFLAGS lt o sed i s o g 基
  • 分配时出现 JPEG 错误 #42

    为什么我不能直接将 MemoryStream 分配给图片 下面我发布了两种将 MemoryStream 分配给 TImage 的方法 方法 1 不起作用 方法 2 起作用 为什么 谢谢 山姆 方法 1 此方法返回 JPEG 错误 42 Va
  • jax-ws webservice 的端点始终是 localhost

    我真的需要你的帮助 我读到 jax ws web 服务的 wsdl 将为每个请求动态生成 这样 soap 端点等地址将被调整为请求 url 就我而言 无论是内部请求还是外部请求 地址始终引用 localhost 8080 某人知道我该如何处
  • C++ Linux 最快的时间测量方法(比 std::chrono 更快)?包含基准

    include
  • 为大型 URI 配置 Nginx

    我有一个很大的 URI 我正在尝试配置 Nginx 来接受它 URI参数长度为52000个字符 大小为52kb 我尝试过在没有 Nginx 的情况下访问 URI 效果很好 但是当我使用 Nginx 时 它给了我一个错误 414 请求 URI
  • 如何生成 3 列列表?

    我必须生成一个 3 列的项目列表 类似于此页面上不同群体 主要是银行和金融机构 可以看到的内容 http funds ft com FundDirectory aspx http funds ft com FundDirectory asp
  • 如何将 RDF 文件导入 Apache Solr

    我是 Apache Solr 的新手 我想将 rdf 文件导入 solr 进行索引 我用 google 搜索了它 但没有找到任何有用的东西 请给我一些指示 Solr 接受 JSON 文档 您可以将 RDF 文档转换为JSON LD http
  • 在 Spark mapPartitions 中使用 Java 8 并行流

    我试图了解 Spark 并行性中 Java 8 并行流的行为 当我运行下面的代码时 我期望输出大小为listOfThings与输入大小相同 但事实并非如此 我的输出中有时会缺少一些项目 这种行为并不一致 如果我只是遍历迭代器而不是使用par
  • scala:将 null 分配给原语

    我试图将 null 分配给一个 Double 变量 如下所示 var foo 0 0 foo null 但是 这会出现 null 无法隐式转换为 Double 的错误 所以我这样做 foo null asInstanceOf Double
  • cmake - 链接静态库 pytorch 在构建过程中找不到其内部函数

    我正在尝试使用 cmake 构建一个程序 由于多种原因 必须使用静态库而不是动态库构建程序 并且我需要使用 PyTorch 所以这就是我所做的 下载并安装 PyTorch 静态库 我发现libtorch a在正确的道路上 在 home me
  • Karate UI:通过 CSS 定位文本

    我经常遇到空手道看不到的奇怪的可见页面文本 可能是由于一些我不完全理解的时髦 JS 魔法 Example image shows text on the page generated after clicking on a translat
  • Node.js 和导出的变量

    我正在尝试使用一个脚本来公共存储 全局 变量 而其他脚本可能需要该脚本来查看这些变量 但这似乎不是正确的方法 所以我有一个名为 gamedata js 的脚本 如下所示 var players exports players players
  • 使用 PHP 验证查找恶意 PDF 文件?

    目前 对于文件验证 实施了以下操作 使用 MIME 详细信息 例如 application pdf 进行文件类型验证 验证文件扩展名以及 MIME 详细信息 但有些PDF文件包含JavaScript等恶意脚本来破坏系统 有关 PDF 攻击的
  • 如何将字符串中的特殊字符转换回转义序列?

    假设我有一个像这样的字符串 a tb If I print它 我会看到a b 但我想看看a tb反而 我怎样才能转换我的字符串 让它像这样打印 print repr a tb repr https docs python org 3 lib
  • 登录后重定向到入口网址?

    我正在开发的网站正在使用 Frontpage 模块将匿名用户重定向到登录页面 我知道如何使用触发器来设置登录后重定向的操作 设置为一个特定的网址 但这里有一个问题 我的用户每个都到达不同的入口网址 例如 www mysite Persons
  • 如何检查数组是否至少包含一个对象?

    我想检查数组是否包含对象 我不想比较值只是想检查我的数组是否存在对象 Ex arr a b c normal arr id 1 id 2 array of objects arr id 1 id 2 a b mix values 那么我如何
  • 如何在 C# 中停靠 Windows 窗体?

    我只是想知道是否可以将 Windows 窗体停靠在用户屏幕顶部 我一直在尝试通过手动将表单的位置设置为我想要的坐标来做到这一点 但使用此方法 用户只需通过拖动即可更改表单的位置 我想让表单停靠在屏幕的上部 因为此窗口表单将作为我正在制作的项
  • Google Groups Directory API - 将用户添加到组会引发错误 - PHP

    我一直在尝试将成员添加到我的 Google Apps 群组 我正在尝试使用以下代码 但它会引发错误 不知道做错了什么 include once api client autoload php clientId xxxxxxxxxxxxxxx
  • 查找 XPath 属性名称包含特定字符串

    I have
  • Swift - 解码/编码具有不同类型的泛型数组

    如何解码 编码不同泛型类型的数组 我有一个数据结构 它具有符合协议的属性Connection 因此我使用泛型 Data structure which saves two objects which conform to the Conne