NEW: Nominations are now open for the 2019 Swift Community Awards! >>

Custom subclasses of NSObject

You already created your first custom class when you created the collection view cell. But this time we're going to do something very simple: we're going to create a class to hold some data for our app. So far you've seen how we can create arrays of strings by using [String], but what if we want to hold an array of people?

Well, the solution is to create a custom class. Create a new file and choose Cocoa Touch Class. Click Next and name the class “Person”, type “NSObject” for "Subclass of", then click Next and Create to create the file.

NSObject is what's called a universal base class for all Cocoa Touch classes. That means all UIKit classes ultimately come from NSObject, including all of UIKit. You don't have to inherit from NSObject in Swift, but you did in Objective-C and in fact there are some behaviors you can only have if you do inherit from it. More on that in project 12, but for now just make sure you inherit from NSObject.

We're going to add two properties to our class: a name and a photo for every person. So, add this inside the Person definition:

var name: String
var image: String

When you do that, you'll see errors: "Class 'Person' has no initializers." Swift is telling us that we aren't satisfying one of its core rules: objects of type String can't be empty. Remember, String! and String? can both be nil, but plain old String can't – it must have a value. Without an initializer, it means the object will be created and these two variables won't have values, so you're breaking the rules.

To fix this problem, we need to create an init() method that accepts two parameters, one for the name and one for the image. We'll then save that to the object so that both variables have a value, and Swift is happy.

init(name: String, image: String) {
    self.name = name
    self.image = image
}

Our custom class is done; it's just a simple data store for now. If you're the curious type, you might wonder why I used a class here rather than a struct. This question is even more pressing once you know that structs have an automatic initializer method made for them that looks exactly like ours. Well, the answer is: you'll have to wait and see. All will become clear in project 12!

With that custom class done, we can start to make our project much more useful: every time a picture is imported, we can create a Person object for it and add it to an array to be shown in the collection view.

So, go back to ViewController.swift, and add this declaration for a new array:

var people = [Person]()

Every time we add a new person, we need to create a new Person object with their details. This is as easy as modifying our initial image picker success method so that it creates a Person object, adds it to our people array, then reloads the collection view. Put this code before the call to dismiss():

let person = Person(name: "Unknown", image: imageName)
people.append(person)
collectionView.reloadData()

That stores the image name in the Person object and gives them a default name of "Unknown", before reloading the collection view.

Can you spot the problem? If not, that's OK, but you should be able to spot it if you run the program.

The problem is that although we've added the new person to our array and reloaded the collection view, we aren't actually using the people array with the collection view – we just return 10 for the number of items and create an empty collection view cell for each one! Let's fix that…

SAVE 20% ON iOS CONF SG The largest iOS conference in Southeast Asia is back in Singapore for the 5th time in January 2020, now with two days of workshops plus two days of talks on SwiftUI, Combine, GraphQL, and more! Save a massive 20% on your tickets by clicking on this link.

MASTER SWIFT NOW
Buy Testing Swift Buy Practical iOS 12 Buy Pro Swift Buy Swift Design Patterns Buy Swift Coding Challenges Buy Server-Side Swift (Vapor Edition) Buy Server-Side Swift (Kitura Edition) Buy Hacking with macOS Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with Swift Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Beyond Code

Was this page useful? Let us know!

Average rating: 4.8/5