标签: swift-protocols

Swift 通用可序列化协议

我注意到我有很多重复的代码来获取/发送 JSON 到我的应用程序的 API,但唯一不同的是正在(反)序列化的实体。所以我想出了以下设计(为简洁起见,只有 GET 方法):

HTTPClient.swift

func getEntityJSON<T: JSONSerializable>(
    type: T.Type,
    url: String,
    completionHandler: @escaping (_ result: T?,
                                  _ headers: [String: String]?,
                                  _ statusCode: Int?,
                                  _ error: Error?) -> Void) {
    HttpClient.sharedInstance().getJSON(url, completionHandler: { (jsonData, headers, statusCode, error) in
        if let error = error {
            completionHandler(nil, headers, statusCode, error)
        } else {
            if let entityData = jsonData {
                completionHandler(T.fromJSON(data: entityData), headers, statusCode, nil)
            }
        }
    })
}
Run Code Online (Sandbox Code Playgroud)

打算像这样使用它:

HTTPClient.sharedInstance().getEntity(type: Translation, url: url) { (translation, _, _, _) in
    // …
Run Code Online (Sandbox Code Playgroud)

generics swift swift-protocols

1
推荐指数
1
解决办法
67
查看次数

使 @objc 枚举符合 @objc 协议?

是否可以使 @objc 枚举符合 @objc 协议?

下面的枚举显示错误Non-class type 'TestEnum' cannot conform to class protocol 'Testable'

@objc protocol Testable {
    var isTesting: Bool { get }
}

// error: Non-class type 'TestEnum' cannot conform to class protocol 'Testable'
@objc enum TestEnum: Int, Testable {
    case foo

    var isTesting: Bool {
        return true
    }
}
Run Code Online (Sandbox Code Playgroud)

enums objective-c swift swift-protocols

1
推荐指数
1
解决办法
210
查看次数

具有多个控制器的单个代表

我遇到了一个情况,我想用一个委托注册2个不同的UIViewControllers,因为我的项目一次显示2个UIViewControllers.当我触发事件时,我希望两个控制器都得到通知,但不幸的是只有任何一个控制器才能接收到这两个事件.

这是示例代码:

@objc protocol DownloaderDelegate: class {
    func complete()
}

class Downloader {
    static let sharedInstance = Downloader()
    weak var delegate: DownloaderDelegate?

    private init() {

    }

    func downloadFile() {
         self.delegate!.complete()
    }
}
Run Code Online (Sandbox Code Playgroud)

我在UIViewControllers中使用它就像这样:

override viewDidLoad() {
    super.viewDidLoad()

    Downloader.sharedInstance.delegate = self
}
Run Code Online (Sandbox Code Playgroud)

知道如何让视图控制器从单个委托中侦听事件吗?

delegates ios swift swift-protocols

0
推荐指数
1
解决办法
2353
查看次数

如何定义Swift协议以使实现可以是属性_或_方法?

这就是我想要做的事情:

import Foundation
import UIKit

protocol PlayableMediaItem {
    func title() -> String
    func albumArt() -> UIImage
    func audioFileURL() -> URL
}


struct AudioTrack : Codable, PlayableMediaItem {
    var title: String
    var desc:String
    var albumArtDemoName:String
    var audioDemoFilename:String

    func albumArt() -> UIImage {
        let image = UIImage(named: albumArtDemoName)
        return image!
    }

    func audioFileURL() -> URL {
        return Bundle.main.url(forResource: audioDemoFilename, withExtension: "mp3")!
    }
}
Run Code Online (Sandbox Code Playgroud)

但我得到AudioTrack不符合PlayableMediaItem协议的错误,因为该title属性不是方法,它是属性.

我怎样才能设置此让title,albumArt等可以实现为两种属性或方法,只要他们给我回到正确的类型?

我的一些实现可能只是属性,而其他的是计算.

swift swift-protocols

0
推荐指数
1
解决办法
45
查看次数

无法将“AProtocol”类型的值转换为预期参数类型协议

我正在尝试为 NSXPCInterface 构建一个协议,但遇到了一个奇怪的问题。

我创建了一个协议:

public protocol AProtocol {

    //functions in here

}
Run Code Online (Sandbox Code Playgroud)

当我想将其添加到 NSXPCConnection 的导出接口时,

let newConnection: NSXPCConnection
newConnection.exportedInterface = NSXPCInterface(with: AProtocol.self)
Run Code Online (Sandbox Code Playgroud)

我收到这个奇怪的错误:

Cannot convert value of type 'AProtocol.Protocol' to expected argument type 'Protocol'
Run Code Online (Sandbox Code Playgroud)

macos swift swift-protocols

0
推荐指数
1
解决办法
2222
查看次数

Swift 协议的可变性

我目前对协议中的 gettable 属性有点困惑。考虑这个例子:

protocol Person {
    var name: String { get }
}
Run Code Online (Sandbox Code Playgroud)

我希望该name属性是只读的,但我发现您可以在没有编译器投诉的情况下更改该值:

struct Driver: Person {
    var name: String
}

var driver = Driver(name: "Ryan")
driver.name = "Changed!"
Run Code Online (Sandbox Code Playgroud)

如果我们driverlet关键字定义,那么编译器会引发错误,但如果我理解正确,它与协议无关,因为常量结构在 Swift 中设计为不可变的。

方法交互的行为与我预期的一样:

extension Person {
    mutating func changeName(_ newName: String) {
        self.name = newName    // Error: 'name' is a get-only property
    }
}
Run Code Online (Sandbox Code Playgroud)

我是 Swift 的新手,提到的细微差别可能没有任何实际用途,但是这种行为让我问自己,我是否对结构的工作方式缺乏一些基本的了解。

struct swift swift-protocols

0
推荐指数
1
解决办法
234
查看次数

我们可以在 Swift 中编辑“let”协议属性的属性吗?

我有一个这样的代码(在操场上玩:

protocol ServiceProtocol {
    var enabled: Bool { get set }
}

class Service: ServiceProtocol {
    var enabled: Bool = false
}

class A {
    let service = Service()
}

class B {
    let service: ServiceProtocol = Service()
}

let a = A()
let b = B()

a.service.enabled = false
b.service.enabled = false // <-- the error is here: Cannot assign to property: 'service' is a 'let' constant
Run Code Online (Sandbox Code Playgroud)

如果我引用serviceService(class A),则一切都按预期进行。在 class 中Bservice …

let swift swift-protocols

0
推荐指数
1
解决办法
102
查看次数

标签 统计

swift ×7

swift-protocols ×7

delegates ×1

enums ×1

generics ×1

ios ×1

let ×1

macos ×1

objective-c ×1

struct ×1