- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试将此库 ( https://github.com/dankogai/swift-json ) 中的以下代码转换为 Swift 3 兼容代码。
我很难弄清楚如何将 Swift 2 中使用的 Sequence 协议(protocol)转换为适用于 Swift 3 的正确版本。与 3 相比,我找不到任何关于 Swift 2 Sequence 协议(protocol)更改的文档。
这里是我目前尽可能转换为 Swift 3 的代码
extension JSON : Sequence {
public func generate()->AnyIterator<(AnyObject,JSON)> {
switch _value {
case let o as NSArray:
var i = -1
return AnyIterator {
i=i+1
if i == o.count { return nil }
return (i as AnyObject, JSON(o[i]))
}
case let o as NSDictionary:
var ks = Array(o.allKeys.reversed())
return AnyIterator {
if ks.isEmpty { return nil }
if let k = ks.removeLast() as? String {
return (k as AnyObject, JSON(o.value(forKey: k)!))
} else {
return nil
}
}
default:
return AnyIterator{ nil }
}
}
public func mutableCopyOfTheObject() -> AnyObject {
return _value.mutableCopy as AnyObject
}
}
我遇到的具体错误在附图中。
如果您想尝试一下,整个代码对于 JSON 库来说相当短。下面是:
//
// json.swift
// json
//
// Created by Dan Kogai on 7/15/14.
// Copyright (c) 2014 Dan Kogai. All rights reserved.
//
import Foundation
/// init
public class JSON {
public let _value:AnyObject
/// unwraps the JSON object
public class func unwrap(obj:AnyObject) -> AnyObject {
switch obj {
case let json as JSON:
return json._value
case let ary as NSArray:
var ret = [AnyObject]()
for v in ary {
ret.append(unwrap(obj: v as AnyObject))
}
return ret as AnyObject
case let dict as NSDictionary:
var ret = [String:AnyObject]()
for (ko, v) in dict {
if let k = ko as? String {
ret[k] = unwrap(obj: v as AnyObject)
}
}
return ret as AnyObject
default:
return obj
}
}
/// pass the object that was returned from
/// NSJSONSerialization
public init(_ obj:Any) { self._value = JSON.unwrap(obj: obj as AnyObject) }
/// pass the JSON object for another instance
public init(_ json:JSON){ self._value = json._value }
}
/// class properties
extension JSON {
public typealias NSNull = Foundation.NSNull
public typealias NSError = Foundation.NSError
public class var null:NSNull { return NSNull() }
/// constructs JSON object from data
public convenience init(data:NSData) {
var err:NSError?
var obj:Any?
do {
obj = try JSONSerialization.jsonObject(
with: data as Data, options:[])
} catch let error as NSError {
err = error
obj = nil
}
self.init(err != nil ? err! : obj!)
}
/// constructs JSON object from string
public convenience init(string:String) {
let enc:String.Encoding = String.Encoding.utf8
self.init(data: string.data(using: enc)! as NSData)
}
/// parses string to the JSON object
/// same as JSON(string:String)
public class func parse(string:String)->JSON {
return JSON(string:string)
}
/// constructs JSON object from the content of NSURL
public convenience init(nsurl:NSURL) {
var enc:String.Encoding = String.Encoding.utf8
do {
let str = try NSString(contentsOf:nsurl as URL, usedEncoding:&enc.rawValue)
self.init(string:str as String)
} catch let err as NSError {
self.init(err)
}
}
/// fetch the JSON string from NSURL and parse it
/// same as JSON(nsurl:NSURL)
public class func fromNSURL(nsurl:NSURL) -> JSON {
return JSON(nsurl:nsurl)
}
/// constructs JSON object from the content of URL
public convenience init(url:String) {
if let nsurl = NSURL(string:url) as NSURL? {
self.init(nsurl:nsurl)
} else {
self.init(NSError(
domain:"JSONErrorDomain",
code:400,
userInfo:[NSLocalizedDescriptionKey: "malformed URL"]
)
)
}
}
/// fetch the JSON string from URL in the string
public class func fromURL(url:String) -> JSON {
return JSON(url:url)
}
/// does what JSON.stringify in ES5 does.
/// when the 2nd argument is set to true it pretty prints
public class func stringify(obj:AnyObject, pretty:Bool=false) -> String! {
if !JSONSerialization.isValidJSONObject(obj) {
let error = JSON(NSError(
domain:"JSONErrorDomain",
code:422,
userInfo:[NSLocalizedDescriptionKey: "not an JSON object"]
))
return JSON(error).toString(pretty: pretty)
}
return JSON(obj).toString(pretty: pretty)
}
}
/// instance properties
extension JSON {
/// access the element like array
public subscript(idx:Int) -> JSON {
switch _value {
case _ as NSError:
return self
case let ary as NSArray:
if 0 <= idx && idx < ary.count {
return JSON(ary[idx])
}
return JSON(NSError(
domain:"JSONErrorDomain", code:404, userInfo:[
NSLocalizedDescriptionKey:
"[\(idx)] is out of range"
]))
default:
return JSON(NSError(
domain:"JSONErrorDomain", code:500, userInfo:[
NSLocalizedDescriptionKey: "not an array"
]))
}
}
/// access the element like dictionary
public subscript(key:String)->JSON {
switch _value {
case _ as NSError:
return self
case let dic as NSDictionary:
if let val:Any = dic[key] { return JSON(val) }
return JSON(NSError(
domain:"JSONErrorDomain", code:404, userInfo:[
NSLocalizedDescriptionKey:
"[\"\(key)\"] not found"
]))
default:
return JSON(NSError(
domain:"JSONErrorDomain", code:500, userInfo:[
NSLocalizedDescriptionKey: "not an object"
]))
}
}
/// access json data object
public var data:AnyObject? {
return self.isError ? nil : self._value
}
/// Gives the type name as string.
/// e.g. if it returns "Double"
/// .asDouble returns Double
public var type:String {
switch _value {
case is NSError: return "NSError"
case is NSNull: return "NSNull"
case let o as NSNumber:
switch String(cString:o.objCType) {
case "c", "C": return "Bool"
case "q", "l", "i", "s": return "Int"
case "Q", "L", "I", "S": return "UInt"
default: return "Double"
}
case is NSString: return "String"
case is NSArray: return "Array"
case is NSDictionary: return "Dictionary"
default: return "NSError"
}
}
/// check if self is NSError
public var isError: Bool { return _value is NSError }
/// check if self is NSNull
public var isNull: Bool { return _value is NSNull }
/// check if self is Bool
public var isBool: Bool { return type == "Bool" }
/// check if self is Int
public var isInt: Bool { return type == "Int" }
/// check if self is UInt
public var isUInt: Bool { return type == "UInt" }
/// check if self is Double
public var isDouble: Bool { return type == "Double" }
/// check if self is any type of number
public var isNumber: Bool {
if let o = _value as? NSNumber {
let t = String(cString:o.objCType)
return t != "c" && t != "C"
}
return false
}
/// check if self is String
public var isString: Bool { return _value is NSString }
/// check if self is Array
public var isArray: Bool { return _value is NSArray }
/// check if self is Dictionary
public var isDictionary: Bool { return _value is NSDictionary }
/// check if self is a valid leaf node.
public var isLeaf: Bool {
return !(isArray || isDictionary || isError)
}
/// gives NSError if it holds the error. nil otherwise
public var asError:NSError? {
return _value as? NSError
}
/// gives NSNull if self holds it. nil otherwise
public var asNull:NSNull? {
return _value is NSNull ? JSON.null : nil
}
/// gives Bool if self holds it. nil otherwise
public var asBool:Bool? {
switch _value {
case let o as NSNumber:
switch String(cString:o.objCType) {
case "c", "C": return Bool(o.boolValue)
default:
return nil
}
default: return nil
}
}
/// gives Int if self holds it. nil otherwise
public var asInt:Int? {
switch _value {
case let o as NSNumber:
switch String(cString:o.objCType) {
case "c", "C":
return nil
default:
return Int(o.int64Value)
}
default: return nil
}
}
/// gives Int32 if self holds it. nil otherwise
public var asInt32:Int32? {
switch _value {
case let o as NSNumber:
switch String(cString:o.objCType) {
case "c", "C":
return nil
default:
return Int32(o.int64Value)
}
default: return nil
}
}
/// gives Int64 if self holds it. nil otherwise
public var asInt64:Int64? {
switch _value {
case let o as NSNumber:
switch String(cString:o.objCType) {
case "c", "C":
return nil
default:
return Int64(o.int64Value)
}
default: return nil
}
}
/// gives Float if self holds it. nil otherwise
public var asFloat:Float? {
switch _value {
case let o as NSNumber:
switch String(cString:o.objCType) {
case "c", "C":
return nil
default:
return Float(o.floatValue)
}
default: return nil
}
}
/// gives Double if self holds it. nil otherwise
public var asDouble:Double? {
switch _value {
case let o as NSNumber:
switch String(cString:o.objCType) {
case "c", "C":
return nil
default:
return Double(o.doubleValue)
}
default: return nil
}
}
// an alias to asDouble
public var asNumber:Double? { return asDouble }
/// gives String if self holds it. nil otherwise
public var asString:String? {
switch _value {
case let o as NSString:
return o as String
default: return nil
}
}
/// if self holds NSArray, gives a [JSON]
/// with elements therein. nil otherwise
public var asArray:[JSON]? {
switch _value {
case let o as NSArray:
var result = [JSON]()
for v:Any in o { result.append(JSON(v)) }
return result
default:
return nil
}
}
/// if self holds NSDictionary, gives a [String:JSON]
/// with elements therein. nil otherwise
public var asDictionary:[String:JSON]? {
switch _value {
case let o as NSDictionary:
var result = [String:JSON]()
for (ko, v): (Any, Any) in o {
if let k = ko as? String {
result[k] = JSON(v)
}
}
return result
default: return nil
}
}
/// Yields date from string
public var asDate:NSDate? {
if let dateString = _value as? String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZ"
return dateFormatter.date(from: dateString) as NSDate?
}
return nil
}
/// gives the number of elements if an array or a dictionary.
/// you can use this to check if you can iterate.
public var count:Int {
switch _value {
case let o as NSArray: return o.count
case let o as NSDictionary: return o.count
default: return 0
}
}
public var length:Int { return self.count }
// gives all values content in JSON object.
public var allValues:JSON{
if(self._value.allValues == nil) {
return JSON([])
}
return JSON(self._value.allValues)
}
// gives all keys content in JSON object.
public var allKeys:JSON{
if(self._value.allKeys == nil) {
return JSON([])
}
return JSON(self._value.allKeys)
}
}
extension JSON : Sequence {
public func generate()->AnyIterator<(AnyObject,JSON)> {
switch _value {
case let o as NSArray:
var i = -1
return AnyIterator {
i=i+1
if i == o.count { return nil }
return (i as AnyObject, JSON(o[i]))
}
case let o as NSDictionary:
var ks = Array(o.allKeys.reversed())
return AnyIterator {
if ks.isEmpty { return nil }
if let k = ks.removeLast() as? String {
return (k as AnyObject, JSON(o.value(forKey: k)!))
} else {
return nil
}
}
default:
return AnyIterator{ nil }
}
}
public func mutableCopyOfTheObject() -> AnyObject {
return _value.mutableCopy as AnyObject
}
}
extension JSON : CustomStringConvertible {
/// stringifies self.
/// if pretty:true it pretty prints
public func toString(pretty:Bool=false)->String {
switch _value {
case is NSError: return "\(_value)"
case is NSNull: return "null"
case let o as NSNumber:
switch String(cString:o.objCType) {
case "c", "C":
return o.boolValue.description
case "q", "l", "i", "s":
return o.int64Value.description
case "Q", "L", "I", "S":
return o.uint64Value.description
default:
switch o.doubleValue {
case 0.0/0.0: return "0.0/0.0" // NaN
case -1.0/0.0: return "-1.0/0.0" // -infinity
case +1.0/0.0: return "+1.0/0.0" // infinity
default:
return o.doubleValue.description
}
}
case let o as NSString:
return o.debugDescription
default:
let opts = pretty ? JSONSerialization.WritingOptions.prettyPrinted : JSONSerialization.WritingOptions()
if let data = (try? JSONSerialization.data(
withJSONObject: _value, options:opts)) as NSData? {
if let result = NSString(
data:data as Data, encoding:String.Encoding.utf8.rawValue
) as? String {
return result
}
}
return "YOU ARE NOT SUPPOSED TO SEE THIS!"
}
}
public var description:String { return toString() }
}
extension JSON : Equatable {}
public func ==(lhs:JSON, rhs:JSON)->Bool {
// print("lhs:\(lhs), rhs:\(rhs)")
if lhs.isError || rhs.isError { return false }
else if lhs.isLeaf {
if lhs.isNull { return lhs.asNull == rhs.asNull }
if lhs.isBool { return lhs.asBool == rhs.asBool }
if lhs.isNumber { return lhs.asNumber == rhs.asNumber }
if lhs.isString { return lhs.asString == rhs.asString }
}
else if lhs.isArray {
for i in 0..<lhs.count {
if lhs[i] != rhs[i] { return false }
}
return true
}
else if lhs.isDictionary {
for (k, v) in lhs.asDictionary! {
if v != rhs[k] { return false }
}
return true
}
fatalError("JSON == JSON failed!")
}
最佳答案
在 Swift 3 中,generate()
已重命名为 makeIterator()
。更改函数的名称应该可以解决问题。 (请注意,其他名称也发生了变化,例如 AnyGenerator → AnyIterator,但看起来您的代码中已经处理了这个名称。)
此更改是作为 SE-0006: Apply API Guidelines to the Standard Library 的一部分实现的.
关于Swift 序列协议(protocol)的 Swift 2 到 3 迁移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39803826/
internal protocol Reducer { associatedtype S : BaseState associatedtype A : BaseActi
我在考虑我的应用程序中的验证检查,我认为在任何模型上调用 ValidatorFactory,实现 Validee,这意味着说哪个类负责 ValidatorCreation 听起来不错。但是下面的代码不
我已经定义了 2 个协议(protocol)。我需要第一个 (NameProtocol) 来执行 Equatable 协议(protocol)。而另一个类 (BuilderProtocol) 有一个返
在上传方面,WebDAV 协议(protocol)在哪些方面优于 HTTP 协议(protocol)。 Socket Upload 协议(protocol)和 WebDav Upload 协议(pro
是否可以在任何版本的 Swift 中扩展具有混合类/协议(protocol)类型约束的协议(protocol)?例如,仅当 Self 是 UIViewController 的子类并且符合 Protoc
我有一个协议(protocol) (ProtocolA),其中包含符合第二个协议(protocol) (ProtocolB) 的单个属性。 public protocol ProtocolA {
NSObject 协议(protocol)带有常用的协议(protocol)模板,但它似乎并不是协议(protocol)实际实现所必需的。将其排除在外似乎完全没有任何改变。那么,协议(protocol
我想根据这两种协议(protocol)的一般特征(例如开销(数据包)、安全性、信息建模和可靠性)来比较 OPC UA 和 MQTT。我在哪里可以找到每个协议(protocol)的开销和其他特性的一些示
使用 Swift 4,我正在尝试编写一个自定义协议(protocol),它提供对 @objc 协议(protocol)的一致性。 一些代码 更具体地说,我有一个自定义协议(protocol) Sear
我想定义一个在 Viper 架构中使用的协议(protocol),以使用具有弱属性的协议(protocol)在 Viper 组件之间建立连接,但我收到以下错误消息: 'weak' may only b
我在同一个网络中有 3 个 docker 容器: 存储 (golang) - 它提供了用于上传视频文件的 API。 主播 (nginx) - 它流式传输上传的文件 反向代理 (姑且称之为代理) 我有
我打算在我的项目中使用 php socket。它需要用户登录才能根据 session 填充内容。所以我的问题是,TCP/IP 协议(protocol)也像 HTTP 协议(protocol)一样为每个
目前,我的网站有两个版本。一种带有 https://-证书,一种没有。我想将我网站的 http 版本上的所有用户 301 重定向到我网站的 https://版本。 这似乎不可能,因为创建重定向将导致重
目前,我的网站有两个版本。一种带有 https://-证书,一种没有。我想将我网站的 http 版本上的所有用户 301 重定向到我网站的 https://版本。 这似乎不可能,因为创建重定向将导致重
我有一个 Swift View Controller ,它定义了一个在 Objective-C View Controller 中应该遵循的协议(protocol): ChildViewControl
我在客户那里有数百个硬件设备,需要通过telnet接口(interface)发送HTTP数据。 目标是等待数据的 Apache 2 Web 服务器和 PHP 脚本。 这已经可以正常工作了,但是我们发现
我发现如果我创建一个这样的协议(protocol): protocol MyProtocol { } 我不能这样做: weak var myVar: MyProtocol? 我找到了解决这个问题的方法
Xcode 基于模板生成了这个头文件: // this file is XYZAppDelegate.h #import @interface XYZAppDelegate : UIRespond
我在 github 中有一个公开的存储库,我正在开发一个开源应用程序,用于制作产品目录和小型 cms 内容。 我还有一个私有(private)仓库(不托管在github),它是在托管在github的开
您好,我想让别人看到私有(private) repo 代码,但不想公开我的 repo ,也不希望他们有能力更改内容。这可能吗?我查看了网站的“管理”部分,但没有找到合适的内容。谢谢大家。 最佳答案 据
我是一名优秀的程序员,十分优秀!