why does UIWindow has two question marks (UIWindow??) [duplicate] - ios

When accessing UIapplication's main window it is returned as a UIWindow??
let view = UIApplication.sharedApplication().delegate?.window // view:UIWindow??
Why is it returning as a double optional and what does it mean and if put into a if let should I add one ! after it?
if let view = UIApplication.sharedApplication().delegate?.window!
My first though was to replace ? with a ! after delegate but that was not the solution.

#matt has the details, but there is a (somewhat horrible, somewhat awesome) workaround. (See edit below, though)
let window = app.delegate?.window??.`self`()
I will leave the understanding of this line of code as an exercise for the reader.
OK, I lie, let's break it down.
app.delegate?.window
OK, so far so good. At this point we have the UIWindow?? that is giving us a headache (and I believe is a bug in Swift disconnect between Swift and Cocoa). We want to collapse it twice. We can do that with optional chaining (?.), but that unwraps and rewraps, so we're back where we started from. You can double-optional-chain, though, with ??. which is bizarre, but works.
That's great, but ?? isn't a legal suffix operator. You have to actually chain to something. Well, we want to chain back to itself (i.e. "identity"). The NSObject protocol gives us an identity method: self.
self is a method on NSObject, but it's also a reserved word in Swift, so the syntax for it is `self`()
And so we get our madness above. Do with it as you will.
Note that since ??. works, you don't technically need this. You can just accept that view is UIWindow?? and use ??. on it like view??.frame. It's a little noisy, but probably doesn't create any real problems for the few places it should be needed.
(*) I used to think of this as a bug in Swift, but it's not fixable directly by optional chaining. The problem is that there is no optional chaining past window. So I'm not sure where the right place to fix it is. Swift could allow a postfix-? to mean "flatten" without requiring chaining, but that feels odd. I guess the right operator would be interrobang delegate?.window‽ :D I'm sure that wouldn't cause any confusion.
EDIT:
Joseph Lord pointed out the better solution (which is very similar to techniques I've been using to avoid trivial if-let, but hadn't thought of this way before):
let window = app.delegate?.window ?? nil // UIWindow?
I agree with him that this is the right answer.

It's because the window property is itself in doubt (it's optional). Thus, you need one question mark because there might or might not be a window property, and another question mark because the return value of that window property is itself an Optional. Thus we get a double-wrapped Optional (as I explain in my tutorial: scroll down to the Tip box where I talk about what happens when an optional property has an Optional value).
Thus, one way to express this would be in two stages — one to cast (and unwrap that Optional), and one to fetch the window (and unwrap that Optional):
if let del = UIApplication.sharedApplication().delegate as? AppDelegate {
if let view = del.window {
Now view is a UIWindow.
Of course, if you're sure of your ground (which you probably are), you can force the cast in the first line and the unwrapping in the second line. So, in Swift 1.2:
let del = UIApplication.sharedApplication().delegate as! AppDelegate
let view = del.window!

Oh the double optional! Sometimes you can use a double-bang (two exclamation marks) but you cannot cast that way with optional binding. So... my remix of all the other code gets you a UIWindow object called window of the non-optional kind:
guard let w = UIApplication.shared.delegate?.window, let window = w else { return }
But let's not waste time and just use
let window = UIApplication.shared.delegate!.window!!
and be done.

With advent of Swift2 for me a usual workaround in this kind of cases is
if let _window = UIApplication.sharedApplication().delegate?.window, window = _window {
// Some code... i.e.
let frame = window.frame
}

Related

Can I get compile-time checks for implicitly unwrapped optionals in view controllers in Swift (4)?

I have a class that looks like this (simplified):
class GuideViewController: UIViewController, StoreSubscriber {
var tileRenderer: MKTileOverlayRenderer! // <------ this needs to be set by whoever instantiates this class
override func viewDidLoad() {
super.viewDidLoad()
...
}
}
My app uses this GuideViewController class to display many different styles of maps, so the tileRenderer instance variable can have many different values.
I want a compile-time guarantee that tileRenderer will never be nil, instead of using an implicitly-unwrapped optional.
How can I achieve this?
Things I've considered so far but am unsure about
Setting tileRenderer in the init() method of the GuideViewController. This was my first instinct by this answer implies that this is not possible, or an antipattern.
Setting tileRenderer in viewDidLoad(). This seems to require using an implicitly unwrapped optional which bypasses compile-time checks. Also, I'm under the impression that viewDidLoad() is only called once for the view controller in the lifecycle of the app
Manually setting tileRenderer after instantiating the VC. E.g.,
let vc = self.storyboard?.instantiateViewController(withIdentifier: "GuideViewController")
vc.tileRenderer = MKTileOverlayRenderer(...) // <----- can I make the compiler force me to write this line?
navigationController?.pushViewController(vc!, animated: true)
Forgive me for asking such a naive question—I'm fairly new to iOS development.
It isn't possible for there to be a compile-time check, since that would require the compiler to completely analyse the flow of your program.
You can't make the property a non-optional (well, you can - see point 4), since that requires a custom initialiser, which doesn't really work with UIViewController subclasses.
You have a few choices:
Use an implicitly unwrapped optional and crash at runtime if it is nil - hopefully the developer will quickly identify their mistake
Check for nil at a suitable point (such as viewWillAppear) and issue a warning to the console, followed by a crash when you try and access the value or call fatalError - This will give the developer more hints as to what they have done wrong
Use an optional and unwrap it before you use it
Use a non-optional and provide a default value
Option 4 may be the best option; Provide a default render that does nothing (or perhaps issues warnings to the console log that it is a default renderer and that the developer needs to provide one).

Swift - Capturing closures - Apple's swift programming guide snippet

In Apple's Swift programming guide, "Automatic Reference Counting" section, at "Resolving Strong Reference Cycles for Closures",
This snippet is mentioned:
lazy var someClosure: () -> String = {
[unowned self, weak delegate = self.delegate!] in
// closure body goes here
}
What is the point of the exclamation mark in the assignment "weak delegate = self.delegate!"?
I mean, why do you care if there is a value or not? In either ways, you will be receiving an optional delegate inside the closure body since delegate is declared weak, which must be optional, and you will have to access it as an optional.
On the other hand, if you know for sure there 'self.delegate' wont be nil when you access it, why not declaring it as unowned?
Therefore, why is the force unwrapping necessary here?
Can someone shed some light on this?
As there is not really any more context in the text around this example the only person who can know for sure is the author or maintainer of the Swift programming guide.
But here are some possible reasons that I can think of (in no particular order)
The author made a mistake (it happens)
It was required in an older version of Swift and the documentation has not been updated (keeping documentation up to date is hard)
The author wanted to make it obvious to others that creating the block if the delegate does not exist is a bug
The author wants to make it easier to track cases when a delegate was deallocated between creating the block and calling it (maybe for analytics purposes?)

Swift Lazy and Optional properties

What is the difference between a Lazy or Optional property in Swift?
For example, if someone is building a navigation bar that comes in from the side, I think that should all be within one UIViewController. The user might never open the menu but sometimes they will.
var menu: NavigationBar?
lazy var menu: NavigationBar = NavigationBar.initialize()
Both of the optional I think are good code, because they don't create the view unless its needed. I understand Optional means there might be a value it might be nil. I also understand Lazy means don't worry about it until I need it.
Specific Question
My question is are their performance patterns (safety and speed) that say optionals are faster and safer or vise versa?
OK, this is an interesting question, and I don't want to imply that the existing answers aren't good, but I thought I'd offer my take on things.
lazy variables are great for things that need to be setup once, then never re-set. It's a variable, so you could change it to be something else, but that kind of defeats the purpose of a lazy variable (which is to set itself up upon demand).
Optionals are more for things that might go away (and might come back again). They need to be set up each time.
So let's look at two scenarios for your side menu: one where it stays around while it's not visible, and another for when it is deallocated.
lazy var sideMenu = SideMenu()
So the first time the sideMenu property is accessed, SideMenu() is called and it is assigned to the property. The instance stays around forever, even when you're not using it.
Now let's see another approach.
var _sideMenu: SideMenu?
var sideMenu: SideMenu! {
get {
if let sm = _sideMenu {
return sm
} else {
let sm = SideMenu()
_sideMenu = sm
return sm
}
}
set(newValue) {
_sideMenu = newValue
}
}
(Note this only works for classes, not structs.)
OK so what does this do? Well it behaves very similarly to the lazy var, but it let's you re-set it to nil. So if you try to access sideMenu, you are guaranteed to get an instance (either the one that was stored in _sideMenu or a new one). This is a similar pattern in that it lazily loads SideMenu() but this one can create many SideMenu() instances, where the previous example can only create one once.
Now, most view controllers are small enough that you should probably just use lazy from earlier.
So two different approaches to the same problem. Both have benefits and drawbacks, and work better or worse in different situations.
They're actually pretty different.
Optional means that the value could possibly be nil, and the user isn't guaranteeing that it won't be. In your example, var menu: NavigationBar? could be nil for the entire lifetime of the class, unless something explicitly assigns it.
Lazy on the other hand means that the assignment will not be called until it is first accessed, meaning that somewhere in code someone tries to use your object. Note however that it is STILL promised to not be nil if you declare it like you have here lazy var menu: NavigationBar = NavigationBar.initialize(), so no need to do optional chaining.
And actually, a variable can be BOTH Lazy AND Optional, which means that it's value will be loaded when it is first accessed, and that value might be nil at the point it's initialized or at any future point. For example:
lazy var menu: NavigationBar? = NavigationBar.initialize()
That NavigationBar.initialize() is now allowed to return nil, or someone in the future could set the menu to be nil without the compiler/runtime throwing errors!
Does that make the difference clear?
Edit:
As to which is BETTER that's really a case by case thing. Lazy variables take a performance hit on first initialization, so the first access will be a slow one if the initialization process is long. Otherwise, they're nearly identical in terms of safety/performance. Optional variables you have to unwrap before using and so there is a very minor performance cost with that (one machine instruction, not worth the time to think about)
Optional and lazy properties are not the same
An optional property is used when there are chances that the value might not be available(i.e can be nil). But in your scenario, the navigation bar will always be available, its just that the user might not open it.
So using a lazy property serves your purpose. The NavigationBar will only be initialised if the user taps on it.
I do not see any performance issues except that if you use an optional, there is an additional overhead of checking if the value is nil each time before accessing it.

In Swift, why have `as` operator. What does it benefit? Why did they put in?

I'm aware of what the as operator does and how to use them. But I'm more curious in the architectural side of the as operator. Why is it there? What's the huge reason? What does it help?
Example:
var objectData: NSData = NSUserDefaults.standardUserDefaults().objectForKey("myKey") as NSData
...wouldn't it be better if it's:
var objectData: NSData = NSUserDefaults.standardUserDefaults().objectForKey("myKey")
You're right to be a bit confused, as prior to Swift 1.2, the as keyword was overloaded with multiple meanings. Swift 1.2 makes this a lot clearer, as there are now 3 versions of as: as, as? and as!. (in prior versions, as and as! where conflated as just as)
In your example (which I'm assuming is prior to 1.2 as otherwise it wouldn't compile), you are using as to do two things simultaneously.
NSUserDefaults.objectForKey's return type is an AnyObject?, an optional AnyObject. That is, it could be any kind of object, and it might not be an object at all (because there might not have been a value set for the key "myKey").
To make use of this result, you need to do two things – unwrap the optional (i.e. test if it contains a value), and convert the AnyObject to a more useful type (in this case, NSData).
Here's how you can do this:
if let objectData = NSUserDefaults.standardUserDefaults()
.objectForKey("myKey") as? NSData
// note the question mark --^
{
// use the value
}
else {
// handle the value not being present – perhaps set it to a default value
}
This is using as? to test, tentatively, if the value returned by objectForKey is of type NSData. The if let tests if there was a valid value, and if it is of the correct type.
Bear in mind, there is a chance that the value stored for "myKey" is not compatible with the type you want. Suppose instead of an NSData you wanted an Int. You'd do if let intData = NSUserDefaults.standardUserDefaults().objectForKey("myKey") as? Int. If the value stored for "myKey" was the string "foo", this cannot be converted to an Int an you'd get an error.
If instead of using as? above, you use as, you force Swift to unwrap the value and convert the type without checking. If everything works out, that's fine. But if there was no value or if the data was not compatible with the type, you'll get a runtime assertion and your program will crash.
This is so dangerous that in Swift 1.2, this use of as has been renamed as!, the exclamation part indicating a dangerous "forcing" of the conversion. If you try to compile your example code in 1.2, you'll get an error asking if you meant as? or as!.
The as keyword remains for type clarifications that are always safe. For example, suppose you have an overloaded function like so:
func f(i: Int?) { println("called with Int") }
func f(s: String) { println("called with String") }
// try to call f with nil – Swift will complain because it
// doesn't know if this is a nil int or a nil string
f(nil)
// you can tell it which with as:
f(nil as Int?) // prints "called with Int"
f(nil as String?) // prints "called with String"
There are also some kinds of Swift <-> Objective-C bridging conversions that are guaranteed to always succeed, which you can also use as for:
let a = [1,2,3]
// you can always convert a Swift array to an NSArray
let n = a as NSArray
The benefit of as is that it confirms that the object on its left side is of the type on its right side. It differentiates between, for example:
myAnimalReallyADog as Dog
and
myAnimalReallyACat as Dog
Without it you would have to use other, probably more long-winded ways to test whether the object cast is legal.
The as concept is common among many languages and not unique to Swift, so it's a well-established paradigm and pretty clearly useful.
First, we should know when to use it. Usually you use this operator in order to perform a "downcast" - that is, the operator tries to return an object reference as a derived class - and succeeds iff the object is actually of that kind. That implies, that the call-site has to make a guess about the actual kind of the object. This downcast can fail, too.
Thus, the answer is really twofold:
As OldPeculier already pointed out, "it's a well established paradigm and clearly useful".
However, there are other, better designs which could avoid a downcast which can potentially fail. Frequent use of a downcast is a code smell. You should strive to re-think your design, possibly using protocols, or class extensions and so force.

Double question mark, How does it work?

I am learning Swift and, as part of the process, trying to figure out what exactly is going on here. I have a custom segue where I want to place my modal view controller dismissing transition. What used to be in objective-c as:
UIViewController *sourceViewController = self.sourceViewController;
[sourceViewController.presentingViewController dismissViewControllerAnimated:YES completion:nil];
self is an instance of UIStoryboardSegue.
I translated this snippet in Swift as:
self.sourceViewController.presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
getting this error from the compiler:
'UIViewController?' does not have a member named
'dismissViewControllerAnimated'
Now, by documentation, the presentingViewController method looks like this:
var presentingViewController: UIViewController? { get }
From what I understood by the Swift language documentation, ? should unwrap the value, if any. In this case the view controller. The unexplained fact is: if I put a double question mark, it compiles and it works:
self.sourceViewController.presentingViewController??.dismissViewControllerAnimated(true, completion: nil)
Can someone tell me what I am missing? What should that do?
The extra ? required is due sourceViewController returning an AnyObject instead of a UIViewController. This is a flaw in the API conversion from Objective-C (in which such property returns a rather meaningless id). It's still an on-going process that started with iOS 8 beta 5, and apparently those API have not been fixed yet.
If you provide an appropriate cast, it will work as expected
(self.sourceViewController as UIViewController).presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
Now, why do we need an extra ? when dealing with AnyObject?
AnyObject can represent any object type, pretty much as id does in Objective-C. So at compile-time you can invoke any existing method on it, for example sourceViewController.
When you do so, it triggers an implicit downcast from AnyObject to UIViewController and according to the official guide:
As with all downcasts in Swift, casting from AnyObject to a more specific object type is not guaranteed to succeed and therefore returns an optional value
So when you do
self.sourceViewController.presentingViewController??
it implicitly translates to something like
let source: UIViewController? = self.sourceViewController as? UIViewController
let presenting: UIViewController? = source?.presentingViewController
and that's why you need two ?: one for resolving the downcast and one for the presentingViewController.
Finally, always according to the documentation:
Of course, if you are certain of the type of the object (and know that it is not nil), you can force the invocation with the as operator.
which is exactly my proposed solution above.

Resources