Optional binding with try? and as? still produces an optional type
You must wrap your try?
call within parenthesis like this :
if let expenses = (try? App.mainQueueContext.fetch(request)) as? [Expense]
That's because as?
has a higher precedence than try?
(probably because try?
can be applied to the whole expression).
Bound value in a conditional binding must be of Optional Type
You can get it to compile by making the cast as Usable? instead of as Usable, like this:
// Check whether or not a class is useable
if let usableThing = thing as Usable? { // error here
usableThing.use()
}
else {
println("can't use that")
}
Swift3 optional chaining and unwrapping with error handling
I think if you rearrange the parens it will work.
guard let parsedResponse = (try? JSONSerialization.jsonObject(with: data, options: .allowFragments)) as? [String:Any] else {
How to use published optional properties correctly for SwiftUI
Below is an extension of Binding
you can use to convert a type like Binding<Int?>
to Binding<Int>?
. In your case, it would be URL
instead of Int
, but this extension is generic so will work with any Binding
:
extension Binding {
func optionalBinding<T>() -> Binding<T>? where T? == Value {
if let wrappedValue = wrappedValue {
return Binding<T>(
get: { wrappedValue },
set: { self.wrappedValue = $0 }
)
} else {
return nil
}
}
}
With example view:
struct ContentView: View {
@StateObject private var model = MyModel()
var body: some View {
VStack(spacing: 30) {
Button("Toggle if nil") {
if model.counter == nil {
model.counter = 0
} else {
model.counter = nil
}
}
if let binding = $model.counter.optionalBinding() {
Stepper(String(binding.wrappedValue), value: binding)
} else {
Text("Counter is nil")
}
}
}
}
class MyModel: ObservableObject {
@Published var counter: Int?
}
Result:
Swift 3 | JSON Value of optional type '[String : Any] not unwrapped, did mean to use '!' or '?'?
json
is optional (since you are using as?
).
The best solution is to conditionally unwrap it:
if let json = (try? JSONSerialization.jsonObject(with: data!, options: .allowFragments)) as? [String: Any] {
if let Users = dict["User"] as? [String: Any] {
}
}
Note, you should also be safely unwrapping data
. If the data can't be obtained, using data!
will crash your app.
Conditional Binding: if let error – Initializer for conditional binding must have Optional type
if let
/if var
optional binding only works when the result of the right side of the expression is an optional. If the result of the right side is not an optional, you can not use this optional binding. The point of this optional binding is to check for nil
and only use the variable if it's non-nil
.
In your case, the tableView
parameter is declared as the non-optional type UITableView
. It is guaranteed to never be nil
. So optional binding here is unnecessary.
func tableView(tableView: UITableView, commitEditingStyle editingStyle:UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
// Delete the row from the data source
myData.removeAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
All we have to do is get rid of the if let
and change any occurrences of tv
within it to just tableView
.
How can I unwrap an optional value inside a binding in Swift?
You can use this initialiser, which seems to handle this exact case - converting Binding<T?>
to Binding<T>?
:
var body: some View {
AvatarView(userData: Binding($userById[activeUserId])!)
}
I have used !
to force unwrap, just like in your attempts, but you could unwrap the nil
however you want. The expression Binding($userById[activeUserId])
is of type Binding<UserData>?
.
Initializer for conditional binding must have Optional type, not 'AnyObject - Approach
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.
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.
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()
How to handle failed Optional Binding
Just add else to the IF control flow
let newString = "http://somehost:1337/parse/classes/CompEntry?where={\"CompID\":{\"__type\":\"Pointer\",\"className\":\"Competition\",\"objectId\":\"CXy40U65Z9\"}}"
if let url = URL(string: newString) {
print("here") // NEVER GETS EXECUTED
} else {
print("here") // EXECUTED when optional binding fails
}
Updated:
Author expected an error
URL initializer doesn't throws an error in case of not being able to parse a given string
This initializer returns nil if the string doesn’t represent a valid
URL. For example, an empty string or one containing characters that
are illegal in a URL produces nil. source
Related Topics
Center Content of Uiscrollview When Smaller
How to Open Mail App from Swift
Saving Image to Documents Directory and Retrieving for Email Attachment
Passing Data to View Controllers That Are Embedded in Container Views
What Are the Device-Width CSS Viewport Sizes of the Iphone6 and iPhone 6 Plus
Set Default iOS Local Notification Style for Application
Creating Delegates on the Spot with Blocks
How Does Apple Notify iOS Apps of Refunds of In-App Purchases (Iap)
iPhone "Slide to Unlock" Animation
In Swift How to Call Method with Parameters on Gcd Main Thread
Uilabel Wrong Word Wrap in iOS 11
Creating Custom Info Window in Swift with the Google Maps iOS Sdk
Fix CSS Hover on Iphone/Ipad/Ipod
iOS Simulator Games Run Very Slow (Low Fps)