Swift has been easily the best and most comfortable language I've known in my career, and it was a great benefit to really get into it just as it came out. At this point I've completely let go of Objective-C, which may still be slightly tricky as many companies do still want you to work in Objective-C often for legacy purposes. But I figured some time along the line when I get to the point that I have to look for more work, the tables will have turned. That stated, it remains a great time to get started with Swift.
Object and class structures really aren't that different in Swift. You'll still use the same common sense logic to separate segments of a scene into classes as you would in Objective-C. So if two separate areas or modalities can be separated in different SKScenes, do so. It'll cut down on the management of states of your game and interface. Next try to recognize any repeating elements of your game, functionalities that could be independent or things that would better serve as almost plug-and-play components, and separate those into classes with a healthy serving of common sense (you also don't want to overdo it). Remember to also think what your class will be subclassing - which in the case of SpriteKit would normally be SKNode.
Here's a super simple relationship between an SKScene and a custom class that subclasses SKNode. In this example MyScene has its own hardcoded property, which is passed to the MyObject object upon creation. MyObject then just takes that variable, passed along in a convenience initializer, and sets it as the value of its own property (which by the way is a implicitly unwrapped optional, with the exclamation point and all). Finally MyScene prints that variable directly from the object property.
MyScene.swift
import SpriteKit
class MyScene: SKScene {
let sceneVariable = 1
override func didMove(to view: SKView) {
let object = MyObject(variable: sceneVariable)
addChild(object)
print(object.classVariable)
}
}
MyObject.swift
import SpriteKit
class MyObject: SKNode {
var classVariable: Int!
convenience init(variable: Int) {
self.init()
classVariable = variable
}
override init() {
super.init()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
There are some clear improvements that Swift + Xcode offer that should be stated here. First, there are no separate header .h and method .m files. Everything can be encapsulated into that one .swift file. Second, classes, variables and properties are automatically universally available within a project to whatever hierarchy level you declare them. So no more importing of class files, which is just such a hassle-saver. This also makes it really easy to have global variables without a singleton class. If you want to make variables private to wherever they are, you have to separately declare them as private. Third, connected to the previous points, there is no need to make properties and synthesize them. Instance variables of a class are completely straightforward.
To get started with the Swift language itself I would focus on the following things:
- Understanding the use of var and let properties. It's very simple once you get it and Xcode will keep you in correct form anyway 🙂.
- Letting Swift infer as much information as possible. Instead of overly defining property types and other stuff, it's good practice to let Swift infer everything it can, unless you specifically want something else. So you should prefer let variable = 4.0 over let variable: Double = 4.0, because both will end up as Double types.
- Learning optionals and their different manifestations. This can be a bit of nut to crack, but when you start to understand it, handling optionals will become second nature. It's important to learn why they're so important, how to properly wrap and mostly unwrap them, what the implications are to having very secure code, taking responsibility of said security implications and other stuff. Important terms here would be optional binding, optional chaining, implicitly versus explicitly unwrapped optionals, etc.
- The increased emphasis on structs as an alternative to classes. I'm not personally so into structs, but I guess they have their audience.
- Verbosity in naming functions and properties. You'll be more respected the more readable and descriptive your code is. For example, you would prefer func runAirConditioner() over func runAC().
- Designing smarter functions. In addition to verbosity, you will want to be more efficient with your function definitions. You should look into specifying argument labels for parameters, omitting argument labels, defining default values for parameters, and if you really want to geek out, find out about variadic and in-out parameters. For example, a traditional function like func moveBalloonWithDelay(balloonNumber: Int, balloonPosition: CGFloat, delay: Double) would turn into moveBalloon(_ number: Int, to position: CGFloat, with delay: Double = 2.0), where number is omitting the label, position and delay are specifying it and delay is establishing a default in case no value is given.
Anyway, that's probably enough to get you started 😀. I would really recommend checking out this WWDC talk: https://developer.apple.com/videos/play/wwdc2016/404/. It goes into great detail about how to approach Swift as a newcomer.