我需要使用以下结构:
import Foundation
protocol QueryValueConvertible {
func itemsWith(name: String) -> [URLQueryItem]
}
struct QueryList : QueryValueConvertible {
var elements: [(String, QueryValueConvertible)]
init(elements: [(String, QueryValueConvertible)]) {
self.elements = elements
}
var isEmpty: Bool {
return elements.isEmpty
}
var percentEncodedQuery: String {
let allowedCharacters = QueryList.percentEncodedQueryAllowedCharacters
return items.map { (item) -> String in
guard let encodedName = item.name.addingPercentEncoding(withAllowedCharacters: allowedCharacters) else {
return ""
}
if let value = item.value, let encodedValue = value.addingPercentEncoding(withAllowedCharacters: allowedCharacters) {
return encodedName + "=" + encodedValue
} else {
return encodedName
}
}.joined(separator: "&")
}
var items: [URLQueryItem] {
return elements.flatMap { (name, value) -> [URLQueryItem] in
return value.itemsWith(name: name)
}
}
func itemsWith(name: String) -> [URLQueryItem] {
let prefix = name
guard !elements.isEmpty else {
return [URLQueryItem(name: "\(name)[]", value: nil)]
}
return elements.flatMap { (suffix, value) -> [URLQueryItem] in
let name = "\(prefix)[\(suffix)]"
return value.itemsWith(name: name)
}
}
private static let percentEncodedQueryAllowedCharacters: CharacterSet = { () -> CharacterSet in
// We are far more conservative than NSURLComponents because nobody implements RFC 3986.
// HTML5 allows the following restricted set of characters to appear in query.
// cf: http://www.w3.org/TR/html5/forms.html#application/x-www-form-urlencoded-encoding-algorithm
let characters = NSMutableCharacterSet()
characters.addCharacters(in: NSRange(location: 0x2a, length: 1)) // *
characters.addCharacters(in: NSRange(location: 0x2d, length: 1)) // -
characters.addCharacters(in: NSRange(location: 0x2e, length: 1)) // .
characters.addCharacters(in: NSRange(location: 0x30, length: 10)) // 0-9
characters.addCharacters(in: NSRange(location: 0x41, length: 26)) // A-Z
characters.addCharacters(in: NSRange(location: 0x5f, length: 1)) // _
characters.addCharacters(in: NSRange(location: 0x61, length: 26)) // a-z
return characters as CharacterSet
}()
}
extension QueryList : ExpressibleByDictionaryLiteral {
init(dictionaryLiteral elements: (String, QueryValueConvertible)...) {
self.elements = elements
}
init<S : Sequence>(_ elements: S)
where S.Iterator.Element == (String, QueryValueConvertible)
{
self.elements = Array(elements)
}
}
extension QueryList : ExpressibleByArrayLiteral {
init(arrayLiteral elements: QueryValueConvertible...) {
self.elements = elements.enumerated().map { (index, value) in (String(index), value) }
}
init<S : Sequence>(_ elements: S)
where S.Iterator.Element : QueryValueConvertible
{
self.elements = elements.enumerated().map { (index, value) in (String(index), value) }
}
}
func + (lhs: QueryList, rhs: QueryList) -> QueryList {
return QueryList(elements: lhs.elements + rhs.elements)
}
func += (lhs: inout QueryList, rhs: QueryList) {
lhs = QueryList(elements: lhs.elements + rhs.elements)
}
extension String : QueryValueConvertible {
func itemsWith(name: String) -> [URLQueryItem] {
return [URLQueryItem(name: name, value: self)]
}
}
extension Int : QueryValueConvertible {
func itemsWith(name: String) -> [URLQueryItem] {
return [URLQueryItem(name: name, value: String(self))]
}
}
extension Bool : QueryValueConvertible {
func itemsWith(name: String) -> [URLQueryItem] {
return [URLQueryItem(name: name, value: self ? "true" : "false")]
}
}
在另一个类中,我有以下代码:
var sampleData = [
"foo": someString,
"bar": anotherString
] as QueryList
let myDict: [String: Bool] = ["example": true]
var myArray = [[String:Any]]()
myArray.append(myDict)
sampleData += ["myData": myArray]// this is where the error is occurring.
我收到以下编译时错误:
"Value of type [[String: Any]] does not conform to expected dictionary value type "QueryValueConvertible"
我要做的是将包含键/值对“String”的字典提交到包含在Array中的“Bool”。反过来,该数组也被引用为“String”类型的键。
答案 0 :(得分:0)
在声明时,只需将myArray的类型从[[String:Any]]更改为[[String:QueryValueConvertible]]。 或者你可以将它初始化为相同的效果:
var myArray: [[String: QueryValueConvertible]] = [myDict]
答案 1 :(得分:-1)
Xcode对你的代码做的第一件事是建议你转:
sampleData += ["myData": myArray]
到
sampleData += ["myData": myArray as! QueryValueConvertible]
变量myArray
不是正确的类型。您可以将其投射或初始化为QueryValueConvertible
。如果你投了它,我建议使用as?
而不是as!
,然后在添加之前检查Optional
。