What does this block mean in Swift - Alamofire? - ios

This is a code block in Alamofire/Manager.swift:
It is inside a class named "public class Manager"
public static let sharedInstance: Manager = {
let configuration: NSURLSessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
configuration.HTTPAdditionalHeaders = Manager.defaultHTTPHeaders
return Manager(configuration: configuration)
}()
Obviously, this is "let something equals the closure," but what I don't get is what does the "()" in the end of the line mean?
To defer the execution of the code? How? (It seems to me that the execution won't be deferred as it has the "()"? And I am wondering why this is not causing the existing of a memory circle? It returns the Manger itself and the returned new instance will also do the same, returning a new self...
Why not a key word "lazy"?
I have a strange feeling that i've seem this usage somewhere else too. I'm learning Swift for 60 days now. Am I fast or slow? How to be a iOS developer also?(I mean how to be a real one, not enroll the program)
For now I'm kind of confused and reading all the source code I could get. Sometimes I feel the official docs and Xcode sucks and I don't know how to read a source code scratch. Any tips and advice?

This initializes sharedInstance with the result of the closure (without the parens at the end it would just initialize it to the closure itself) It's a standard syntax for initializing variable with an initializer too complex for a simple expression. In this multiple statements are required so that the HTTPAdditionalHeaders can be initialized.

Okay, I've made a mistake. The trick lies that the sharedInstance used a key word "static" This is common, but in python, which I am most familiar with, do not use this key word.
According to the official guide:
“You can also define properties that belong to the type itself, not to any one instance of that type. There will only ever be one copy of these properties, no matter how many instances of that type you create. These kinds of properties are called type properties.”
Apple Inc. “The Swift Programming Language”. iBooks. https://itun.es/cn/jEUH0.l

the answer is at the session name "Setting a Default Property Value with a Closure or Function": https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html#//apple_ref/doc/uid/TP40014097-CH18-ID231

Related

Swift instance members & functions calls, could someone please clarify?

I'm practicing functions in an Xcode project (not playground, if that matters) and when I set the constant's function name to the above function's name, Xcode won't let me call it.
In other functions I've done the same thing I haven't had this error, I don't know why it's being triggered. I've tried putting the "let fun" constant into it's own struct but that just throws up a different error.
Your let fun = playstation(... is code. It is an executable command. Code consisting of an executable command cannot just live anywhere. It cannot exist just free-floating the way you have it. It must live in a method. For example you could put it inside your viewDidLoad method.
I am sure you know this, but I would like to say that learning the basics/fundamentals of the Swift language is really good if you use playgrounds for that or any other online IDEs which support Swift language.
Swift Playgrounds Experience is very, very different than what an iOS dev has to do later, i.e. when it actually comes to building an app.
Of course in app making, the Swift language is used, and one uses the knowledge he practiced using playgrounds. BUT!
When it comes to storyboards, ViewControllers, etc., one has to understand that this time, it is all about OOP (classes and structs).
It is about managing views, loading them, displaying UIView objects, implementing logic, saving/loading data...
So as people mentioned above, here you are creating an instance method and trying to use it as a regular function inside that Class.
To be able to use this function as you expect, you have to create an object/instance of this class, then you can call this function.
In this picture, you may see that using a static keyword also might be a solution. static func(){} means that this function belongs to the class itself. You access that func by using the full name of the type/class.
You cannot call an instance method to initialize this same exact instance property, so you will need to convert to a lazy var like so:
lazy var fun = playStation(game: "Monsters")
This way, the playStation(game: "Monsters") call will be triggered lazily, in the exact moment when the fun property will be called for the first time. This can be very useful, especially when performing more intensive tasks. The quirk with using lazy keyword is that it can only be used with var, which means the property can be mutated or set again - we lose immutability of let constants.
But maybe you do not want to store the fun value as an instance property and only want to get it once? You could then move it into the viewDidLoad implementation, so the fun is no longer an instance property but a local one, available only within the viewDidLoad method scope.
override func viewDidLoad() {
super.viewDidLoad()
let fun = playStation(game: "Monsters")
// do what you want with the `fun` value.
// maybe set it as text to some label?
myLabel.text = fun
}
You can read more about Lazy Initialization in this blogpost, also make sure to read the official documentation.

How to read Apple developer document

I have been very confuse with how to read apple developer document. It has restrict me to learn deeper into ios coding environment beyond what Youtuber have taught me. One of the example is this
Declaration:
func run(_ configuration: ARConfiguration,
options: ARSession.RunOptions = [])
From this apple link
https://developer.apple.com/documentation/arkit/arsession/2875735-run
It suppose to get me started on how to start ARKit but i cant understand what it wants me to do.
What is that line of code for?
How do i use that line of code?
I dont get it at all. I cant find any tutorial that explain apple documentation. Someone please explain it to me i need to know this
A declaration example just shows the parameters of the method (their types). Bellow the declaration, it is explained where that method can be used, in more detail. You asked about the purpose of the declaration; after the name of the method (the first line) it is written that it
Starts AR processing for the session with the specified configuration and options.
So, this part answers to your first question. What's going after the example of a method declaration, answers to your second question.
Always try to read the Discussion section of the documentation and don't miss it. It will help you to have a basic idea what the method, property, etc. is doing.
However, there are some cases when there is almost no information is provided except a declaration. But those cases are quite rare.
The line of code is for the following as mentioned in the documentation:
Starts AR processing for the session with the specified configuration and options.
To answer your question of how you may use that in context we can look at the Overview for ARSession.
Every AR experience built with ARKit requires a single ARSession object. If you use an ARSCNView or ARSKView object to easily build the visual part of your AR experience, the view object includes an ARSession instance. If you build your own renderer for AR content, you'll need to instantiate and maintain an ARSession object yourself.
If we use the first suggestion we can do the following.
// Create an instance of ARSKView
let view = ARSKView()
// We can get the session from the view as per documentation:
// A view creates its own session object; use this property
// to access and configure the view's session.
let session = view.session
// We now need to create an instance of a ARConfiguration subclass.
// Looking at the documentation we have the possibility of
// ARWorldTrackingConfiguration, AROrientationTrackingConfiguration
// or ARFaceTrackingConfiguration.
let configuration = ARWorldTrackingConfiguration()
// We can now call our function because we have all that's necessary.
// You'll notice we're not passing a value for the second parameter because it has a default parameter of an empty array.
session.run(configuration)
To improve on your ability of understanding documentation I recommend to identify the moment you don't have enough information for an implementation. In this case you want to call the function
func run(_ configuration: ARConfiguration, options: ARSession.RunOptions = []). Notice that that function is called on a receiver of type ARSession and requires an ARConfiguration be passed in. Your next step would be to look into those classes, specifically looking for an initializer of each and have enough of an understanding to then return to that above function and use them in it.

What should I do about frequently repeated constants?

This seems like a very simple question, but I can't find a clear answer. Also it's not specifically about swift or iOs, but I'm new to programming and swift is the only language I know anything about, so I don't know how to phrase it for a more general context.
I'm trying to write an iOs app and I found myself defining the same constants many times throughout my code.
I must have written this line about a hundred times, for instance:
let calendar = NSCalendar.currentCalendar()
Another example is getting my only User object from its persistent store:
let realm = try! Realm()
let user = realm.objects(User).first!
I define those calendar and user constants over and over throughout my whole code in classes and subclasses and extensions and computed properties.
That seems kind of stupid, though. I think I should be able to define calendar once and for all and just use it when I need it. So my first thought was to declare a global constant, but apparently everybody thinks anything with the word "global" in it should be avoided at all costs.
So what should I do? Is there another solution for this? Should I just keep writing the same stuff over and over again?
Thanks in advance,
Daniel
There are many different situations in which the best use of different approaches.
For example in your case:
let calendar = NSCalendar.currentCalendar()
currentCalendar is a static method that already returns a pointer to the object that you will use. And you don't need to set it to some constant for using with simple case:
print(NSCalendar.currentCalendar().calendarIdentifier)
Another thing that is most often better to use a shorter name for the object in your code when you need to refer to it often and this code looks much more readable:
print(calendar.calendarIdentifier)
If you have the functionality that you will often use in application from different places, you can just make it to the static method and does not create an object of this class every time you call it:
class NetworkConnection {
class func getDataFromServet(completion block: (data: SomeType) -> Void) {
...
}
}
And use it without object creation like:
NetworkConnection.getDataFromServer(completion: {(data: SomeType) -> Void in
...
})
If you need to use created object in many places, the best solution is not to make it global or singleton instance, but pass a pointer to it to the objects where you need to use it. This makes the code more readable, for example by looking at the input parameters of the init method, anyone can immediately understand which objects use this class for their work. And this class is easier to take from the project in a separate module and connect to another project. At that time, if you use the singleton instance, the class's interface is not clear what it can be used and this leads to code obfuscation. This applies and to the global objects.
If you're constantly changing it, why aren't you just using var instead of let?

Difference between self.view.addSubview and view.addSubview

I have done a bunch of coding in swift and prefer to do a lot programmatically and I was wondering what the difference was between these two:
self.view.addSubview(someNewView)
view.addSubview(someNewView)
they both seem to work. Is one better for some reason? Are they actually that different?
If this is a dumb question or already answered it can be removed. Just a thought.
There's no real difference, although you may see the use of self more often from previously Objective-C developers. From the docs:
In practice, you don’t need to write self in your code very often. If
you don’t explicitly write self, Swift assumes that you are referring
to a property or method of the current instance whenever you use a
known property or method name within a method.
...
The main exception to this rule occurs when a parameter name for an instance method has the same name as a property of that instance. In this situation, the parameter name takes precedence, and it becomes necessary to refer to the property in a more qualified way.
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Methods.html

Expensive Object management in Swift

I have been looking at Swift the last couple of days and it looks good, I am confused on a point though even after review of the guide Apple published.
I understand that memory management in Swift uses ARC and therefore quite safe, however in situations where I'd like more fine grained control of object creation and destruction I'm slightly confused.
Take these two simple examples:
In ObjC, when you'd (for example) like a UIViewController you intend to push to stay around for the lifetime of your app and only be created once (say because it's expensive to create), you'd make it a property and then wrap it's Alloc Init like this:
if (!self.myProperty)
{
self.myProperty = [[MyObj alloc] init];
}
This way it only creates once, keeps state and the same object instance can be reused indefinitely, yielding known object references, and good performance not having to recreate each time the viewController goes out of scope.
Another example of this is with NSMutableString, vs Swifts String.
You can set an NSMutableString's string many times and it will keep the same object reference, however this doesn't seem to be the case with a Swift String when changing it.
This may just be 'deprecated thinking in Objective C' but is there a best practice with regard to keeping around expensive objects or to keep state (same object) for certain objects during the lifetime of their usage.
I think what you're looking for is a "Lazy stored property":
The example in the swift docs is:
class DataManager {
#lazy var importer = DataImporter()
var data = String[]()
// the DataManager class would provide data management functionality here
}
and it says about #lazy:
A lazy stored property is a property whose initial value is not calculated until the first time it is used. You indicate a lazy stored property by writing the #lazy attribute before its declaration.
The comment about NSMutableString is a little different, you can continue to use NSMutableString in your swift code, but Apple are encouraging developers to use the Swift built-in types whenever possible :)
see the "String Mutability" section in the swift docs

Resources