The following code throws a message which says "Initializer for conditional binding must have Optional type, not 'AnyObject'"
以下代码抛出一条消息,指出“条件绑定的初始化程序必须具有可选类型,而不是'AnyObject'”
func parseData2(){
var data:NSData?
if let data2 = data {
do {
let details = try NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments)
if let actualDetails = details where actualDetails.isKindOfClass(NSDictionary) {
print("Parse Data")
}
}catch {
print("Error \(error)")
}
}
}
To resolve the above error I used the following code.
为解决上述错误,我使用了以下代码。
func parseData2(){
var data:NSData?
if let data2 = data {
do {
let details:AnyObject = try NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments)
if let actualDetails:AnyObject = details where actualDetails.isKindOfClass(NSDictionary) {
print("Parse Data")
}
}catch {
print("Error \(error)")
}
}
}
Is there any better approach then the above or my code might crash?
有没有比上面更好的方法或我的代码可能会崩溃?
There is one more code which I want to add considering nil check,type check and then type cast check. The reason behind that Swift offers great flexibility but litle bit difficult to fix issues. Let's say I have a dictionary, cityDetails and I am trying to get data for self.cityZipCode and self.cityIdentifier, which are optional, defined as var cityZipCode:Int? and var cityIdentifier:Int?
考虑到nil检查,键入检查然后键入cast check,还有一个我想要添加的代码。 Swift背后的原因提供了很大的灵活性,但很难解决问题。假设我有一个字典,cityDetails,我正在尝试获取self.cityZipCode和self.cityIdentifier的数据,这些数据是可选的,定义为var cityZipCode:Int?和var cityIdentifier:Int?
if let cityBasic = cityDetails["basicDetails"] where
cityBasic!.isKindOfClass(NSDictionary) {
self.cityZipCode = (cityBasic as! NSDictionary)["zip"].integerValue ?? 0
self.cityIdentifier = (cityBasic as! NSDictionary)["cityId"].integerValue ?? 0
}
2 个解决方案
#1
5
No need to unwrap the result from try
. It is not an optional. You do need to cast the result from try
to an NSDictionary
. Use as?
to downcast it.
无需从try中解包结果。它不是可选的。您需要将结果从try转换为NSDictionary。用于?贬低它。
Best practice: full access to returned error for good error handling
最佳实践:完全访问返回的错误以获得良好的错误处理
func parseData2(){
var data:NSData?
if let data2 = data {
do {
let details = try NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments)
if let detailsDict = details as? NSDictionary {
print("Parse Data")
} else if let detailsArray = details as? NSArray {
print("array")
}
} catch {
print("Error \(error)")
}
}
}
Quick and dirty: error handling is not for me!
快速而肮脏:错误处理不适合我!
func parseData2(){
var data:NSData?
if let data2 = data {
let details = try? NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments)
if let detailsDict = details as? NSDictionary {
print("Parse Data")
} else {
print("details might be nil, or not an NSDictionary")
}
}
}
Bad Ass Mode: crashes are features
坏屁股模式:崩溃是功能
func parseData2(){
var data:NSData?
if let data2 = data {
let details = try! NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments) as! NSDictionary
}
}
Some extra info on multiple unwraps : Drop the code below in a playground.
多个unwraps的一些额外信息:在操场上删除下面的代码。
struct SomeStruct {
var anOptional : Int?
init() {
}
}
func unwrapWithIfLet() {
if let unWrappedStruct = myStruct, let unWrappedSomething = unWrappedStruct.anOptional {
print("multiple optional bindings succeeded")
// both unWrappedStruct and unWrappedSomething are available here
} else {
print("something is nil")
}
}
func unwrapWithGuard() {
guard let unWrappedStruct = myStruct, let unWrappedSomething = unWrappedStruct.anOptional else {
print("something is nil")
return
}
print("multiple optional bindings succeeded")
// both unWrappedStruct and unWrappedSomething are available here
}
var myStruct : SomeStruct?
//unwrapWithGuard()
//unwrapWithIfLet()
myStruct = SomeStruct()
myStruct!.anOptional = 1
unwrapWithGuard()
unwrapWithIfLet()
#2
1
You are looking for as?
, which attempts to convert the thing on the left to the type on the right, and returns nil if the conversion is not possible:
您正在寻找?,它试图将左侧的东西转换为右侧的类型,如果转换不可能则返回nil:
let details = try NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments)
if let actualDetails = details as? NSDictionary {
print("Parse Data")
}
You rarely need to use isKindOfClass
in Swift. If you find yourself using it, ask why, and consider whether as
or as?
will work instead.
你很少需要在Swift中使用isKindOfClass。如果您发现自己使用它,请问为什么,并考虑是否为或?会改变。
#1
5
No need to unwrap the result from try
. It is not an optional. You do need to cast the result from try
to an NSDictionary
. Use as?
to downcast it.
无需从try中解包结果。它不是可选的。您需要将结果从try转换为NSDictionary。用于?贬低它。
Best practice: full access to returned error for good error handling
最佳实践:完全访问返回的错误以获得良好的错误处理
func parseData2(){
var data:NSData?
if let data2 = data {
do {
let details = try NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments)
if let detailsDict = details as? NSDictionary {
print("Parse Data")
} else if let detailsArray = details as? NSArray {
print("array")
}
} catch {
print("Error \(error)")
}
}
}
Quick and dirty: error handling is not for me!
快速而肮脏:错误处理不适合我!
func parseData2(){
var data:NSData?
if let data2 = data {
let details = try? NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments)
if let detailsDict = details as? NSDictionary {
print("Parse Data")
} else {
print("details might be nil, or not an NSDictionary")
}
}
}
Bad Ass Mode: crashes are features
坏屁股模式:崩溃是功能
func parseData2(){
var data:NSData?
if let data2 = data {
let details = try! NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments) as! NSDictionary
}
}
Some extra info on multiple unwraps : Drop the code below in a playground.
多个unwraps的一些额外信息:在操场上删除下面的代码。
struct SomeStruct {
var anOptional : Int?
init() {
}
}
func unwrapWithIfLet() {
if let unWrappedStruct = myStruct, let unWrappedSomething = unWrappedStruct.anOptional {
print("multiple optional bindings succeeded")
// both unWrappedStruct and unWrappedSomething are available here
} else {
print("something is nil")
}
}
func unwrapWithGuard() {
guard let unWrappedStruct = myStruct, let unWrappedSomething = unWrappedStruct.anOptional else {
print("something is nil")
return
}
print("multiple optional bindings succeeded")
// both unWrappedStruct and unWrappedSomething are available here
}
var myStruct : SomeStruct?
//unwrapWithGuard()
//unwrapWithIfLet()
myStruct = SomeStruct()
myStruct!.anOptional = 1
unwrapWithGuard()
unwrapWithIfLet()
#2
1
You are looking for as?
, which attempts to convert the thing on the left to the type on the right, and returns nil if the conversion is not possible:
您正在寻找?,它试图将左侧的东西转换为右侧的类型,如果转换不可能则返回nil:
let details = try NSJSONSerialization.JSONObjectWithData(data2, options: .AllowFragments)
if let actualDetails = details as? NSDictionary {
print("Parse Data")
}
You rarely need to use isKindOfClass
in Swift. If you find yourself using it, ask why, and consider whether as
or as?
will work instead.
你很少需要在Swift中使用isKindOfClass。如果您发现自己使用它,请问为什么,并考虑是否为或?会改变。