How to read Apple developer document - ios

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.

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.

Treat object coming from server at app launch as non optional

When it launches, the first thing our app does is to load a user object from our backend, while showing a splash screen.
Once that user has been fetched, our home screen is shown and we can consider that this user is valid. However, this property can only be optional in our codebase since it doesn't have a default value, so swift forces us to either mark it as optional or implicitly unwrapped.
We don't want to make it implicitly unwrapped because then if future developper were to add code using the user object that is actually ran before the object is loaded from the server, the app would crash.
My question is then, is there a design pattern on iOS that would let swift understand something like: first run that small part of the codebase that loads the user, then consider the rest of the project can be ran knowing the object is valid ?
Once that user has been fetched, our home screen is shown and we can consider that this user is valid. However, this property can only be optional in our codebase since it doesn't have a default value, so swift forces us to either mark it as optional or implicitly unwrapped.
It can be non-optional if you programmatically create your home screen and add User to its init. (This fairly straightforward idea often goes by the IMO confusing name of "dependency injection" rather than the obvious name of "passing parameters.") This tends to spread through the whole system, requiring that most view controller be programmatically created. That does not mean you can't use Storyboards (or simpler XIBs), but it does typically mean you can't use segues and will need to handle navigation more programmatically to pass your properties through the system.
This approach lets you make strong requirements for the existence of various properties at each point that you need them. It is not all-or-nothing. You can have some screens that use optionals, some that use implicitly unwrapped optionals, and some that are programmatically created. It's even possible to evolve an existing system over to this a few pieces at a time.
To your last paragraph, there is a common technique of a shared instance that is implicitly unwrapped and gets assigned early in the program's life. You then have to promise not to call any of the "main" code before you initialize it. As you note, that means if it isn't called correctly, it will crash. Ultimately there is either a compile-time proof that a value must exist, or there is only a runtime assertions.
You prove that a value must exist by passing it. You implicitly assert the the object should exist by using !. If it's possible for a developer to call the code incorrectly, then it's not a proof.
The correct design pattern is exactly what you are doing. When you have a data that won't be present at initialization time, make the property that holds it an Optional. nil means the data is not yet present; non-nil means that it is. This is completely standard stuff. Just keep doing it the way you are doing it.
If what bothers you is the fact that you have to fetch this thing as an Optional in every method that deals with it, well, tough. But at least the Swift language has nice techniques for safe unwrapping. Typically the first thing you will do in your method is to unwrap safely:
func f() {
guard let myData = self.myData else { return }
// and now myData is not Optional
}
The only I thing I would advise against here is the splash screen. What if the data never arrives? You need to show the user something real, perhaps with actual words saying "please wait while we fetch the data". You need to plan for possible timeout. So, what I'm saying is, your proposed interface might need some work. But your underlying technique of using an Optional is exactly right.

What does this block mean in Swift - Alamofire?

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

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

UILexicon in Objective-C

How do you use UILexicon in Objective-C? I find the documentation Apple provides is extremely unhelpful.
What does it do? Does it return a dictionary or proper spellings of words? Or do I provide a word like "hellllo" and it matches it with the proper spelling "Hello" and returns that as a string?
Any help would be appreciated.
requestSupplementaryLexiconWithCompletion:
Here's my error report, but obviously I'll have errors because I'm completely guessing how to use the function, no clue what goes inside the block statement (because the docs (at the time) don't say! (Beta 4 docs)) Hahahah!
I've never used this feature, but a quick web search for "UILexicon" landed me in Apple's documentation; reading and following links from there filled in the picture pretty quick.
App Extension Programming Guide has a quick explanation of what lexicons are for:
Every custom keyboard (independent of the value of its RequestsOpenAccess key) has access to a basic autocorrection lexicon through the UILexicon class. Make use of this class, along with a lexicon of your own design, to provide suggestions and autocorrections as users are entering text.
Clicking the UILexicon link on that page took me to the reference doc for that class, which explains that it's a read-only list of Apple-provided term pairs. Each of its entries is a UILexiconEntry object -- the docs for that class say it provides a userInput (what the user typed, e.g. "ipad") and a documentText (what to substitute for it, e.g. "iPad"). Since those classes are read-only, it follows that they're probably not a way for you to provide your own autocorrection pairs -- as stated in the docs, they're for supplementing whatever autocorrection system you implement.
At this point, I don't even have to look at the doc for requestSupplementaryLexiconWithCompletion: to get a good idea how to use it: just the declaration tells me:
It's a method on UIInputViewController, the class I'd have to subclass to create a custom keyboard. Somewhere in that subclass I should probably call it on self.
Its return type is void, so I can't get a lexicon by assigning the result of a requestSupplementaryLexiconWithCompletion call to to a variable.
It calls the block I provide, passing me a UILexicon object as a parameter to that block.
It's got words like "request" and "completionHander" in it, so it'll probably do something asynchronous that takes awhile, and call that block when it's done.
So, I'm guessing that if I were writing a custom keyboard, I'd call this method early on (in viewDidLoad, perhaps) and stash the UILexicon it provides so I can refer to it later when the user is typing. Something like this:
#property UILexicon *lexicon;
- (void)viewDidLoad {
[super viewDidLoad];
[self requestSupplementaryLexiconWithCompletion:^(UILexicon *lexicon){
self.lexicon = lexicon;
}];
}
Because it's unclear how long requestSupplementaryLexiconWithCompletion will take to complete, any place where I'm using self.lexicon I should check to see if it's nil.
Back in the App Extension Programming Guide, it lists "Autocorrection and suggestion" under "Keyboard Features That iOS Users Expect", right before saying:
You can decide whether or not to implement such features; there is no dedicated API for any of the features just listed
So it sounds like autocorrection is something you have to do yourself, with your own UI that's part of the view presented by your UIInputViewController subclass. The API Quick Start for Custom Keyboards section in the programming guide seems to hint at how you'd do that: use documentContextBeforeInput to see what the user has recently typed, deleteBackward to get rid of it, and insertText: to insert a correction.

Resources