Skip to content
loading...

Explain iOS development like I'm five

Ben Halpern on August 02, 2018

I've been getting into iOS development and Swift, and I'm getting to like it. I sort of know how I could do most things, and I've happily been goin... [Read Full]
markdown guide
 

Where do I put reusable functions?
I think that depends on where or how you plan to reuse them. If a function is shared by related classes, perhaps you can place it somewhere along the class heirarchy where they can be inherited by subclasses. If a function is shared by classes that are not exactly from the same hierarchy, you can look into using extensions.

Another option would be to create a Helper/Utility class that can be used anywhere, although some people say that having utility classes can violate the purpose of object-oriented design.

What is AppDelegate's role?
I like to think of it as the middle man between your app and the operating system. iOS calls the AppDelegate to inform your app about its lifecycle events so your app can handle them accordingly. Examples of these events are: when the app is about to go to the background, when it's about to be terminated, and when it's opened from a URL. Delegates are a huge and important part of iOS development.

Where would I put my models?
The link posted by Casey Brooks is similar to how projects I have worked on are usually organized. I think it's a good jump off point. :)

Is it more of a "one right way" or a "many right ways" kind of culture?
I'm no expert, but I think there's always several ways of building something. Your design should depend on what works for your situation. Although there are prevalent best practices and design patterns, at the end of the day it's still best to tailor-fit all these to your specific needs.

What do web developers typically least understand about iOS development?
I dabble on some web development from time to time, and if I am to put myself in the shoes of a web dev with no prior experience in iOS development, I think it would take a while for me to wrap my head around how building for iOS (or mobile development in general) takes you a bit closer to the hardware. You have to optimise for smaller screens, smaller memory, and sometimes you have to communicate with lower-level elements. The OS can also meddle with your app's life cycle. For example, if your app takes too long to wrap things up while performing background processes, iOS will terminate it.

Again, I'm no expert myself. But I hope these somehow shed more light into the world of iOS development :D

 

What is AppDelegate's Role?
The tl;dr version: App Delegate is a place to handle system-level events that relate to the application as a whole, not something within the application. Any object that becomes the app's delegate can handle events like "what happens when the application launches," "what happens when it goes into the background," "what happens when it comes back into the foreground," "what happens when it receives a remote notification," etc.

The longer version has to do with the concept of delegation, which is a really fancy way of saying "I want to make someone else or something else do the thing and I don't really care how it does it."

In daily life, we are surrounded by all kinds of delegates. When you run the dishwasher, you are delegating the task of washing the dishes to a machine. The dishwashing machine is your dish washing delegate.

You don't necessarily care how it goes about washing the dishes, so long as you can tell it when to start, and that you can get your dishes when you're done. A dishwashing delegate doesn't even need to be a dishwashing machine. Plenty of people working in restaurants make a living acting as the dishwashing delegate for the people enjoying dinner in the dining room.

The only thing that matters is that the delegate can wash the dishes. That's it.

AppDelegate is somewhat different in an interesting way. When you implement it, you're on the other side of the deal. You are the one being told that there's important stuff to do, and it's up to you to decide how to handle the situation.

Apple is saying, "hey there are some events you might want to handle. They're pretty fundamental and relate to your application being able to function in a way that pleases your users. We don't care how you handle them. Here's what those events are. Now get to it."

You see this as the UIApplicationDelegate protocol. It's just a list of methods such that when you implement them, you decide how your app handles those high-level events.

Any object can implement the UIApplicationDelegate protocol, but only one object can act as the AppDelegate for a given application. Otherwise the wires would get crossed and your program wouldn't be able to decide which way to handle the events.

In most projects, all of this work is taken care of for you. You are given an object that already conforms to the UIApplicationDelegate protocol, and it's denoted with "@UIApplicationMain" to signify that it's the only one your app is going to use. All you have to do is fill in the blanks for the methods already implemented.

Things like:
applicationDidFinishLaunching() - Triggered when the app just launched for the first time
applicationWillTerminate() - Triggered right before the system kills your app
applicationDidEnterForeground() - Triggered when you restore your app from the background

The list goes on.

It's also important to understand what not to do in your AppDelegate. You really shouldn't be doing anything other than handling events that occur at the application level. So don't put your reusable functions in there. Move them to a separate class with its own namespace, and if you do need to use them when your app starts up, simply call them instead.

I've seen projects where they've stuffed all of the code into the App Delegate and it was horrendously difficult to figure out what's going on. Don't do that. AppDelegate is single-purpose. Use it for the thing it was designed to do.

 

I recently started diving into Swift as well. My hot tip would be to skip all the google results, and go straight for Apple's docs. Kind of the opposite of what I've experienced with other ecosystems. For example, their HTTP guide and JSON decode/encode guide are super comprehensive. The inbuilt documentation feature in Xcode is really good, I didn't even realise it was there until a few months in (Try option+click on a type).

Function re-use within a project

Go straight for a protocol. The whole language seems to be designed for 'protocol oriented programming', and Cocoa leans on it heavily. Create protocols with default implementations of functions with generic types. For example, the EntityObject protocol in Amatino Swift.

Function re-use across projects

Re-using functionality across projects seems to be a bit of a hair-ball. Whereas in Python or JS we can create self-contained modules, publish them to PyPi/NPM, and use them across projects, in Swift the community seems split between Carthage and CocoaPods. Neither are as turn-key as pip install x or npm install y.

 

+1 for using the Apple docs. They are the best way I've found to get a real understanding of how a framework is used and the functionality it provides. The Xcode builtin docs are really great as well and save a ton of time when you just need a quick method definition or signature.

I'm in the CocoaPods camp myself. It's what I used when building open source frameworks, mainly because I started using it before Swift and Carthage came around and I'm waiting for Swift Package Manager to become more stable before I switch over.

 

I've done a little bit of swift in before and can answer a handful of the questions.

Reusable functions

Swift allows methods to be static meaning you can call them without having to call a new instance of the class, similar to Java. I tend to make a class dedicated to them if needed for example:

class Helper {
  static func postRequest() -> [String:String] {
    return ["something here" : "something also here"]
 }
}

Can then be called like so

Helper.postRequest()

Additionally i found it's possible to use structs as well as extensions

struct BackendError {
    var message : String
}

struct SuccessCall {
    var json : JSON

    var containsError : Bool {
        if let error = json["error"].string {
            return true
        }
        else {
            return false
        }

    }
}

typealias FailureBlock  = (BackendError) -> Void
typealias SuccessBlock  = (SuccessCall) -> Void

typealias AlamoFireRequest = (path: String, method: Alamofire.Method, data: [String:String]) -> Request
typealias GetFunction = (path: String , data: [String : String], failureBlock: FailureBlock, successBlock: SuccessBlock) -> Void

class Backend {
   func getRequestToBackend (token: String )(path: String , data: [String : String], failureBlock: FailureBlock, successBlock: 

}

Extension example


extension Array {
    func sampleItem() -> T {
        let index = Int(arc4random_uniform(UInt32(self.count)))
        return self[index]
    }
}

AppDelegate

It kind of acts like a template of basic code needed to run the project out of the box. From this example it shows that its using the UIKit framework, and by seeing this we can see that the class needs to have some form of connection to the user interface

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

  var window: UIWindow?
}

The @UIApplicationMain attribute indicates that the application delegate is using this function and passing the class's name as the name of the delegate class.

Ways

I think that with swift there is multiple right ways, with the little experience I found that multiple methods and ways of doing something can always work as intended.

I believe majority of this info is correct, my swift knowledge is pretty low. But hope it can help in some way :p

 
 

Where do I put reusable functions?

It depends :) If, say, you wanted to have a function that does something with a string, like see if a string ended with "!" and you used it a lot. This might be a good candidate for a Category extension (similar to monkey patching in other languages).

It's easy to go overboard with this, but IMO it's a wonderfuly powerful tool.

You can still make "static" methods (called class methods in ObjC) and put them in some Util class.

What is AppDelegate's role? Other have answered this much better than I could.

Where would I put my models? Separate from your View for sure! iOS is super heavy on MVC. Your model should strive to be as decoupled from your view as possible. This makes it easy (or possible) to write good unit tests for your model.

One mental trick is to consider writing your Model in C++. You don't have to actually do this but it helps enforce how separate your model should be from the rest.

Is it more of a "one right way" or a "many right ways" culture?
I think it leans a bit toward "one right way" but it's not super strict. There is a tendancy toward protocols (equivalent to other languages), verbosity, and common design patterns.

Is Swift "culture" different from Obj C in any meaningful way?
The main "culture" difference is that ObjC is for apps that were originally written before Swift (or before Swift was a couple years old).

No one is doing a full rewrite of their existing ObjC app in Swift (at least they shouldn't be).

You can use the two together, so most new code should be in Swift (with some exceptions as always).

However, there is still a lot of apps that are mostly written in ObjC, so it's not going away anytime soon.

The only other culture difference is that ObjC is pretty loose with nil, while Swift is very explicit about it with Optionals.

What do web developers typically least understand about iOS development?

With app dev (iOS or Android), you're pretty locked into your API design. On web, if you want to add a new field or remove an existing field from some request, it's pretty easy. Update the backend, deploy the change to your web servers and done.

With app, you can have old versions of your app in the wild years later, so backwards compatibility is king.

 

I've done a good amount of iOS (Swift/Objective-C) development, so I'll give my experience on some of this:

What is AppDelegate's role?

The AppDelegate delegates events from the system to your app like launch, going to the background, etc.. Delegation is an important concept in iOS dev and is used a bunch throughout the system (i.e. UITableViewDelegate. UICollectionViewDelegate) and leverages Protocols to allow objects to communicate with each other.

Where would I put my models?

I structure my iOS apps similar to Rails app/ (with less starting directories) using an MVC pattern. So I'll start with a Models, Controllers and Views directories, then add other folders/groups like Services, Presenters/ViewModels, etc.. as necessary. There are some other app architectures like MVVM, Viper that are gaining popularity, but iOS and the underlying API's have been built following MVC.

Is it more of a "one right way" or a "many right ways" culture?

This is an interesting question I haven't really thought about before. I would say it's more of a "one right way" culture. Apple normally hint's (sometimes subtle, sometimes not) about how they wan't things done in there WWDC presentations

Is Swift "culture" different from Obj C in any meaningful way?

I don't know if it would be considered a cultural difference but Objective-C is a very object oriented language, while Swift is a protocol-oriented programming language and although you can solve any thing in Swift in an object-oriented way, there seems to be a strong push to solve things using Swift's protocol oriented features.

 

While I'm an Android dev and have never personally worked with iOS, a guy on the iOS side of my project at work had recently written an article for my company's blog about how to structure code for iOS apps which might be helpful for you.

Organizing an iOS Project

 

Cool thanks!

Still open to any and all pro tips on this subject :)

 

Is Swift "culture" different from Obj C in any meaningful way?

Yes, and in one key way that permeates the structure of Swift to the very foundation.

That difference is optionals.

Swift is a language that makes you be explicit and up-front about the things you have and the things you don't have. This is enforced via optionals.

In Swift, you can't create an instance of a class with uninitialized properties without also declaring that those properties can't be expected to have a value.

So something like this isn't allowed:
Not allowed

It's not allowed because there is no initializer for the RGBColor class that lets someone give the red, green, and blue properties a default value.

But if you add an initializer, you're back in the game because you've given Swift a way to create your entity in a way that gives each property a default value.

This, however, is allowed:
Class with an initializer

Optionals are sort of like an "IOU." They're a way of saying, "I don't have what you're looking for now, so please give me a pass and let me get it to you later."

That's why this is also allowed:
Optionals

You can make an instance of RGBColor without setting any of those properties because they are all some sort of optional

! or ? are just two sides of the same coin.

? is a way of saying "this may or may not have a value, so please tread with caution."

! is a way of saying "this doesn't have a value right now (at the moment of class initialization), but I swear it's gonna have a value when you need it. Trust me!

The compiler treats these two entities very differently. With ?, you aren't allowed to reference a value without carefully "unwrapping" it in a way that doesn't assume the value is there.

However, with !, you are telling the compiler to trust that you know what you're doing, so if you try to access that value and it's nil, the app will simply crash. It's your own damn fault too because you said the value was gonna be there.

All of this gets to the core of the cultural difference between Swift and Objective-C. When you have to be explicit about the things you have, might or might not have, and swear you're gonna have, you write your code in fundamentally different ways. By extension you communicate differently and a new culture evolves out of that.

Swift devs really like these compound statements that unwrap all of the optionals in a single stroke, something the new guard command lets you do.

Objective-C devs aren't as explicit about the things they have and don't have, so you have to do some digging to figure out which properties are always going to be populated and which ones might not be.

Generally speaking, Swift builds upon Apple's penchant for writing code that is explicit and up-front about what it does. It takes the concept further by enforcing up-front-ness with respect to the availability of data via optionals.

You can see a similar attitude in Objective-C, which strongly encourages clarity at the call site (another form of being explicit) by forcing you to use external parameter names in your functions. That way, when someone uses your function, they know what they're passing in without guessing or reading documentation.

It's the difference between:

add(1,2)

and

add(leftSide: 1, rightSide:2)

The latter is waaaay more readable. You get what the arguments are for by simply looking at the usage of the function. There's no need to dig into the documentation.

Swift follows a uniquely Apple tradition of improving the developer's experience by making code as clear and concise as possible. To be culturally "Swifty" simply means you care more about these things than the previous generation.

 

I'm currently learning iOS on my free time and would also like to know these things.

 
 
Sloan, the sloth mascot Comment marked as low quality/non-constructive by the community View code of conduct

Hello, I'm an IOS developer. Recently, when using swift to develop applications, I found that there are few caches written by pure swift. So I wrote a cache -- swiftlycache, a lightweight general-purpose IOS cache library using swift 5. If you are using swift for development, if you also need to use cache, maybe you can try swiftlycache, maybe you will like it, If you like, you can also introduce it to your friends. Thank you
github.com/hlc0000/SwiftlyCache

code of conduct - report abuse