我想创建一个特定类型的属性,并且符合协议,我会在Objective-C中完成这样的:
@property (nonatomic) UIViewController<CustomProtocol> *controller;
Run Code Online (Sandbox Code Playgroud)
我正在寻找的是指定可以使用类型为UIViewController的对象设置属性,该对象也符合CustomProtocol,以便清楚基类是什么.我知道我可能只是使用一个短类存根来获得相同的结果,即
class CustomViewController : UIViewController, CustomProtocol {}
Run Code Online (Sandbox Code Playgroud)
但这似乎不是最干净的方法.
我正在开发一个Restofire库,我想在其中保留一个配置对象.我想在配置对象中有一个ResponseSerializer,但事情是ResponseSerializer是一个通用的.
public struct Configuration<M> {
/// The Default `Configuration`.
static let defaultConfiguration = Configuration<AnyObject>()
/// The base URL. `nil` by default.
public var baseURL: String!
/// The `ResponseSerializer`
public var responseSerializer: ResponseSerializer<M, NSError> = AlamofireUtils.JSONResponseSerializer()
/// The logging, if enabled prints the debug textual representation of the
/// request when the response is recieved. `false` by default.
public var logging: Bool = false
}
Run Code Online (Sandbox Code Playgroud)
我用baseUrl设置了defaultConfiguration Configuration.defaultConfiguration.baseUrl = "http://httpbin.org/"
我有一个带有associatedType要求的协议,它使用defaultConfiguration作为默认实现.但我需要将通用AnyObject更改为associatedType模型,以便配置对象的responseSerializer返回类型Model.
public protocol Configurable {
associatedtype Model
/// The Restofire …Run Code Online (Sandbox Code Playgroud) 在尝试迁移到Swift 3时(在包含大约一半/半swift/objective-c代码的项目中),我遇到了一个问题.我们在objective-c中声明这个特定的协议,如下所示:
@protocol AProtocolDeclaration <NSObject>
- (void)someEventHappened:(nullable NSError *)error;
@end
Run Code Online (Sandbox Code Playgroud)
Swift编译器为上面的协议声明生成以下内容:
public protocol AProtocolDeclaration : NSObjectProtocol {
public func someEventHappened(_ error: Error?)
}
Run Code Online (Sandbox Code Playgroud)
当在a中实现协议concrete class (in swift)并尝试定义生成的方法时,我会继续得到类似的错误:无法转换Error to NSError.我不知道如何解决这个错误.有人可以建议吗?
我正在努力在Swift 4中使用新的强类型KVO语法来观察仅通过协议可见的属性:
import Cocoa
@objc protocol Observable: class {
var bar: Int { get }
}
@objc class Foo: NSObject, Observable {
@objc dynamic var bar = 42
}
let implementation = Foo()
let observable: Observable = implementation
let observation = observable.observe(\.bar, options: .new) { _, change in
guard let newValue = change.newValue else { return }
print(newValue)
}
implementation.bar = 50
Run Code Online (Sandbox Code Playgroud)
error: value of type 'Observable' has no member 'observe'
let observation = observable.observe(\.bar, options: .new) { _, change …Run Code Online (Sandbox Code Playgroud) 我是一名经验丰富的Objective-c程序员,但我不能对Swift说同样的话,我很难在不使用像OCMock这样的框架的情况下在swift中测试一个类.
问题:我正在将Firebase集成到一个混合的Objective-C/Swift项目中,我需要根据应用程序的构建配置对其进行配置.
我为此编写了一个Swift类(将由obj-c app委托使用),但是由于firebase框架是通过静态类方法配置的FIRApp.configure(with: FIROptions),所以我需要以某种方式模拟这个方法以进行单元测试它.
我的代码,没有任何处理依赖注入,看起来像这样:
@objc class FirebaseConfigurator: NSObject{
func configureFirebase(){
let config = configManager.buildConfiguration
var optionsPlistBaseName = getPlistName()
let optionsFile = Bundle.main.path(forResource: optionsPlistBaseName, ofType: "plist")
guard let opts = FIROptions(contentsOfFile: optionsFile) else{
assert(false, "fatal: unable to load \(optionsFile)")
return
}
FIRApp.configure(with: opts)
}
func getPlistName() -> String{
// retrieves correct plist name and returns it
}
}
Run Code Online (Sandbox Code Playgroud)
我做了一些研究,但到目前为止我没有发现任何适合我的解决方案,但我想到的是以下其中一项:
FIRApp.configure(with:)但是我应该从objective-c执行此操作并且函数也接受一个参数,我正在努力学习语法作为参考(个人和可能需要它的人),这些是我认为有用的一些资源,我将继续挖掘:
同时,每一个帮助都会非常感激.
作为旁注,有很多方法可以解决这个问题而不用嘲笑静态类方法,但我的目标是找到一种嘲弄它的方法,以便在测试更复杂时更好地理解最佳实践的情况.
unit-testing dependency-injection xctest swift swift-protocols
我无法完全掌握协议和泛型的问题。
在下面的代码中,用 ERROR HERE 注释标记,我收到以下错误:
成员“protocolMethod”不能用于“any Protocol1”类型的值;考虑使用通用约束来代替
我认为它抱怨主要是因为参数的类型item至少在某种程度上未解决?不幸的是,我发现这个建议没有帮助,因为我不知道通用约束在这里有何帮助(至少就我对它们的理解而言)。
老实说,我觉得我可能对 Swift 要求太多了。
有人可能会看到问题是什么或有尝试解决此问题的建议吗?
添加于 12/26/22 - 作为进一步的背景,导致错误出现的原因是将参数添加item到protocolMethod协议上的方法中,这几乎表明它是问题的核心。
protocol Protocol1
{
associatedtype DataItem
func protocolMethod(item : DataItem)
}
protocol Protocol2 {
associatedtype AType1: Hashable
//...
}
class Class1<Type1: Protocol2>: NSObject
{
typealias Item = Type1.AType1
var delegate : (any Protocol1)?
private func method1(item: Item)
{
delegate?.protocolMethod(item : item) //ERROR HERE
}
}
Run Code Online (Sandbox Code Playgroud)
(使用最新的Xcode)
我有两个框架
首先 - Restofire.它有一个协议ResponseSerializer与扩展.
public protocol ResponseSerializable {
/// The type of object returned in response.
associatedtype Model
/// The `Alamofire.ResponseSerializer`.
var responseSerializer: ResponseSerializer<Model, NSError> { get }
}
extension ResponseSerializable {
/// `CustomJSONResponseSerializer`
public var responseSerializer: ResponseSerializer<Model, NSError> {
return AlamofireUtils.JSONResponseSerializer()
}
}
Run Code Online (Sandbox Code Playgroud)
第二 - Restofire-Gloss.它具有对Restofire框架中符合Decodable的模型的协议的扩展.
public extension ResponseSerializable where Model: Decodable {
/// `GLOSSResponseSerializer`
public var responseSerializer: ResponseSerializer<Model, NSError> {
return GlossUtils.GLOSSResponseSerializer()
}
}
public extension ResponseSerializable where Model: CollectionType, Model.Generator.Element: Decodable {
/// `GLOSSResponseSerializer`
public …Run Code Online (Sandbox Code Playgroud) 我正在尝试按照本教程构建自定义转换.一旦我得到了涉及UIViewControllerAnimatedTransitioning的部件的自定义,我就开始出错了.(我对于斯威夫特来说还是新手,所以到目前为止,我们需要付出很多努力才能展现出来).
我一直得到2个错误.1 -
无法指定'CircleTransitionAnimator'类型的值来键入'CAAnimationDelegate?'
2 -
方法不会覆盖其超类中的任何方法
我猜这个问题与UIViewControllerAnimatedTransitioning有关
class CircleTransitionAnimator: NSObject, UIViewControllerAnimatedTransitioning {
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.5
}
weak var transitionContext: UIViewControllerContextTransitioning?
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
self.transitionContext = transitionContext
var containerView = transitionContext.containerView()
var fromViewController = transitionContext.viewController(forKey: UITransitionContextFromViewControllerKey) as! ViewController
var toViewController = transitionContext.viewController(forKey: UITransitionContextToViewControllerKey) as! ViewController
var button = fromViewController.button
containerView.addSubview(toViewController.view)
var circleMaskPathInitial = UIBezierPath(ovalIn: (button?.frame)!)
var extremePoint = CGPoint(x: (button?.center.x)! - 0, y: (button?.center.y)! - toViewController.view.bounds.height)
var radius = sqrt((extremePoint.x*extremePoint.x) …Run Code Online (Sandbox Code Playgroud) 我希望能够使用数组文字实例化一个子类,这里MyLabel是一个子类,它是一个子类UILabel.我在我的框架ViewComposer中使用它,它允许使用枚举视图的数组来创建UIViews,如下所示:
let label: UILabel = [.text("Hello World"), .textColor(.red)]
Run Code Online (Sandbox Code Playgroud)
在这个问题中,我大大简化了用例,而是允许编写:
let vanilla: UILabel = [1, 2, 3, 4] // works!
print(vanilla.text!) // prints: "Sum: 10"
Run Code Online (Sandbox Code Playgroud)
我想要做的是使用相同的ExpressibleByArrayLiteral语法,但使用的是被UILabel调用的子类MyLabel.但是当我尝试时,编译器会阻止我:
let custom: MyLabel = [1, 2, 3, 4] // Compilation error: "Could not cast value of type 'UILabel' to 'MyLabel'"
Run Code Online (Sandbox Code Playgroud)
UILabel由于符合Makeable以下自定义协议,使用数组文字的实例化可行.
是否有可能使编译器理解我指的是子类的数组文字初始值设定项MyLabel而不是它的超类UILabel?
以下代码可能没有任何逻辑意义,但它是一个最小的例子,隐藏了我真正想要的东西:
// This protocol has been REALLY simplified, in fact …Run Code Online (Sandbox Code Playgroud) 我希望 Swift 使我能够在where块中为具有指定条件的类型创建扩展。我想象我可以使用依赖于具体泛型类型值 ( T) 的不同扩展来扩展相同的泛型类型。但不是。以下示例演示了我的问题:
protocol P {
associatedtype Prop
var property: Prop { get }
}
enum E<T: P> {
case single(T)
case double(T)
}
extension E: P where T.Prop == Int {
var property: Int {
switch self {
case .single(let o): return o.property
case .double(let o): return o.property * 2
}
}
}
extension E: P where T.Prop == String {
var property: String {
switch self {
case .single(let o): return o.property …Run Code Online (Sandbox Code Playgroud) swift-protocols ×10
swift ×8
ios ×4
generics ×3
swift3 ×2
nserror ×1
objective-c ×1
swift2 ×1
swift4 ×1
uiview ×1
unit-testing ×1
xctest ×1