Quantcast
Channel: Kodeco | High quality programming tutorials: iOS, Android, Swift, Kotlin, Unity, and more
Viewing all 4374 articles
Browse latest View live

Introduction to the SpriteKit Scene Editor

$
0
0
Update 05/12/17: Updated for Swift 3.1, iOS 10 and Xcode 8.3 by Caroline Begbie. Original tutorial by Morten Faarkrog.
SpriteKit Scene Editor

Run, run, run!

Did you know that creating game levels can be easy, fun and done with almost no contact with code? In this tutorial, you’ll learn how to do just that using the powerful SpriteKit scene editor.

You’ll create a fancy level for a spooky 2D zombie game named Fear the Dead. In the process, you’ll learn:

  • What the scene editor is, how to navigate its layout, and how you can add sprites to it
  • How you can use file references to reuse an SKScene
  • How to create a dark vibe using an SKLightNode
  • How to work with SKCameraNodes
  • How to use the Action Editor to add animations to nodes without any code
  • How to use SKAudioNodes to create positional audio
  • How to survive a zombie apocalypse. :]

As you can see we have a lot to cover, so let’s get started!

Note: This SpriteKit scene editor tutorial assumes that you already know the basics of Swift as well as the basics of the SpriteKit. If you’re new to Swift, check out the Swift Apprentice book, and if you’re new to SpriteKit, check out the SpriteKit Swift 3 Tutorial for Beginners.

Getting Started

In order to get you up and running without a bunch of noise, download the starter project for this tutorial. It’s based on the SpriteKit Game template and already has some of the more tedious work done for you.

This way you can focus on creating an awesome zombie-rich environment level without tinkering with all the underlying logic. The starter project comes with:

  • The logic needed for actually playing the game, including the logic for moving around the player and the zombies, as well as logic for when these collide.
  • All the sounds and images you need.
  • A MenuScene that denotes the end of a game and also gives the option to restart the game.

Once you’ve downloaded and unzipped the project, open it in Xcode and build and run. After the splash screen intro, you should see the following appear on your device or in the simulator:

SpriteKit Scene Editor

As you can see, there’s not much to play with yet, so let’s get started with the scene editor, shall we?

The Scene Editor

First, a bit about the game you’re building. Fear the Dead leads you on a nail-biting adventure where you have to escape from one room into another without being bitten by nasty, infected zombies. For a full-blown game, there would be tons of exciting levels.

Creating levels in code, however, can be very tedious and cumbersome, and could lead you to become one of the zombies you’re trying to escape. This is where the scene editor, a built-in Xcode tool designed to help you build levels without having to write everything in code, comes in.

Setting up the Scene

In the project navigator, locate the Scenes folder and select the file GameScene.sks. You’ll see an editor panel that shows a gray background as shown in the screenshot below:

SpriteKit Scene Editor

The scene hierarchy appears to the left of the editor panel. When you have multiple elements in the scene, you can select them here. You can even drag and drop to rearrange parent / child relationships.

Click the button in the lower right corner until you see a black rectangle appear. This is the boundary of your scene and all of your level’s components will be placed within this. Alternatively, you can also pinch your trackpad to zoom in and out. You should now have a view similar to:

SpriteKit Scene Editor

When creating a new scene, the default scene size is 750 x 1334 pixels, but you want your level to be a bit bigger. First, make sure you have the utilities editor open on the right-hand side, and select the Attributes Inspector.

If you do not see the utilities editor, simply click View\Utilities\Show Attributes Inspector and it should show itself. Next, change the dimensions of the scene to be 1080 x 1920.

SpriteKit Scene Editor

Awesome! The scene is now ready for you to add some elements to it.

The Object Library

SpriteKit Scene Editor

At the bottom of the utilities editor, select the Object Library.

The Object Library displays all the different objects you can drop onto your scene and configure. In this tutorial you’ll be working primarily with Color Sprites, but there many other objects to choose from, including:

  • Shape Node: a node that allows you to easily draw squares, circles and other shapes with Core Graphics paths.
  • Label: you’ve probably used labels in your games before, and this one is no different. However, this time you’ll be able to easily place it on the screen and edit it with a few clicks.
  • Light: A very cool object you can add is a light, and by placing one on your scene you get a spotlight effect; you can then make your other objects cast shadows. You’ll add a light later in the tutorial. :]

If you’ve used SKSpriteNodes in other games, then you’ll already be familiar with the configuration options that come with a Color Sprite. You can determine the node’s size, position, texture and even add a physics body to it.

Here’s the best part: you don’t have to manage these in code nor re-run your program every few seconds to make sure everything is placed correctly. Quite neat, right?

Adding a Player Sprite

So how about you add a sprite to the scene?

Drag and drop a Color Sprite from the Object Library onto the scene. You’ll notice that the sprite is selected by default and that a ton of properties are shown in the Attributes Inspector to the right.

SpriteKit Scene Editor

Most of these properties should be recognizable. You can set the sprite’s name, position and anchor point, its parent node and the image file you want to use as the texture.

The default anchor point for the scene is X: 0.5, Y: 0.5. If you add a node to the scene with position X: 0, Y: 0, the node will be exactly at the center of the scene.

To position a node on the left of the scene, you’ll use negative X values, and to position the node in the bottom half of the scene, you’ll use negative Y values.

Make this sprite your player by changing the following properties:

  • Name: player
  • Texture: character
  • Position: (-340, 520)
  • Size: 75 x 75

But wait! There’s more. If you scroll further down the Attributes Inspector, you’ll notice a section called Physics Definition where you can set the body type of your sprite. That way you don’t have to define it in code. Awesome, right? 

When it comes to body type, you have three different options to choose from:

  • Bounding rectangle: This sets the body be the exact size of the node.
  • Bounding circle: This sets the body be a circle with a diameter the size of the node’s longest side.
  • Alpha mask: This makes SpriteKit define the physical shape of your node based on the outline of the sprite’s texture image – unless you’re working with rectangles and/or circles, this is the most accurate one of the three.

SpriteKit Scene Editor

Generally, you want to choose the simplest possible shape to get the desired accuracy you need for your game, as the more complicated the shape, the higher the performance cost. For this game, you want collisions to be very accurate (after all, it’s hard enough to survive a zombie apocalypse), so you will choose alpha mask.

With the player node selected in the scene, click the Body Type menu and select Alpha mask. Next, uncheck Allows Rotation and Affected By Gravity as neither are needed for this tutorial. Finally, change the Category Mask to 1.

Note: The category mask will come into play later to detect contacts between the player and other nodes.

As previously mentioned, Fear the Dead will also use lighting to create a spooky feel. To ensure that the game is ready for this, set the Light Mask, Shadow Cast Mask and Shadowed Mask of the player to be 1.

SpriteKit Scene Editor

One last thing before you build and run. Open GameScene.swift and add the following lines to didMove(to:), right after the contact delegate has been set:

// Set up player
player = childNode(withName: "player") as? SKSpriteNode

With this simple line of code you have hooked up the player sprite from the scene editor to the actual code inside GameScene.swift. This works because you set the name of the sprite to “player” inside the scene editor earlier.

Easy, right? Build and run the game and you should now be able to move the player around by touching the screen. Oh yeah, progress!

SpriteKit Scene Editor

Adding Zombie Sprites

Now that you know how to add a sprite it’s time to practice by adding some brain-hungry zombies to the mix! In this level, you’ll add five zombie sprites. Every zombie sprite will have a unique position but all will have the following properties:

  • Name: zombie
  • Texture: zombie
  • Size: 50 x 50
  • Lighting, Shadow Cast and Shadowed Mask: 1
  • Body Type: Alpha mask
  • Allows Rotation & Affected By Gravity: Disabled
  • Category Mask: 2
  • Contact Mask: 1
Note: A time-saving trick is to set this up for one zombie, then copy and paste the zombie using Command-C and Command-V. (In Xcode 8.3, duplicating the zombie with Command-D causes a crash.) Change the positions appropriately. Unfortunately you’ll also need to change the Physics attributes as they don’t copy.

Now, add five zombie sprites with the following positions using the above properties.

  1. (330, 750)
  2. (-340, -160)
  3. (330, 140)
  4. (-390, -810)
  5. (410, -410)

Done? Awesome! Your game scene should now have five zombies in these positions:

SpriteKit Scene Editor

So, there is a little more coding to do. You didn’t actually think that you could get out of a tutorial with zero coding, did you?

Just like you did with the player, you need to add a few lines of code before these zombies will operate with the rest of the game. Open GameScene.swift, and add the following lines to didMove(to:) right after the line where you set up the player:

// Set up zombies
for child in self.children {
  if child.name == "zombie" {
    if let child = child as? SKSpriteNode {
      zombies.append(child)
    }
  }
}

These lines will find every child node with the name zombie and add them to an array of zombies – that sounds truly terrifying!

Build and run the game and the zombies should now be chasing you. Yikes! Hope you’ve been keeping up on your cardio.

SpriteKit Scene Editor

Adding a Goal, Walls and a Background

All this running about is tiresome, and the zombies have you trapped. Your player might as well be the main course at a buffet as far as they are concerned.

Wouldn’t it be great to have a way to complete the level by adding a goal?

Open GameScene.sks. Select a Color Sprite from the Object Library and drop it on the scene. Then add the following properties to the sprite:

  • Name: goal
  • Texture: goal
  • Position: x: 515, y: -825
  • Size: 50 x 170
  • Light, Shadow Cast, and Shadowed Masks: 1
  • Body Type: Bounding rectangle
  • Dynamic, Allows Rotation & Affected By Gravity: Disabled
  • Category Mask: 3
  • Contact Mask: 1

Your game scene should now look like this:

SpriteKit Scene Editor

Just like before, you’ll need to set up this sprite in code. Open GameScene.swift, and add the following lines to didMove(to:) right after the lines where you set up the zombies:

// Set up goal
goal = childNode(withName: "goal") as? SKSpriteNode

When running the game, it’s hard to tell where the boundaries of the level are. In order to fix this you’ll need some walls around your level. You’ll add four walls with the following properties:

  • Light, Shadow Cast, and Shadowed Masks: 1
  • Body Type: Bounding rectangle
  • Dynamic, Allows Rotation & Affected By Gravity: disabled

In GameScene.sks, add four color sprites to the scene for the four walls with the above properties and customize the position properties as follows:

Wall 1:

  • Texture: wall_50x1920
  • Position: (-515, 0)
  • Size: 50 x 1920

Wall 2:

  • Texture: wall_50x1700
  • Position: (515, 110)
  • Size: 50 x 1700

Wall 3:

  • Texture: wall_1080x50
  • Position: (0, 935)
  • Size: 1080 x 50

Wall 4:

  • Texture: wall_1080x50
  • Position: (0, -935)
  • Size: 1080 x 50

Good job! Your game scene should now look as follows:

SpriteKit Scene Editor

Last, but not least, add a background to the game scene. Select a Color Sprite from the Object Library and drop it on the scene. Add the following properties to the sprite:

  • Name: background
  • Texture: background
  • Position: (0, 0)
  • Z-position: -1 (This layers the background behind all other nodes.)
  • Size: 1080 x 1920
  • Light Mask: 1

Control-click background in the scene hierarchy and choose Locked. This will allow you to still drag the scene around when zoomed in (as long as you don’t click on any other sprites!).

Build and run the game. As you run around the level the walls should keep you in place – see if you can get to the goal before the zombies get to you.

SpriteKit Scene Editor

Camera Positioning with SKCameraNode

Being able to view the whole level at once isn’t really the best experience. The player and the zombies look too small, and the game feels a bit too predictable. To fix this, you’ll just need to implement a camera node.

Using a SKCameraNode, you can specify the rendering position of the scene. Because the camera is a node, it can be moved just like any other node in the scene using actions, physics and so on. When a scene renders with a camera node, two things happen:

  1. The scene renders so that the origin of the camera node is placed directly in the middle of the scene.
  2. The inverse of the camera node’s xScale, yScale and zRotation properties are applied to all nodes in the scene.

What this means is that if, for example, the camera is moved 20 pixels to the right, then the scene is rendered as if everything else moved 20 pixels to the left. If the camera is scaled by (0.5, 0.5) then only a quarter of the screen will show.

Adding a Camera to the Scene

So now you might be wondering – possibly even dreading – whether the camera node is something you’ll have to create programmatically. The answer is, as you might expect, that you can create it using the scene editor. Whew!

In GameScene.sks, go to the Object Library, and locate the Camera node. Next, drag and drop it onto the scene. Open the Attributes Inspector, and change these properties:

  • Name: camera
  • Position: (0, 0)
  • Scale: (0.5, 0.5)

The camera’s position doesn’t have to be exact as it’s updated in code as the player moves, but centering it keeps the scene tidy.

SpriteKit Scene Editor

If you were to run the game right now, the camera would not yet be activated because you need to tell the game scene to use the camera node as its camera.

Click Scene in the scene hierarchy to select the scene and set its Camera property to the camera node you just created.

SpriteKit Scene Editor

With this done, the camera should work as expected. Good job! Build and run the game and you should now only see a quarter of the level at any given time. The camera should also follow the player as you move it around.

SpriteKit Scene Editor

Reference Nodes

The scene editor allows you to reference content between different .sks (scene) files, meaning you can put together a bunch of sprites in a single archived scene and then reference the archive from another scene.

You might wonder why you would need more than one scene. There are a couple of reasons:

  1. You can reuse the same collection of sprites in multiple different scenes, so you don’t have to recreate them over and over again.
  2. If you need to change the referenced content in all of your scenes, all you have to do is edit the original scene and the content automatically updates in every scene that references it. Smart, right?

Creating a Wall Scene

And now that you’ve read about it, you’ll create some reusable components. For your game, it would be nice if you could add some walls, so kick off this part by adding a wall scene.

In the project navigator, control-click the Scenes folder and from the pop-up menu, click New File…. Choose the iOS/Resource/SpriteKit Scene file template, and then click Next. Call the new file Wall.sks, and save it in the project’s folder.

Xcode automatically opens the newly created Wall.sks file and presents you with an empty editor window. In exactly the same way as before, your task is to resize the scene to your needs and add some sprites. Set the scene size to be 50 x 400 pixels.

Next, select a Color Sprite from the Object Library, drop it onto the scene and add the following properties to it:

  • Texture: wall_50x400
  • Position: (0, 0)
  • Size: 50 x 400
  • Light, Shadow Cast, and Shadowed Masks: 1
  • Body Type: Bounding rectangle
  • Dynamic, Allows Rotation, Affected By Gravity: Unchecked

That’s it – you now have a reusable wall!

SpriteKit Scene Editor

Creating a Room Scene

Now that you have a reusable wall, you have the building blocks to create a new reusable room scene. Just like before, in the project navigator, control-click the Scenes folder and select New File…. Choose the SpriteKit Scene file template, click Next, name the new file Room.sks and save it in the project’s folder. Next, set the scene’s size to be 400 x 400 pixels.

Now, instead of selecting Color Sprite, select a Reference from the Object Library.

SpriteKit Scene Editor

Drag and drop three reference objects onto the scene and give them the following properties:

Wall 1:

  • Reference: Wall – this is the .sks scene archive file you’re referencing
  • Position: (-175, 0)

Wall 2:

  • Reference: Wall
  • Position: (175, 0)

Wall 3:

  • Reference: Wall
  • Position: (0, -175)
  • Rotation: 270

With this in place your room should look as follows:

SpriteKit Scene Editor

Adding Rooms and Walls to the level

Go back to GameScene.sks and add a Reference object from the Object Library for each of the following:

Rooms (Reference / Position)

  1. Room / (-340, 550)
  2. Room / (340, 550)
  3. Room / (-340, -90)

Walls (Reference / Position / Rotation)

  1. Wall / (10, 85) / 90
  2. Wall / (340, -265) / 90
  3. Wall / (340, -580) / 90
  4. Wall / (-165, -755) / 0

That was quite the task, but with these fancy reference objects added your amazing level should look like this:

SpriteKit Scene Editor

Build and run the game to see if you can complete your newly created level. It’s harder than it looks…

SpriteKit Scene Editor

Positional Audio using SKAudioNode

SKAudioNodes allow you to add positional sound right in your SpriteKit game. Best of all, they are super simple to set up.

All you have to do is specify the sound asset that should play back, as well as the node that will be the listener for positional audio coming from SKAudioNodes. With these in place, SpriteKit automatically calculates volume based on the relative distance of the listener and the SKAudioNode, ensuring immersive, positional audio in your game.

A quiet zombie just isn’t right, so let’s add some sound to make them more, um, undead-like. First, open GameScene.swift, locate didMove(to:), and add the following line underneath the setup of the player:

listener = player

This sets the player as the node listening for positional audio.

Next, directly underneath, change the for-loop for adding zombies so that it looks like this:

// Set up zombies
for child in children {
  if child.name == "zombie" {
    if let child = child as? SKSpriteNode {

      // Add SKAudioNode to zombie
      let audioNode = SKAudioNode(fileNamed: "fear_moan.wav")
      child.addChild(audioNode)

      zombies.append(child)
    }
  }
}

Here you first create an audio node with the file named fear_moan.wav, and then add it to the individual zombie. This ensures that the moaning sound comes from the zombie and only the zombie itself.

Before running your code, add an audio node to your scene. Select GameScene.sks, open the Object Library and locate the Audio object. Drag and drop the object on top of the player and set its Filename to be fear_bg and its parent to be player.

Easy, right?

SpriteKit Scene Editor

Build and run the game, and you should be able to hear the zombies moaning and the background music. You should notice the zombie’s audio becoming richer, more centered and louder as it nears the player, which is the listener, and more one-sided and distant as it moves away.

For a more immersive feel, try wearing headphones.

Animations and Action-References

Wouldn’t it be cool if you could also add actions to nodes without having to write it all in code? Well, you can! In the Action Editor View you can drag and drop actions from the Object Library.

To open the Action Editor View, open GameScene.sks and click the Show the Action Editor View icon. This is at the bottom left of the editor panel, to the left of the word Animate:

SpriteKit Scene Editor

The action editor displays all the nodes in the scene and a timeline with rows that correspond to each node. If you’ve ever worked with animation or video software, you might be familiar with this user interface. You’re going to use the action editor to create a nifty zoom-out effect when you first launch the game.

Grab a Scale Action object from the Object Library and drop it onto the timeline track for the camera node. Next, locate the Attributes Inspector for the action up in the upper-right corner, and change the properties as follows:

  • Start time: 0.3
  • Duration: 1.5
  • Timing Function: Ease in, Ease out
  • Scale Amount: 5

SpriteKit Scene Editor

With this action, you scale the camera by a factor of five. However, you don’t want to change the scene-to-camera ratio you previously defined. Therefore, click the camera node in the scene hierarchy and change its scale to be X = 0.1, Y = 0.1. After the action has been triggered, this will end up being 0.5, just like it was before.

Build and run the game, and you should see a cool zoom-out effect happening at launch.

SpriteKit Scene Editor

Creating a Dark Vibe using SKLightNodes

A game called Fear the Dead needs a spooky feel and so far it’s not very spooky. Change this by adding a SKLightNode to the player.

Because lights are nodes, you can move them or set them to perform actions. This means that if you add a light node to the player, it’ll follow the player around as it moves through the level – just the effect needed here.

The light node itself is invisible except for the effects you configure on the sprite nodes to interact with them.

Ah-ha!!! So that’s why I’ve had you setting the light, shadow cast and shadowed masks on all sprites throughout this tutorial. Each property has a different effect:

  • Light Mask: The sprite is illuminated by the light with specular, diffuse and ambient lighting.
  • Shadow Cast Mask: Whenever a sprite intersects with a light, a shadow projects past the sprite.
  • Shadowed Mask: If the sprite is inside a shadow cast by a light, and the sprite has a lower z position than the light, the shadow affects how the sprite is lit.

Time to light it up!

In GameScene.sks, locate the Light object from the Object Library and drop it on top of the player sprite’s torch. Next, change the light’s Parent to player and change its Falloff to 2.

The Falloff denotes the exponent for the rate of decay of the light source, so the higher the number, the spookier and darker the level.

SpriteKit Scene Editor

One more thing before you’re done: The outside of the level is still a very non-spooky gray color. To fix this, select the scene in the scene hierarchy, and change its Color to Black.

Note: At the time of writing, the iOS Simulator is having a hard time running the game without lag after implementing the light. I’d suggest running it on a device, where it shouldn’t cause any problems, or simply disable the light while you build your level.

Build and run the game, and as you move the player, the light will follow him and cast shadows as it moves.

SpriteKit Scene Editor

Note: Xcode 8.3 crashes when SKLightNodes are used on top of Metal (i.e. when you run the game on a device). To overcome this until a further Xcode update, the starter project runs on top of OpenGL. To accomplish this, in Info.plist there is a key PrefersOpenGL set to to YES. You can test to see if the project runs on Metal in future updates by deleting this key.

Normal maps

One of the clever techniques in computer graphics is faking detailed textures by using normal maps. A normal indicates the perpendicular from a surface. This means that if you have a flat plane, the surface normal would point straight up from the plane. By indicating what the normal is at a certain pixel, you can manipulate how that pixel is lit.

Normal maps are RGB images, where red corresponds to the x value of the normal, green to y and blue to z.

Here is the background texture with a normal map. The lit result is on the right. You can see that the texture now appears bumpy and much more interesting.

SpriteKit Scene Editor

The scene editor can automatically generate normal maps, so this effect is really easy to do. In GameScene.sks, select background in the scene hierarchy and change these Normal Map properties:

  • Smoothness: 0.2
  • Contrast: 0.2

Feel free to experiment with the Smoothness and Contrast values to make the cobbles more or less bumpy.

SpriteKit Scene Editor

Note: In Xcode 8.3, the normal map value resets, and the normal map is created from the sprite’s own texture. In this case that is the desired effect.

That’s it! Now you’ve created a terrifying place where zombies run wild. Build and run the game, and you should see the following:

SpriteKit Scene Editor

Where To Go From Here?

Congratulations! You’ve made it to the end of this tutorial and have now built a complete level for Fear the Dead. You have learned a ton of cool new features that you’ll be able to implement in your own projects going forward. You can download the final project here.

One of the best ways to make sure you remember what you’ve learned is to apply it in practice. For that reason, you should try and create another level or maybe even build your own game full of increasingly challenging levels.

We love seeing what you guys come up with, so make sure to share your creations in the comments below or on the forums.

If you want to learn more about SpriteKit, you should check out our book 2D iOS & tvOS Games by Tutorials. In this book we’ll teach you everything you need to know to make great games for iOS & tvOS – from physics, to tile maps, to particle systems, and even how to make your games “juicy” with polish and special effects.

Enjoy playing your new game; I look forward to hearing from you with comments below or questions on the forums. :]

The post Introduction to the SpriteKit Scene Editor appeared first on Ray Wenderlich.


Video Tutorial: Advanced Swift 3 Part 6: Implementing Copy-on-Write

How To Secure iOS User Data: The Keychain and Touch ID

$
0
0
Learn how to add Touch ID & 1Password to your app!

Learn how to secure your app using Touch ID

Update note: This tutorial has been updated for Xcode 8.3.2 and Swift 3.1 by Tim Mitra. The original tutorial was also written by Tim Mitra.

Protecting an app with a login screen is a great way to secure user data – you can use the Keychain, which is built right in to iOS, to ensure that their data stays secure.  Apple also offers yet another layer of protection with Touch ID. Available since the iPhone 5s, Touch ID stores biometrics in a secure enclave in the A7 and newer chips.

All of this means you can comfortably hand over the responsibility of handling login information to the Keychain and/or Touch ID. In this tutorial you’ll start out with static authentication. Next you’ll be using the Keychain to store and verify login information. After that, you’ll explore using Touch ID in your app.

Note: Touch ID requires that you test on a physical device, but the Keychain can be used in the simulator.

Getting Started

Please download the starter project for this tutorial here.

This is a basic note taking app that uses Core Data to store user notes; the storyboard has a login view where users can enter a username and password, and the rest of the app’s views are already connected to each other and ready to use.

Build and run to see what your app looks like in its current state:

TouchMeIn starter

At this point, tapping the Login button simply dismisses the view and displays a list of notes – you can also create new notes from this screen. Tapping Logout takes you back to the login view. If the app is pushed to the background it will immediately return to the login view; this protects data from being viewed without being logged in. This is controlled by setting Application does not run in background to YES in Info.plist.

Before you do anything else, you should change the Bundle Identifier, and assign an appropriate Team.

Select TouchMeIn in the Project Navigator, and then select the TouchMeIn target. In the General tab change Bundle Identifier to use your own domain name, in reverse-domain-notation – for example com.raywenderich.TouchMeIn.

Then, from the Team menu, select the team associated with your developer account like so:

With all of the housekeeping done, it’s time to code! :]

Logging? No. Log In.

To get the ball rolling, you’re going to add the ability to check the user-provided credentials against hard-coded values.

Open LoginViewController.swift and add the following constants just below where the managedObjectContext variable is declared:

let usernameKey = "batman"
let passwordKey = "Hello Bruce!"

These are simply the hard-coded username and password you’ll be checking the user-provided credentials against.

Add the following function below loginAction(_:):

func checkLogin(username: String, password: String) -> Bool {
  return username == usernameKey && password == passwordKey
}

This checks the user-provided credentials against the constants you defined earlier.

Next, replace the contents of loginAction(_:) with the following:

if checkLogin(username: usernameTextField.text!, password: passwordTextField.text!) {
  performSegue(withIdentifier: "dismissLogin", sender: self)
}

This calls checkLogin(username:password:), which dismisses the login view if the credentials are correct.

Build and run. Enter the username batman and the password Hello Bruce!, and tap the Login button. The login screen should dismiss as expected.

While this simple approach to authentication seems to work, it’s not terribly secure, as credentials stored as strings can easily be compromised by curious hackers with the right tools and training. As a best practice, passwords should NEVER be stored directly in the app.

To that end, you’ll employ the Keychain to store the password. Check out Chris Lowe’s Basic Security in iOS 5 – Part 1 tutorial for the lowdown on how the Keychain works.

The next step is to add a Keychain wrapper class to your app.

Rapper? No. Wrapper.

In the starter app you’ll find that you have already downloaded the KeychainPasswordItem.swift file; this class comes from Apple’s sample code GenericKeychain.

In the Resources folder, drag the KeychainPasswordItem.swift into the project, like so:

When prompted, make sure that Copy items if needed is checked and the TouchMeIn target is checked as well:

Copy files if needed

Build and run to make sure you have no errors. All good? Great — now you can leverage the Keychain from within your app.

Keychain, Meet Password. Password, Meet Keychain

To use the Keychain, you first need to store a username and password. After that, you check the user-provided credentials against the Keychain to see if they match.

You’ll need to track whether the user has already created some credentials so that you can change the text on the Login button from “Create” to “Login”. You’ll also store the username in the user defaults so you can perform this check without hitting the Keychain each time.

The Keychain requires some configuration to properly store your app’s information. You will need to add a serviceName and an optional accessGroup. You’ll add a struct to store these values.

Open up LoginViewController.swift. At the top of the file and just below the imports add this struct.

// Keychain Configuration
struct KeychainConfiguration {
  static let serviceName = "TouchMeIn"
  static let accessGroup: String? = nil
}

Next delete the following lines:

let usernameKey = "batman"
let passwordKey = "Hello Bruce!"

In their place, add the following:

var passwordItems: [KeychainPasswordItem] = []
let createLoginButtonTag = 0
let loginButtonTag = 1

@IBOutlet weak var loginButton: UIButton!

The passwordItems is an empty array of KeychainPasswordItem types that will pass into the keychain. The next two constants will be used to determine if the Login button is being used to create some credentials, or to log in; the loginButton outlet will be used to update the title of the button depending on that same state.

Open Main.storyboard and choose the Login View Controller Scene. Ctrl-drag from the Login View Controller to the Login button, as shown below:

From the resulting popup, choose loginButton:

Next, you need to handle the following two cases for when the button is tapped: if the user hasn’t yet created their credentials, the button text will show “Create”, otherwise the button will show “Login”. You also need to check the entered credentials against the Keychain.

Open LoginViewController.swift and replace the code in loginAction(_:) with the following:

  @IBAction func loginAction(_ sender: AnyObject) {
    // 1
    // Check that text has been entered into both the username and password fields.
    guard
      let newAccountName = usernameTextField.text,
      let newPassword = passwordTextField.text,
      !newAccountName.isEmpty &&
      !newPassword.isEmpty else {

        let alertView = UIAlertController(title: "Login Problem",
                                          message: "Wrong username or password.",
                                          preferredStyle:. alert)
        let okAction = UIAlertAction(title: "Foiled Again!", style: .default, handler: nil)
        alertView.addAction(okAction)
        present(alertView, animated: true, completion: nil)
        return
    }

    // 2
    usernameTextField.resignFirstResponder()
    passwordTextField.resignFirstResponder()

    // 3
    if sender.tag == createLoginButtonTag {

      // 4
      let hasLoginKey = UserDefaults.standard.bool(forKey: "hasLoginKey")
      if !hasLoginKey {
        UserDefaults.standard.setValue(usernameTextField.text, forKey: "username")
      }

      // 5
      do {

        // This is a new account, create a new keychain item with the account name.
        let passwordItem = KeychainPasswordItem(service: KeychainConfiguration.serviceName,
                                                account: newAccountName,
                                                accessGroup: KeychainConfiguration.accessGroup)

        // Save the password for the new item.
        try passwordItem.savePassword(newPassword)
      } catch {
        fatalError("Error updating keychain - \(error)")
      }

      // 6
      UserDefaults.standard.set(true, forKey: "hasLoginKey")
      loginButton.tag = loginButtonTag

      performSegue(withIdentifier: "dismissLogin", sender: self)

    } else if sender.tag == loginButtonTag {

      // 7
      if checkLogin(username: usernameTextField.text!, password: passwordTextField.text!) {
        performSegue(withIdentifier: "dismissLogin", sender: self)
      } else {
        // 8
        let alertView = UIAlertController(title: "Login Problem",
                                          message: "Wrong username or password.",
                                          preferredStyle: .alert)
        let okAction = UIAlertAction(title: "Foiled Again!", style: .default)
        alertView.addAction(okAction)
        present(alertView, animated: true, completion: nil)
      }
    }
  }

Here’s what’s happening in the code:

  1. If either the username or password is empty, then present an alert to the user and return from the method.
  2. Dismiss the keyboard if it’s visible.
  3. If the login button’s tag is createLoginButtonTag, then proceed to create a new login.
  4. Next, you read hasLoginKey from UserDefaults which indicates whether a password has been saved to the Keychain. If the username field is not empty and hasLoginKey indicates no login has already been saved, then you save the username to UserDefaults.
  5. You create a KeychainPasswordItem with the serviceNamenewAccountName (username) and accessGroup. Using Swift’s error handling, you try to save save the password. The catch is there if something goes wrong.
  6. You then set hasLoginKey in UserDefaults to true to indicate that a password has been saved to the keychain. You set the login button’s tag to loginButtonTag to change the button’s text, so that it will prompt the user to log in the next time they run your app, rather than prompting the user to create a login. Finally, you dismiss loginView.
  7. If the user is logging in (as indicated by loginButtonTag), you call checkLogin to verify the user-provided credentials; if they match then you dismiss the login view.
  8. If the login authentication fails, then present an alert message to the user.
Note: Why not just store the password along with the username in UserDefaults? That would be a bad idea because values stored in UserDefaults are persisted using a plist file. This is essentially an XML file that resides in the app’s Library folder, and is therefore readable by anyone with physical access to the device. The Keychain, on the other hand, uses the Triple Digital Encryption Standard (3DES) to encrypt its data. Even if somebody gets the data, they won’t be able to read it.

Next, replace the implementation of checkLogin(username:password:) with the following:

  func checkLogin(username: String, password: String) -> Bool {

    guard username == UserDefaults.standard.value(forKey: "username") as? String else {
      return false
    }

    do {
      let passwordItem = KeychainPasswordItem(service: KeychainConfiguration.serviceName,
                                              account: username,
                                              accessGroup: KeychainConfiguration.accessGroup)
      let keychainPassword = try passwordItem.readPassword()
      return password == keychainPassword
    }
    catch {
      fatalError("Error reading password from keychain - \(error)")
    }

    return false
  }

This checks that the username entered matches the one stored in UserDefaults and that the password matches the one stored in the Keychain.

Now you need to set the button title and tags appropriately depending on the state of hasLoginKey.

Add the following to viewDidLoad(), just below the call to super:

    // 1
    let hasLogin = UserDefaults.standard.bool(forKey: "hasLoginKey")

    // 2
    if hasLogin {
      loginButton.setTitle("Login", for: .normal)
      loginButton.tag = loginButtonTag
      createInfoLabel.isHidden = true
    } else {
      loginButton.setTitle("Create", for: .normal)
      loginButton.tag = createLoginButtonTag
      createInfoLabel.isHidden = false
    }

    // 3
    if let storedUsername = UserDefaults.standard.value(forKey: "username") as? String {
      usernameTextField.text = storedUsername
    }

Taking each numbered comment in turn:

  1. You first check hasLoginKey to see if you’ve already stored a login for this user.
  2. If so, change the button’s title to Login, update its tag to loginButtonTag, and hide createInfoLabel, which contains the informative text “Start by creating a username and password“. If you don’t have a stored login for this user, set the button label to Create and display createInfoLabel to the user.
  3. Finally, you set the username field to what is saved in UserDefaults to make logging in a little more convenient for the user.

Build and run. Enter a username and password of your own choosing, then tap Create.

Note: If you forgot to connect the loginButton IBOutlet then you might see the error Fatal error: unexpectedly found nil while unwrapping an Optional value. If you do, connect the outlet as described in the relevant step above.

Now tap Logout and attempt to login with the same username and password – you should see the list of notes appear.

Tap Logout and try to log in again – this time, use a different password and then tap Login. You should see the following alert:

wrong password

Congratulations – you’ve now added authentication use the Keychain. Next up, Touch ID.

Touching You, Touching Me

Note: In order to test Touch ID, you’ll need to run the app on a physical device that supports Touch ID. At the time of this writing, that includes any device with a A7 chip or newer and Touch ID hardware.

In this section, you’ll add Touch ID to your project in addition to using the Keychain. While Keychain isn’t necessary for Touch ID to work, it’s always a good idea to implement a backup authentication method for instances where Touch ID fails, or for users that don’t have a Touch ID compatible device.

Open Images.xcassets.

Open the Resources folder from the starter project you downloaded earlier. Locate Touch-icon-lg.png, Touch-icon-lg@2x.png, and Touch-icon-lg@3x.png, select all three and drag them into Images.xcassets so that Xcode knows they’re the same image, only with different resolutions:

drag to assets

Open up Main.storyboard and drag a Button from the Object Library onto the Login View Controller Scene, just below the Create Info Label, inside the Stack View. You can open the Document Outline, swing open the disclosure triangles and make sure that the Button is inside the Stack View. It should look like this:

If you need to review stack views, take a look at Jawwad Ahmad’s UIStackView Tutorial: Introducing Stack Views.

Use the Attributes Inspector to adjust the button’s attributes as follows:

  • Set Type to Custom.
  • Leave the Title empty.
  • Set Image to Touch-icon-lg.

When you’re done, the button’s attributes should look like this:

Screen Shot 2014-12-22 at 3.05.58 AM

Ensure your new button is selected, then click the Add New Constraints button in the layout bar at the foot of the storyboard canvas and set the constraints as below:

constraints on Touch button

  • Width should be 66
  • Height should be 67

Your view should now look like the following:

login view

Still in Main.storyboard, open the Assistant Editor and make sure LoginViewController.swift is showing.

Now, Ctrl-drag from the button you just added to LoginViewController.swift, just below the other properties, like so:

connect touchButton

In the popup enter touchIDButton as the Name and click Connect:

naming outlet

This creates an outlet that you will use to hide the button on devices that don’t have Touch ID available.

Now you need to add an action for the button.

Ctrl-drag from the same button to LoginViewController.swift to just above checkLogin(username:password:):

connect touch action

In the popup, change Connection to Action, set Name to touchIDLoginAction, optionally set the Type to UIButton. Then click Connect.

touchIDLoginAction

Build and run to check for any errors. You can still build for the Simulator at this point since you haven’t yet added support for Touch ID. You’ll take care of that now.

Adding Local Authentication

Implementing Touch ID is as simple as importing the Local Authentication framework and calling a couple of simple yet powerful methods.

Here’s what the Local Authentication documentation has to say:

“The Local Authentication framework provides facilities for requesting authentication from users with specified security policies.”

The specified security policy in this case will be your user’s biometrics — A.K.A their fingerprint! :]

In Xcode’s Project Navigator right-click the TouchMeIn group folder and select New File…. Choose Swift File under iOS. Click Next. Save the file as TouchIDAuthentication.swift with the TouchMeIn target checked. Click Create.

Open up TouchIDAuthentication.swift and add the following import just below Foundation:

import LocalAuthentication

Create a new class next:

class TouchIDAuth {

}

Now you’ll need a reference to the LAContext class.

Inside the class add the following code between the curly braces:

let context = LAContext()

The context references an authentication context, which is the main player in Local Authentication. You will need a function to see if Touch ID is available to the user’s device or in the Simulator.

Create the following function to return a Bool if Touch ID is supported.

func canEvaluatePolicy() -> Bool {
  return context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil)
}

Open up LoginViewController.swift.
Add another property to create a reference to class you just created.

let touchMe = TouchIDAuth()

At the bottom of viewDidLoad() add the following:

touchIDButton.isHidden = !touchMe.canEvaluatePolicy()

Here you use canEvaluatePolicy(_:error:) to check whether the device can implement Touch ID authentication. If so, then show the Touch ID button; if not, then leave it hidden.

Build and run on the Simulator; you’ll see the Touch ID logo is hidden. Now build and run on your physical Touch ID-capable device; you’ll see the Touch ID button is displayed.

Putting Touch ID to Work

Go back to TouchIDAuthentication.swift and add a function to authenticate the user. At the bottom of the TouchIDAuth class, create the following function

func authenticateUser(completion: @escaping () -> Void) { // 1
  // 2
  guard canEvaluatePolicy() else {
    return
  }

  // 3
  context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics,
    localizedReason: "Logging in with Touch ID") { (success, evaluateError) in
      // 4
      if success {
        DispatchQueue.main.async {
          // User authenticated successfully, take appropriate action
          completion()
        }
      } else {
        // TODO: deal with LAError cases
      }
  }
}

Here’s what’s going on in the code above:

  1. authenticateUser(completion:) is going to pass a completion handler in the form of a closure back to the LoginViewController.
  2. You’re using canEvaluatePolicy() to check whether the device is Touch ID capable.
  3. If the device does support Touch ID, you then use evaluatePolicy(_:localizedReason:reply:) to begin the policy evaluation — that is, prompt the user for Touch ID authentication. evaluatePolicy(_:localizedReason:reply:) takes a reply block that is executed after the evaluation completes.
  4. Inside the reply block, you are handling the success case first. By default, the policy evaluation happens on a private thread, so your code jumps back to the main thread so it can update the UI. If the authentication was successful, you will call the segue that dismisses the login view.

We’ll come back and deal with errors in little while.
Switch to LoginViewController.swift and locate touchIDLoginAction(_:) by scrolling or with the jump bar.
Add the following inside the action so that it looks like this:

  @IBAction func touchIDLoginAction(_ sender: UIButton) {
    touchMe.authenticateUser() { [weak self] in
      self?.performSegue(withIdentifier: "dismissLogin", sender: self)
    }
  }

If the user is authenticated, you can dismiss the Login view.

You can build and run to your device here, but wait! What if you haven’t set up Touch ID on your device? What if you are using the wrong finger? Let’s deal with that.

Go ahead and build and run to see if all’s well.

Dealing with Errors

An important part of Local Authentication is responding to errors, so the framework includes an LAError type. There also is the possibility of getting an error from the second use of canEvaluatePolicy. You’ll present an alert to show the user what has gone wrong. You will need to pass a message from the TouchIDAuth class to the LoginViewController. Fortunately you have the completion handler that you can use it to pass the optional message.

Switch back to TouchIDAuthentication.swift and update the authenticateUser function.

Change the signature to include an optional message that you will pass when you get an error.

func authenticateUser(completion: @escaping (String?) -> Void) {

Find the // TODO: and replace it with the LAError cases in a switch statement:

            // 1
            let message: String

            // 2
            switch evaluateError {
            // 3
            case LAError.authenticationFailed?:
              message = "There was a problem verifying your identity."
            case LAError.userCancel?:
              message = "You pressed cancel."
            case LAError.userFallback?:
              message = "You pressed password."
            default:
              message = "Touch ID may not be configured"
            }
            // 4
            completion(message)

Here’s what’s happening

  1. Declare a string to hold the message.
  2. Now for the “failure” cases. You use a switch statement to set appropriate error messages for each error case, then present the user with an alert view.
  3. If the authentication failed, you display a generic alert. In practice, you should really evaluate and address the specific error code returned, which could include any of the following:
    • LAError.touchIDNotAvailable: the device isn’t Touch ID-compatible.
    • LAError.passcodeNotSet: there is no passcode enabled as required for Touch ID
    • LAError.touchIDNotEnrolled: there are no fingerprints stored.
  4. Pass the message in the completion closure.

iOS responds to LAError.passcodeNotSet and LAError.touchIDNotEnrolled on its own with relevant alerts.

There’s one more error case to deal with. Add the following inside the `else` block of the `guard` statement, just above `return`.

completion("Touch ID not available")

The last thing to update is our success case. That completion should contain nil, indicating that you didn’t get any errors. Inside the first success block add the nil.

completion(nil)

Your finished function should look like this:

  func authenticateUser(completion: @escaping (String?) -> Void) {

    guard canEvaluatePolicy() else {
      completion("Touch ID not available")
      return
    }

    context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics,
      localizedReason: "Logging in with Touch ID") { (success, evaluateError) in
        if success {
          DispatchQueue.main.async {
            completion(nil)
          }
        } else {

          let message: String

          switch evaluateError {
          case LAError.authenticationFailed?:
            message = "There was a problem verifying your identity."
          case LAError.userCancel?:
            message = "You pressed cancel."
          case LAError.userFallback?:
            message = "You pressed password."
          default:
            message = "Touch ID may not be configured"
          }

          completion(message)
        }
    }
  }

Switch to LoginViewController.swift and update the touchIDLoginAction(_:) to look like this:

  @IBAction func touchIDLoginAction(_ sender: UIButton) {

    // 1
    touchMe.authenticateUser() { message in

      // 2
      if let message = message {
        // if the completion is not nil show an alert
        let alertView = UIAlertController(title: "Error",
                                          message: message,
                                          preferredStyle: .alert)
        let okAction = UIAlertAction(title: "Darn!", style: .default)
        alertView.addAction(okAction)
        self.present(alertView, animated: true)

      } else {
        // 3
        self.performSegue(withIdentifier: "dismissLogin", sender: self)
      }
    }
  }
  1. We’ve added a trailing closure to pass in an optional message. If Touch ID works there is no message.
  2. We use if let to unwrap the message and display it with an alert.
  3. No change here, but if you have no message, you can dismiss the Login view.

Build and run on a physical device and test logging in with Touch ID.

Since LAContext handles most of the heavy lifting, it turned out to be relatively straight forward to implement Touch ID. As a bonus, you were able to have Keychain and Touch ID authentication in the same app, to handle the event that your user doesn’t have a Touch ID-enabled device.

Note: If you want test the errors in Touch ID, you can try to login with an incorrect finger. Doing so five times will disable Touch ID and require password authentication. This prevents strangers from trying to break into other applications on your device. You can re-enable it by going to Settings -> Touch ID & Passcode.

Where to Go from Here?

You can download the completed sample application from this tutorial here.

The LoginViewController you’ve created in this tutorial provides a jumping-off point for any app that needs to manage user credentials.

You can also add a new view controller, or modify the existing LoginViewController, to allow the user to change their password from time to time. This isn’t necessary with Touch ID, since the user’s biometrics probably won’t change much in their lifetime! :] However, you could create a way to update the Keychain; you’d want to prompt the user for their current password before accepting their modification.

You can read more about securing your iOS apps in Apple’s official iOS 10 Security Guide.

As always, if you have any questions or comments on this tutorial, feel free to join the discussion below!

The post How To Secure iOS User Data: The Keychain and Touch ID appeared first on Ray Wenderlich.

Advanced Apple Debugging & Reverse Engineering – Available Now!

$
0
0

We’re excited to announce that the full version of Advanced Apple Debugging & Reverse Engineering is available now on the raywenderlich.com store!

The full version of the book has a full five sections, 27 chapters and two appendices, including complete source code for all the projects and scripts in the book.

To continue the launch celebrations, we’re extending the launch discount for the book on our store — for this week only.

Read on to see what the book is all about, how to take advantage of the discount and where you can get your copy!

What’s New in Advanced Apple Debugging & Reverse Engineering?

The v1.0 release of Advanced Apple Debugging and Reverse Engineering adds an entirely new section on DTrace, which is a great tool you can use to hook into a function or a group of functions using what’s known as a probe.

From there, you can perform custom actions to query information out of a specific process, or even system wide on your computer (and monitor multiple users)!

If you’ve ever used the Instruments application, it might surprise you to learn that a lot of the power underneath it is due to DTrace.

Here’s what we’ve added in the latest update to this book:

  • Hello, DTrace: You’ll explore a very small section of what DTrace is capable of doing by tracing Objective-C code in already compiled applications. Using DTrace to observe iOS frameworks (like UIKit) can give you an incredible insight into how the authors designed their code.
  • Learn the basics of DTrace commands – they’re less scary than they first appear!

  • Intermediate DTrace: This chapter will act as a grab-bag of more DTrace fundamentals, destructive actions, as well as how to use DTrace with Swift. In this chapter, you’ll learn additional ways DTrace can profile code, as well as how to augment existing code without laying a finger on the actual executable itself.
  • Learn how DTrace can interact in the deep reaches of your OS – with some rather interesting results!

  • DTrace vs objc_msgSend: In the final chapter, you’ll use DTrace to hook objc_msgSend’s entry probe and pull out the class name along with the Objective-C selector for that class. By the end of this chapter, you’ll have LLDB generating a DTrace script which only generates tracing info for code implemented within the main executable that calls objc_msgSend.

What’s In the Rest of the Book?

Here’s the complete listing of what’s contained in the book:

Section I: Beginning LLDB Commands

  1. Getting Started: In this chapter, you’re going to get acquainted with LLDB and investigate the process of introspecting and debugging a program. You’ll start off by introspecting a program you didn’t even write — Xcode!
  2. Help & Apropos: Just like any respectable developer tool, LLDB ships with a healthy amount of documentation. Knowing how to navigate through this documentation — including some of the more obscure command flags — is essential to mastering LLDB.
  3. Attaching with LLDB: Now that you’ve learned about the two most essential commands, help and apropos, it’s time to investigate how LLDB attaches itself to processes. You’ll learn all the different ways you can attach LLDB to processes using various options, as well as what happens behind the scenes when attaching to processes.
  4. Stopping in Code: Whether you’re using Swift, Objective-C, C++, C, or an entirely different language in your technology stack, you’ll need to learn how to create breakpoints. It’s easy to click on the side panel in Xcode to create a breakpoint using the GUI, but the LLDB console can give you much more control over breakpoints.
  5. Expression: Now that you’ve learned how to set breakpoints so the debugger will stop in your code, it’s time to get useful information out of whatever software you’re debugging. In this chapter you’ll learn about the expression command, which allows you to execute arbitrary code in the debugger.
  6. Thread, Frame & Stepping Around: You’ve learned how to create breakpoints, how to print and modify values, as well as how to execute code while paused in the debugger. But so far you’ve been left high and dry on how to move around in the debugger and inspect data beyond the immediate. In this chapter, you’ll learn how to move the debugger in and out of functions while LLDB is currently paused.
  7. Image: It’s time to explore one of the best tools for finding code of interest through the powers of LLDB. In this chapter, you’ll take a deep dive into the image command.
  8. Persisting & Customizing Commands: In this chapter, you’ll learn how to persist these choices through the .lldbinit file. By persisting your choices and making convenience commands for yourself, your debugging sessions will run much more smoothly and efficiently. This is also an important concept because from here on out, you’ll use the .lldbinit file on a regular basis.
  9. Regex Commands: In the previous chapter, you learned about the command alias command as well as how to persist commands through the lldbinit file. Unfortunately, command alias has some limitations. The LLDB command command regex acts much like command alias, except you can provide a regular expression for input which will be parsed and applied to the action part of the command.

Section II: Understanding Assembly

  1. Assembly Register Calling Convention: Now you’ve gained a basic understanding of how to maneuver around the debugger, it’s time to take a step down the executable Jenga tower and explore the 1s and 0s that make up your source code. This section will focus on the low-level aspects of debugging.
  2. Assembly & Memory: In this chapter, you’ll explore how a program executes. You’ll look at a special register used to tell the processor where it should read the next instruction from, as well as how different sizes and groupings of memory can produce very different results.
  3. Assembly and the Stack: What does being “passed on the stack” mean exactly? It’s time to take a deeper dive into what happens when a function is called from an assembly standpoint by exploring some “stack related” registers as well as the contents in the stack.

Learn how to reverse engineer code like a boss!

Section III: Low Level

  1. Hello, Ptrace: As alluded to in the introduction to this book, debugging is not entirely about just fixing stuff. Debugging is the process of gaining a better understanding of what’s happening behind the scenes. In this chapter, you’ll explore the foundation of debugging, namely, a system call responsible for a process attaching itself to another process: ptrace.
  2. Dynamic Frameworks: With dynamic frameworks comes a very interesting aspect of learning, debugging, and reverse engineering. Since you have the ability to load the framework at runtime, you can use LLDB to explore and execute code at runtime, which is great for spelunking in both public and private frameworks.
  3. Hooking & Executing Code with dlopen & dlsym: It’s time to learn about the complementary skills of developing with these frameworks. In this chapter, you’re going to learn about methods and strategies to “hook” into Swift and C code as well as execute methods you wouldn’t normally have access to.
  4. Exploring and Method Swizzling Objective-C Frameworks: You’ll cap off this round of dynamic framework exploration by digging into Objective-C frameworks using the Objective-C runtime to hook and execute methods of interest.

Section IV: Custom LLDB Commands

  1. Hello Script Bridging: Next up in the tradeoff between convenience and complexity is LLDB’s script bridging. With script bridging, you can do nearly anything you like. Script bridging is a Python interface LLDB uses to help extend the debugger to accomplish your wildest debugging dreams.
  2. Debugging Script Bridging: You need a methodical way to figure out what went wrong in your LLDB script so you don’t pull your hair out. In this chapter, you’ll explore how to inspect your LLDB Python scripts using the Python pdb module, which is used for debugging Python scripts.
  3. Script Bridging Classes and Hierarchy: You’ve learned the essentials of working with LLDB’s Python module, as well as how to correct any errors using Python’s PDB debugging module. Now you’ll explore the main players within the lldb Python module for a good overview of the main parts. In this chapter, you’ll add some arguments to this script and deal with some annoying edge cases, such handling commands differently between Objective-C and Swift.
  4. Script Bridging with Options & Arguments: When you’re creating a custom debugging command, you’ll often want to slightly tweak functionality based upon options or arguments supplied to your command. A custom LLDB command that can do a job only one way is a boring one-trick pony. In this chapter, you’ll explore how to pass optional parameters (aka options) as well as arguments (parameters which are expected) to your custom command to alter functionality or logic in your custom LLDB scripts.
  5. Script Bridging with SBValue & Memory: So far, when evaluating JIT code (i.e. Objective-C, Swift, C, etc. code that’s executed through your Python script), you’ve used a small set of APIs to evaluate the code. It’s time to talk about a new class in the lldb Python module, SBValue, and how it can simplify the parsing of JIT code output.
  6. SB Examples, Improved Lookup: For the rest of the chapters in this section, you’ll focus on Python scripts. As alluded to in the previous chapter, the image lookup -rn command is on its way out. When you finish this chapter, you’ll have a new script named “lookup” which queries in a much cleaner way.
  7. SB Examples, Resymbolicating a Stripped ObjC Binary: When LLDB comes up against a stripped executable (an executable devoid of DWARF debugging information), LLDB won’t have the symbol information to give you the stack trace. Instead, LLDB will generate a synthetic name for a method it recognizes as a method, but doesn’t know what to call it. In this chapter, you’ll build an LLDB script that will resymbolicate stripped Objective-C functions in a stack trace.
  8. SB Examples, Malloc Logging: For the final chapter in this section, you’ll go through the same steps I myself took to understand how the MallocStackLogging environment variable is used to get the stack trace when an object is created. From there, you’ll create a custom LLDB command which gives you the stack trace of when an object was allocated or deallocated in memory — even after the stack trace is long gone from the debugger.

Section V: DTrace

  1. Hello, DTrace: You’ll explore a very small section of what DTrace is capable of doing by tracing Objective-C code in already compiled applications. Using DTrace to observe iOS frameworks (like UIKit) can give you an incredible insight into how the authors designed their code.
  2. Intermediate DTrace: This chapter will act as a grab-bag of more DTrace fundamentals, destructive actions (yay!), as well as how to use DTrace with Swift. In this chapter, you’ll learn additional ways DTrace can profile code, as well as how to augment existing code without laying a finger on the actual executable itself.
  3. DTrace vs objc_msgSend: In this chapter, you’ll use DTrace to hook objc_msgSend’s entry probe and pull out the class name along with the Objective-C selector for that class. By the end of this chapter, you’ll have LLDB generating a DTrace script which only generates tracing info for code implemented within the main executable that calls objc_msgSend.

Who Is this Book For?

This book is for intermediate to advanced developers who want to take their debugging and code exploration game to the next level.

The art of debugging code should really be studied by every developer. However, there will be some of you that will get more out of this book. This book is written for:

  • Developers who want to become better at debugging with LLDB
  • Developers who want to build complex debugging commands with LLDB
  • Developers who want to take a deeper dive into the internals of Swift and Objective-C
  • Developers who are interested in understanding what they can do to their program through reverse engineering
  • Developers who are interested in modern, proactive reverse engineering strategies
  • Developers who want to be confident in finding answers to questions they have about their computer or software

Introducing the Author

Derek Selander became interested with debugging when he started exploring how to make (the now somewhat obsolete) Xcode plugins and iOS tweaks on his jailbroken phone, both of which required exploring and augmenting programs with no source available. In his free time, he enjoys pickup soccer, guitar, and playing with his two doggies, Jake & Squid.

Where to Go From Here?

Here’s how to get your hands on this new release:

  • If you are an existing PDF customer of Advanced Apple Debugging & Reverse Engineering, you can log in to your account and download this update immediately.
  • If you haven’t yet bought the PDF version of Advanced Apple Debugging & Reverse Engineering, you can pick up a copy on the raywenderlich.com store page.

To celebrate the release of the full version of the book, you can get the PDF version of the book for $44.99 when you buy it through our online store. That’s $10 off the cover price!

But the launch discount is only good until Friday, May 19th, so grab it while you can:

The Advanced Apple Debugging & Reverse Engineering team and I hope you enjoy the book — and we can’t wait to hear about your debugging and reverse engineering adventures!

The post Advanced Apple Debugging & Reverse Engineering – Available Now! appeared first on Ray Wenderlich.

Video Tutorial: Advanced Swift 3 Part 7: Custom Sequences

Video Tutorial: Advanced Swift 3 Part 8: Custom Collections

Assembly Register Calling Convention Tutorial

$
0
0

This tutorial has been taken from Chapter 10, “Assembly Register Calling Convention” of our book Advanced Apple Debugging & Reverse Engineering. The book covers advanced debugging tools in detail, from LLDB, to DTrace, and shows you how to automate your workflows with Python to learn everything you wanted to know about your code – or someone else’s. Enjoy!

In this tutorial, you’ll look at registers the CPU uses and explore and modify parameters passed into function calls. You’ll also learn about common Apple computer architectures and how their registers are used within a function. This is known as an architecture’s calling convention.

Knowing how assembly works and how a specific architecture’s calling convention works is an extremely important skill to have. It lets you observe function parameters you don’t have the source code for and lets you modify the parameters passed into a function. In addition, it’s sometimes even better to go to the assembly level because your source code could have different or unknown names for variables you’re not aware of.

For example, let’s say you always wanted to know the second parameter of a function call, regardless of what the parameter’s name is. Knowledge of assembly gives you a great base layer to manipulate and observe parameters in functions.

Assembly 101

Wait, so what’s assembly again?

Have you ever stopped in a function you didn’t have source code for, and saw an onslaught of memory addresses followed by scary, short commands? Did you huddle in a ball and quietly whisper to yourself you’ll never look at this dense stuff again? Well… that stuff is known as assembly!

Here’s a picture of a backtrace in Xcode, which showcases the assembly of a function within the Simulator.

Looking at the image above, the assembly can be broken into several parts. Each line in a assembly instruction contains an opcode, which can be thought of as an extremely simple instruction for the computer.

So what does an opcode look like? An opcode is an instruction that performs a simple task on the computer. For example, consider the following snippet of assembly:

pushq   %rbx
subq    $0x228, %rsp
movq    %rdi, %rbx

In this block of assembly, you see three opcodes, pushq, subq, and movq. Think of the opcode items as the action to perform. The things following the opcode are the source and destination labels. That is, these are the items the opcode acts upon.

In the above example, there are several registers, shown as rbx, rsp, rdi, and rbp. The % before each tells you this is a register.

In addition, you can also find a numeric constant in hexadecimal shown as 0x228. The $ before this constant tells you it’s an absolute number.

There’s no need to know what this code is doing at the moment, since you’ll first need to learn about the registers and calling convention of functions.

Note: In the above example, take note there are a bunch of %’s and $’s that precede the registers and constants. This is how the disassembler formats the assembly. However, there are two main ways that assembly can be showcased. The first is Intel assembly, and the second is AT&T assembly.

By default, Apple’s disassembler tools ship with assembly displayed in the AT&T format, as it is in the example above. Although this is a good format to work with, it can admittedly be a little hard on the head.

x86_64 vs ARM64

As a developer for Apple platforms, there are two primary architectures you’ll deal with when learning assembly: x86_64 architecture and ARM64 architecture. x86_64 is the architecture most likely used on your macOS computer, unless you are running an “ancient” Macintosh.

x86_64 is a 64-bit architecture, which means every address can hold up to 64 1s or 0s. Alternatively, older Macs use a 32-bit architecture, but Apple stopped making 32-bit Macs at the end of the 2010’s. Programs running under macOS are likely to be 64-bit compatible, including programs on the Simulator. That being said, even if your macOS is x86_64, it can still run 32-bit programs.

If you have any doubt of what hardware architecture you’re working with, you can get your computer’s hardware architecture by running the following command in Terminal:

uname -m

ARM64 architecture is used on mobile devices such as your iPhone where limiting energy consumption is critical.

ARM emphasizes power conservation, so it has a reduced set of opcodes that help facilitate energy consumption over complex assembly instructions. This is good news for you, because there are fewer instructions for you to learn on the ARM architecture.

Here’s a screenshot of the same method shown earlier, except this time in ARM64 assembly on an iPhone 7:

in many of their devices, but have since moved to 64-bit ARM processors. 32-bit devices are almost obsolete as Apple has phased them out through various iOS versions. For example, the iPhone 4s is a 32-bit device which is not supported in iOS 10. All that remains in the 32-bit iPhone lineup is the iPhone 5, which iOS 10 does support.

Interestingly, all Apple Watch devices are currently 32-bit. This is likely because 32-bit ARM CPUs typically draw less power than their 64-bit cousins. This is really important for the watch as the battery is tiny.

Since it’s best to focus on what you’ll need for the future, Advanced Apple Debugging & Reverse Engineering will focus primarily on 64-bit assembly for both architectures. In addition, you’ll start learning x86_64 assembly first and then transition to learning ARM64 assembly so you don’t get confused. Well, not too confused.

x86_64 Register Calling Convention

Your CPU uses a set of registers in order to manipulate data in your running program. These are storage holders, just like the RAM in your computer. However they’re located on the CPU itself very close to the parts of the CPU that need them. So these parts of the CPU can access these registers incredibly quickly.

Most instructions involve one or more registers and perform operations such as writing the contents of a register to memory, reading the contents of memory to a register or performing arithmetic operations (add, subtract, etc.) on two registers.

In x64 (from here on out, x64 is an abbreviation for x86_64), there are 16 general purpose registers used by the machine to manipulate data.

These registers are RAX, RBX, RCX, RDX, RDI, RSI, RSP, RBP and R8 through R15. These names will not mean much to you now, but you’ll explore the importance of each register soon.

When you call a function in x64, the manner and use of the registers follows a very specific convention. This dictates where the parameters to the function should go and where the return value from the function will be when the function finishes. This is important so code compiled with one compiler can be used with code compiled with another compiler.

For example, take a look at this simple Objective-C code:

NSString *name = @"Zoltan";
NSLog(@"Hello world, I am %@. I'm %d, and I live in %@.", name, 30, @"my father's basement");

There are four parameters passed into the NSLog function call. Some of these values are passed as-is, while one parameter is stored in a local variable, then referenced as a parameter in the function. However, when viewing code through assembly, the computer doesn’t care about names for variables; it only cares about locations in memory.

The following registers are used as parameters when a function is called in x64 assembly. Try and commit these to memory, as you’ll use these frequently in the future:

  • First Argument: RDI
  • Second Argument: RSI
  • Third Argument: RDX
  • Fourth Argument: RCX
  • Fifth Argument: R8
  • Sixth Argument: R9

If there are more than six parameters, then the program’s stack is used to pass in additional parameters to the function.

Going back to that simple Objective-C code, you can re-imagine the registers being passed like the following pseudo-code:

RDI = @"Hello world, I am %@. I'm %d, and I live in %@.";
RSI = @"Zoltan";
RDX = 30;
RCX = @"my father's basement";
NSLog(RDI, RSI, RDX, RCX);

As soon as the NSLog function starts, the given registers will contain the appropriate values as shown above.

However, as soon as the function prologue (the beginning section of a function that prepares the stack and registers) finishes executing, the values in these registers will likely change. The generated assembly will likely overwrite the values stored in these registers, or just simply discard these references when the code has no more need of them.

This means as soon as you leave the start of a function (through stepping over, stepping in, or stepping out), you can no longer assume these registers will hold the expected values you want to observe, unless you actually look at the assembly code to see what it’s doing.

This calling convention heavily influences your debugging (and breakpoint) strategy. If you were to automate any type of breaking and exploring, you would have to stop at the start of a function call in order to inspect or modify the parameters without having to actually dive into the assembly.

Objective-C and Registers

Registers use a specific calling convention. You can take that same knowledge and apply it to other languages as well.

When Objective-C executes a method, a special C function is executed named objc_msgSend. There’s actually several different types of these functions, but more on that later. This is the heart of message dispatch. As the first parameter, objc_msgSend takes the reference of the object upon which the message is being sent. This is followed by a selector, which is simply just a char * specifying the name of the method being called on the object. Finally, objc_msgSend takes a variable amount of arguments within the function if the selector specifies there should be parameters.

Let’s look at a concrete example of this in an iOS context:

[UIApplication sharedApplication];

The compiler will take this code and create the following pseudocode:

id UIApplicationClass = [UIApplication class];
objc_msgSend(UIApplicationClass, "sharedApplication");

The first parameter is a reference to the UIApplication class, followed by the sharedApplication selector. An easy way to tell if there are any parameters is to simply check for colons in the Objective-C selector. Each colon will represent a parameter in a Selector.

Here’s another Objective-C example:

NSString *helloWorldString = [@"Can't Sleep; " stringByAppendingString:@"Clowns will eat me"];

The compiler will create the following (shown below in pseudocode):

NSString *helloWorldString;
helloWorldString = objc_msgSend(@"Can't Sleep; ", "stringByAppendingString:", @"Clowns will eat me");

The first argument is an instance of an NSString (@"Can't Sleep; "), followed by the selector, followed by a parameter which is also an NSString instance.

Using this knowledge of objc_msgSend, you can use the registers in x64 to help explore content, which you’ll do very shortly.

Putting Theory to Practice

You can download the starter project for this tutorial here.

For this section, you’ll be using a project supplied in this tutorial’s resource bundle called Registers.

Open this project up through Xcode and give it a run.

This is a rather simple application which merely displays the contents of some x64 registers. It’s important to note that this application can’t display the values of registers at any given moment, it can only display the values of registers during a specific function call. This means that you won’t see too many changes to the values of these registers since they’ll likely have the same (or similar) value when the function to grab the register values is called.

Now that you’ve got an understanding of the functionality behind the Registers macOS application, create a symbolic breakpoint for NSViewController’s viewDidLoad method. Remember to use “NS” instead of “UI”, since you’re working on a Cocoa application.

Build and rerun the application. Once the debugger has stopped, type the following into the LLDB console:

(lldb) register read

This will list all of the main registers at the paused state of execution. However, this is too much information. You should selectively print out registers and treat them as Objective-C objects instead.

If you recall, -[NSViewController viewDidLoad] will be translated into the following assembly pseudocode:

RDI = UIViewControllerInstance
RSI = "viewDidLoad"
objc_msgSend(RDI, RSI)

With the x64 calling convention in mind, and knowing how objc_msgSend works, you can find the specific NSViewController that is being loaded.

Type the following into the LLDB console:

(lldb) po $rdi

You’ll get output similar to the following:

<Registers.ViewController: 0x6080000c13b0>

This will dump out the NSViewController reference held in the RDI register, which as you now know, is the location of the first argument to the method.

In LLDB, it’s important to prefix registers with the $ character, so LLDB knows you want the value of a register and not a variable related to your scope in the source code. Yes, that’s different than the assembly you see in the disassembly view! Annoying, eh?

Note: The observant among you might notice whenever you stop on an Objective-C method, you’ll never see the objc_msgSend in the LLDB backtrace. This is because the objc\_msgSend family of functions perfoms a jmp, or jump opcode command in assembly. This means that objc\_msgSend acts as a trampoline function, and once the Objective-C code starts executing, all stack trace history of objc\_msgSend will be gone. This is an optimization known as tail call optimization.

Try printing out the RSI register, which will hopefully contain the selector that was called. Type the following into the LLDB console:

(lldb) po $rsi

Unfortunately, you’ll get garbage output that looks something like this:

140735181830794

Why is this?

An Objective-C selector is basically just a char *. This means, like all C types, LLDB does not know how to format this data. As a result, you must explicitly cast this reference to the data type you want.

Try casting it to the correct type:

(lldb) po (char *)$rsi

You’ll now get the expected:

"viewDidLoad"

Of course, you can also cast it to the Selector type to produce the same result:

(lldb) po (SEL)$rsi

Now, it’s time to explore an Objective-C method with arguments. Since you’ve stopped on viewDidLoad, you can safely assume the NSView instance has loaded. A method of interest is the mouseUp: selector implemented by NSView’s parent class, NSResponder.

In LLDB, create a breakpoint on NSResponder’s mouseUp: selector and resume execution. If you can’t remember how to do that, here are the commands you need:

(lldb) b -[NSResponder mouseUp:]
(lldb) continue

Now, click on the application’s window. Make sure to click on the outside of the NSScrollView as it will gobble up your click and the -[NSResponder mouseUp:] breakpoint will not get hit.

As soon as you let go of the mouse or the trackpad, LLDB will stop on the mouseUp: breakpoint. Print out the reference of the NSResponder by typing the following into the LLDB console:

(lldb) po $rdi

You’ll get something similar to the following:

<NSView: 0x608000120140>

However, there’s something interesting with the selector. There’s a colon in it, meaning there’s an argument to explore! Type the following into the LLDB console:

(lldb) po $rdx

You’ll get the description of the NSEvent:

NSEvent: type=LMouseUp loc=(351.672,137.914) time=175929.4 flags=0 win=0x6100001e0400 winNum=8622 ctxt=0x0 evNum=10956 click=1 buttonNumber=0 pressure=0 deviceID:0x300000014400000 subtype=NSEventSubtypeTouch

How can you tell it’s an NSEvent? Well, you can either look online for documentation on -[NSResponder mouseUp:] or, you can simply use Objective-C to get the type:

(lldb) po [$rdx class]

Pretty cool, eh?

Sometimes it’s useful to use registers and breakpoints in order to get a reference to an object you know is alive in memory.

For example, what if you wanted to change the front NSWindow to red, but you had no reference to this view in your code, and you didn’t want to recompile with any code changes? You can simply create a breakpoint you can easily trip, get the reference from the register and manipulate the instance of the object as you please. You’ll try changing the main window to red now.

Note: Even though NSResponder implements mouseDown:, NSWindow overrides this method since it’s a subclass of NSResponder. You can dump all classes that implement mouseDown: and figure out which of those classes inherit from NSResponder to determine if the method is overridden without having access to the source code. An example of dumping all the Objective-C classes that implement mouseDown: is image lookup -rn '\ mouseDown:'

First remove any previous breakpoints using the LLDB console:

(lldb) breakpoint delete
About to delete all breakpoints, do you want to do that?: [Y/n]

Then type the following into the LLDB console:

(lldb) breakpoint set -o -S "-[NSWindow mouseDown:]"
(lldb) continue

This sets a breakpoint which will fire only once — a one-shot breakpoint.

Tap on the application. Immediately after tapping, the breakpoint should trip. Then type the following into the LLDB console:

(lldb) po [$rdi setBackgroundColor:[NSColor redColor]]
(lldb) continue

Upon resuming, the NSWindow will change to red!

Swift and Registers

When exploring registers in Swift, you’ll hit two hurdles that make assembly debugging harder than it is in Objective-C.

  1. First, registers are not available in the Swift debugging context. This means you have to get whatever data you want and then use the Objective-C debugging context to print out the registers passed into the Swift function. Remember that you can use the expression -l objc -O -- command, or alternatively use the cpo custom command found in Chapter 8 of the book, “Persisting and Customizing Commands”. Fortunately, the register read command is available in the Swift context.
  2. Second, Swift is not as dynamic as Objective-C. In fact, it’s sometimes best to assume that Swift is like C, except with a very, very cranky and bossy compiler. If you have a memory address, you need to explicitly cast it to the object you expect it to be; otherwise, the Swift debugging context has no clue how to interpret a memory address.

That being said, the same register calling convention is used in Swift. However, there’s one very important difference. When Swift calls a function, it has no need to use objc_msgSend, unless of course you mark up a method to use dynamic. This means when Swift calls a function, the previously used RSI register assigned to the selector will actually contain the function’s second parameter.

Enough theory — time to see this in action.

In the Registers project, navigate to ViewController.swift and add the following function to the class:

func executeLotsOfArguments(one: Int, two: Int, three: Int,
                            four: Int, five: Int, six: Int,
                            seven: Int, eight: Int, nine: Int,
                            ten: Int) {
    print("arguments are: \(one), \(two), \(three),
          \(four), \(five), \(six), \(seven),
          \(eight), \(nine), \(ten)")
}

Now, in viewDidLoad, call this function with the appropriate arguments:

override func viewDidLoad() {
  super.viewDidLoad()
  self.executeLotsOfArguments(one: 1, two: 2, three: 3, four: 4,
                              five: 5, six: 6, seven: 7,
                              eight: 8, nine: 9, ten: 10)
}

Put a breakpoint on the very same line as of the declaration of executeLotsOfArguments so the debugger will stop at the very beginning of the function. This is important, or else the registers might get clobbered if the function is actually executing.

Then remove the symbolic breakpoint you set on -[NSViewController viewDidLoad].

Build and run the app, then wait for the executeLotsOfArguments breakpoint to stop execution.

Again, a good way to start investigating is to dump the list registers. In LLDB, type the following:

(lldb) register read -f d

This will dump the registers and display the format in decimal by using the -f d option. The output will look similar to this:

General Purpose Registers:
       rax = 7
       rbx = 9
       rcx = 4
       rdx = 3
       rdi = 1
       rsi = 2
       rbp = 140734799801424
       rsp = 140734799801264
        r8 = 5
        r9 = 6
       r10 = 10
       r11 = 8
       r12 = 107202385676032
       r13 = 106652628550688
       r14 = 10
       r15 = 4298620128  libswiftCore.dylib`swift_isaMask
       rip = 4294972615  Registers`Registers.ViewController.viewDidLoad () -> () + 167 at ViewController.swift:16
    rflags = 518
        cs = 43
        fs = 0
        gs = 0

As you can see, the registers follow the x64 calling convention. RDI, RSI, RDX, RCX, R8 and R9 hold your first six parameters.

You may also notice other parameters are stored in some of the other registers. While this is true, it’s simply a leftover from the code that sets up the stack for the remaining parameters. Remember, parameters after the sixth one go on the stack.

RAX, the Return Register

But wait — there’s more! So far, you’ve learned how six registers are called in a function, but what about return values?

Fortunately, there is only one designated register for return values from functions: RAX. Go back to executeLotsOfArguments and modify the function to return a String, like so:

func executeLotsOfArguments(one: Int, two: Int, three: Int,
                            four: Int, five: Int, six: Int,
                            seven: Int, eight: Int, nine: Int,
                            ten: Int) -> String {
    print("arguments are: \(one), \(two), \(three), \(four),
          \(five), \(six), \(seven), \(eight), \(nine), \(ten)")
    return "Mom, what happened to the cat?"
}

In viewDidLoad, modify the function call to receive and ignore the String value.

override func viewDidLoad() {
    super.viewDidLoad()
    let _ = self.executeLotsOfArguments(one: 1, two: 2,
          three: 3, four: 4, five: 5, six: 6, seven: 7,
          eight: 8, nine: 9, ten: 10)
}

Create a breakpoint somewhere in executeLotsOfArguments. Build and run again, and wait for execution to stop in the function. Next, type the following into the LLDB console:

(lldb) finish

This will finish executing the current function and pause the debugger again. At this point, the return value from the function should be in RAX. Type the following into LLDB:

(lldb) register read rax

You’ll get something similar to the following:

rax = 0x0000000100003760  "Mom, what happened to the cat?"

Boom! Your return value!

Knowledge of the return value in RAX is extremely important as it will form the foundation of debugging scripts you’ll write in later sections.

Changing Values in Registers

In order to solidify your understanding of registers, you’ll modify registers in an already-compiled application.

Close Xcode and the Registers project. Open a Terminal window and launch the iPhone 7 Simulator. Do this by typing the following:

xcrun simctl list

You’ll see a long list of devices. Search for the latest iOS version for which you have a simulator installed. Underneath that section, find the iPhone 7 device. It will look something like this:

iPhone 7 (269B10E1-15BE-40B4-AD24-B6EED125BC28) (Shutdown)

The UUID is what you’re after. Use that to open the iOS Simulator by typing the following, replacing your UUID as appropriate:

open /Applications/Xcode.app/Contents/Developer/Applications/Simulator.app --args -CurrentDeviceUDID 269B10E1-15BE-40B4-AD24-B6EED125BC28

Make sure the simulator is launched and is sitting on the home screen. You can get to the home screen by pressing Command + Shift + H. Once your simulator is set up, head over to the Terminal window and attach LLDB to the SpringBoard application:

lldb -n SpringBoard

This attaches LLDB to the SpringBoard instance running on the iOS Simulator! SpringBoard is the program that controls the home screen on iOS.

Once attached, type the following into LLDB:

(lldb) p/x @"Yay! Debugging"

You should get some output similar to the following:

(__NSCFString *) $3 = 0x0000618000644080 @"Yay! Debugging!"

Take a note of the memory reference of this newly created NSString instance as you’ll use it soon. Now, create a breakpoint on UILabel’s setText: method in LLDB:

(lldb) b -[UILabel setText:]

Next, type the following in LLDB:

(lldb) breakpoint command add

LLDB will spew some output and go into multi-line edit mode. This command lets you add extra commands to execute when the breakpoint you just added is hit. Type the following, replacing the memory address with the address of your NSString from above:

> po $rdx = 0x0000618000644080
> continue
> DONE

Take a step back and review what you’ve just done. You’ve created a breakpoint on UILabel’s setText: method. Whenever this method gets hit, you’re replacing what’s in RDX — the third parameter — with a different NSString instance that says Yay! Debugging!.

Resume the debugger by using the continue command:

(lldb) continue

Try exploring the SpringBoard Simulator app and see what content has changed. Swipe up from the bottom to bring up the Control Center, and observe the changes:

Try exploring other areas where modal presentations can occur, as this will likely result in a new UIViewController (and all of its subviews) being lazily loaded, causing the breakpoint action to be hit.

Although this might seem like a cool gimmicky programming trick, it provides an insightful look into how a limited knowledge of registers and assembly can produce big changes in applications you don’t have the source for.

This is also useful from a debugging standpoint, as you can quickly visually verify where the -[UILabel setText:] is executed within the SpringBoard application and run breakpoint conditions to find the exact line of code that sets a particular UILabel’s text.

To continue this thought, any UILabel instances whose text did not change also tells you something. For example, the UIButtons whose text didn’t change to Yay! Debugging! speaks for itself. Perhaps the UILabel’s setText: was called at an earlier time? Or maybe the developers of the SpringBoard application chose to use setAttributedText: instead? Or maybe they’re using a private method that is not publicly available to third-party developers?

As you can see, using and manipulating registers can give you a lot of insight into how an application functions. :]

Where to Go From Here?

Whew! That was a long one, wasn’t it? Sit back and take a break with your favorite form of liquid; you’ve earned it.

You can download the completed project from this tutorial here.

So what did you learn?

  • Architectures define a calling convention which dictates where parameters to a function and its return value are stored.
  • In Objective-C, the RDI register is the reference of the calling NSObject, RSI is the Selector, RDX is the first parameter and so on.
  • In Swift, RDI is the first argument, RSI is the second parameter, and so on provided that the Swift method isn’t using dynamic dispatch.
  • The RAX register is used for return values in functions regardless of whether you’re working with Objective-C or Swift.
  • Make sure you use the Objective-C context when printing registers with $.

There’s a lot you can do with registers. Try exploring apps you don’t have the source code for; it’s a lot of fun and will build a good foundation for tackling tough debugging problems.

Try attaching to an application on the iOS Simulator and map out the UIViewControllers as they appear using assembly, a smart breakpoint, and a breakpoint command.

If you enjoyed what you learned in the tutorial, why not check out the complete Advanced Apple Debugging & Reverse Engineering book, available on our store?

Here’s a taste of what’s in the book:

  • Getting Started: Learn your way around LLDB and its extensive list of subcommands and options.
  • Python Power: Use LLDB’s Python module to create powerful, custom debugging commands to introspect and augment existing programs.
  • Understanding Assembly: Truly understand how code works at an assembler-level and how you can explore code in memory.
  • Ptrace and Friends: Learn how to leverage ptrace, dlopen and dlsym to hook into C and Swift functions to explore code that you don’t have the source for.
  • Script Bridging: Extend the debugger to make it do almost anything you want, and learn how to pass in options or arguments to your debugging scripts.
  • DTrace: Dig deep and hook into a function with a DTrace probe to query a massive amount of process information.
  • …and more!

By the end of this book, you’ll have the tools and knowledge to answer even the most obscure question about your code — or someone else’s.

To celebrate the launch of the book, it’s currently on sale for $44.99 — that’s a $10 discount off the cover price! But don’t wait too long, as the launch deal is only on until Friday, May 19th.

If you have any questions or comments on this tutorial, feel free to join the discussion below!

The post Assembly Register Calling Convention Tutorial appeared first on Ray Wenderlich.

Windows and WindowController Tutorial for macOS

$
0
0

Update note: This Windows and WindowController Tutorial for macOS has been updated to Xcode 8 and Swift 3 by Warren Burton. The original tutorial was written by Gabriel Miro.

Windows and WindowController Tutorial for macOS

Windows and WindowController Tutorial for macOS

Windows are the “containers” for the user interfaces presented by all macOS apps. They define the area on the screen that the app is currently responsible for, and allow users to interact using a well-understood multi-tasking paradigm. macOS apps fall into one of the following categories:

  • Single-window utility like Calculator
  • Single-window library-style “shoebox” like Photos
  • Multi-window document-based like TextEdit

Regardless of which category an app falls into, nearly every macOS app makes use of the Model-View-Controller (MVC) relationship, a core design pattern.

In Cocoa, a window is an instance of the NSWindow class, and the associated controller object is an instance of the NSWindowController class. In a well-designed app, you typically see a one-to-one relationship between a window and its controller. The third component of the MVC paradigm, the model layer, varies according to your app type and design.

In this tutorial, you’ll create BabyScript, a multi-window document-based app inspired by TextEdit. In the process, you’ll learn about:

  • Windows and window controllers
  • The document architecture
  • NSTextView
  • Modal windows
  • The menu bar and menu items

Prerequisites

This tutorial is aimed at beginners. However, you will need some basic knowledge of the following topics:

  • Swift 3.1
  • The latest Xcode, and in particular, storyboards
  • Creating a simple Mac (macOS) app
  • The First Responder and the responder chain.

If you’re not familiar with any of the above, you can brush up with some other tutorials in the Getting Started section of the macOS tutorials page.

Getting Started

Launch Xcode, and choose File / New / Project…. Select macOS / Application / Cocoa Application, and click Next.

In the next screen, fill out the fields as indicated below. Make sure that Create Document-Based Application is checked, that the Document Extension is set to “babyscript”, and the rest of the options are unchecked.

Click Next and save your project.

Build and run, and you will see this window:

First window state

To open more documents, select File / New (or press Command-N). All the new documents are positioned in the same place, so you’ll only see the top document until you drag them around. You will fix this very soon.

Open many windows

Documents: Under the Hood

Now you’ve seen it in action, let’s take a few minutes to see how a document based app works.

Document Architecture

A document is an instance of the NSDocument class that acts as the controller for the data or model in memory – you can view this model in a window. It can be written to or read from a disk or iCloud.

NSDocument is an abstract class, which means that you always create a subclass of it because on its own it does not provide enough functionality to work.

The other two major classes in the document architecture are NSWindowController and NSDocumentController.

These are the roles of each primary class:

  • NSDocument: Creates, presents and stores document data
  • NSWindowController: Manages a window in which a document is displayed
  • NSDocumentController: Manages all of the document objects in the app

Here’s a chart that shows how these classes work together:

document architechture

Disabling Document Saving and Opening

The document architecture provides built-in mechanisms for saving/opening documents. However, this is one of the things you need to complete for yourself in a subclass.

Open Document.swift. You’ll find the empty implementation of data(ofType:), for writing to files, and read(from:ofType:) for reading from files.

Saving and opening documents is outside the scope of this tutorial, so you’ll make some changes to disable this behaviour and avoid any confusion in functionality.

Open Document.swift and replace the autosavesInPlace implementation with this:

override class func autosavesInPlace() -> Bool {
  return false
}

The above disables the autosave feature. Now, you need to disable all menu items related to opening and saving. But before you do, notice that all the functionality you would expect is already there. For example, build and run, then select File / Open. Notice the Finder dialog box, including controls, sidebar, toolbar etc., is there:

stock open window

When it has no action defined, a menu item is rendered useless. So, you’ll disconnect actions that are defined for the menu items you need to disable.

no-saving-for-you

Open Main.storyboard. Go to the Application Scene and select File / Open menu item in the Main Menu. Then, switch to the Connections Inspector tab on the right sidebar. As you can see, it connects the menu action to the first responder via the openDocument: selector. Delete this connection by clicking on the x as shown below:

break open action

Repeat this step to delete the actions for Save, Save As and Revert to Saved menu items.
And then, delete the Open Recent menu item entirely.

Now, open Document.swift and add this method to the class implementation to show an alert when you try to save. You’ll see this alert later on in the tutorial.

override func save(withDelegate delegate: Any?, didSave didSaveSelector: Selector?, contextInfo: UnsafeMutableRawPointer?) {
  let userInfo = [NSLocalizedDescriptionKey: "Sorry, no saving implemented in this tutorial. Click \"Don't Save\" to quit."]
  let error =  NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: userInfo)
  let alert = NSAlert(error: error)
  alert.runModal()
}

Build and Run. Select the File menu and check that it looks like this:

Now that you’ve finished breaking the windows, you can begin to put some new glass in :]

Window Position

The first thing you’ll fix is the issue of windows appearing exactly on top of each other when you create new documents.

You will do this by creating a subclass of NSWindowController and adding some code to it to control the initial location of the document window.

Create a Subclass of NSWindowController

Select the BabyScript group in the Project Navigator, and choose File / New / File…. In the dialog that pops up, select macOS / Source / Cocoa Class and click Next.

Create a new class called WindowController and make it a subclass of NSWindowController. Make sure the checkbox to create a XIB is unchecked, and the Language is set to Swift.

create window controller subclass

Click Next and choose the location to save the new file.

Next, you need to make sure that your window controller on the storyboard is an instance of WindowController. Open Main.storyboard, and select Window Controller in the Window Controller Scene. Open the Identity Inspector and select WindowController in the Class drop-down.

A Cascade of Windows

Remember how your document windows all opened on top of each other previously? You will now make your windows cascade across the screen as you create them. Open WindowController.swift and add the following code to the class implementation:

required init?(coder: NSCoder) {
  super.init(coder: coder)
  shouldCascadeWindows = true
}

You set the shouldCascadeWindows property to true to tell the window controller to cascade its windows.

Build and run and you will see each new window offsets itself from the previous one so all windows are visible at the same time.

Put it on the Tab

Cascading windows are nice, but they are a bit retro. So, how about using the latest hot Sierra API to switch to tabbed windows?

Open Main.storyboard and select the Window in the Window Controller scene. Then, open the Attributes Inspector and switch the Tabbing Mode control to Preferred.

configure for tabbing

And that’s it. With that single change your app has adopted the new tabbed style!

Build and run the app. Open several new documents and see how they all tab together in one window.

When you run BabyScript, macOS makes a few decisions regarding the size of the current screen and the requested window size to decide where to place a window and how large the actual window should be.

There are two ways to control this position and size. You will learn about them next.

Set the Window’s Position with Interface Builder

First you will use Interface Builder to set the initial position.

Open Main.storyboard, and select the Window in the Window Controller Scene. Then select the Size Inspector. Run BabyScript – or bring it to the front – and you should see the following screen:

Entering numeric values for the X and Y under Initial Position is one way to set the window’s position. You can also set it visually by dragging the gray rectangle in the tiny preview window just below the X and Y values.

Note: The origin for Cocoa views is the bottom left corner. So, Y values increase with distance from the bottom edge. This is in contrast to iOS where the view origin is at top-left.

If you click the red constraints around the gray window in the window preview, you can control the decisions that macOS makes when placing a new window on the screen. Notice how the pulldown menus below the preview change as you do this.

They are initially set to Proportional Horizontal and Proportional Vertical. This means that the window’s initial position will depend on the size of the screen that its being opened on. Now, make these changes:

  1. Set the two pulldowns to Fixed From Left & Fixed From Bottom.
  2. Set the initial position to X:200 and Y:200

Build and run. Notice how your first new window ends up in the exact same position regardless of screen size.

BL aligned window

Note: macOS remembers window positions between app launches. In order to see the changes you make, you need to close the window(s), and then build and run.

Set the Window’s Position Programmatically

In this section you’ll accomplish the same thing you did previously using Interface Builder, but this time you’ll do it programatically. This approach gives you runtime control of the window’s initial position. You might find this approach more flexible in some situations.

You will make your changes to the windowDidLoad method in your window controller. When windowDidLoad is called, the window has already completed loading all its views from the storyboard, so any configuration you do will override the settings in the storyboard.

Open WindowController.swift and replace the windowDidLoad implementation with the following:

override func windowDidLoad() {
  super.windowDidLoad()
  //1.
  if let window = window, let screen = window.screen {
    let offsetFromLeftOfScreen: CGFloat = 100
    let offsetFromTopOfScreen: CGFloat = 100
    //2.
    let screenRect = screen.visibleFrame
    //3.
    let newOriginY = screenRect.maxY - window.frame.height - offsetFromTopOfScreen
    //4.
    window.setFrameOrigin(NSPoint(x: offsetFromLeftOfScreen, y: newOriginY))
  }
}

The above code sets the window’s top-left corner 100 points offset in both the x and y directions from the top-left of the screen as follows:

  1. Get the NSWindow and NSScreen instances so you can calculate the geometry.
  2. Ask for the visibleFrame of the screen.
  3. Subtract your window’s height along with the desired offset from the screens height. Remember you are trying to get the position for the bottom edge.
  4. Set the origin to the calculated point.

The visibleFrame property of NSScreen excludes the areas taken by the Dock and Menu Bar. If you didn’t take this into account, you might end up with the Dock obscuring part of your window.

Build and run. The window should now sit 100 points in each direction from the screen’s top-left corner.

TL aligned window

Make BabyScript a Mini Word Processor

Cocoa has some amazing UI functionality just waiting for you to drag into your app window. Here, you’ll explore the super powerful and versatile NSTextView. But first, you need to know about the content view of NSWindow.

The Content View

The contentView is the root of the view hierarchy of a window. It sits inside the window’s chrome (Title Bar & Controls) and it’s the view where all the user interface elements are located. You can replace the default one with your own view by just changing the contentView property. You won’t do that in this tutorial, but it’s useful to know.

Content View

Add the Text View

Open Main.storyboard and remove the text field that says “Your document contents here” from the content view. Now, add a text view:

  1. Still in the storyboard, open the Object Library.
  2. Search for NSTextView.
  3. Drag the Text View and drop it on the content view.
  4. Resize the text view so its inset is 20 points on each side from the content view. The blue dotted alignment guides will help you here.
  5. In the Outline View, select Bordered Scroll View. Note that the text view is nested in the Clip View, which is nested inside a scroll view.
  6. Select the Resolve Auto Layout Issues control and select Reset To Suggested Constraints

add and resize text view

set textview constraints

Build and run — you should see the following:

empty text window

Look at that friendly, blinking text insertion point inviting you to enter some text! Start your manifesto, or stick to a simple “Hello World”, and then select the text. Copy it with Edit / Copy or Command – C, and then paste several times, just to put the app through its paces.

Explore the Edit and Format menus to get an idea of what’s available. You might have noticed that Format / Font / Show Fonts is disabled. You’re going to fix that now.

Enable the Font Panel

In Main.storyboard, go to the main menu, click on the Format menu, then on Font, then on Show Fonts.

Go to the Connections Inspector and you’ll see that no actions are defined for this menu item. This explains why the menu item is disabled, but what do you connect it to?

The action is already defined in the code imported indirectly by Xcode as part of Cocoa – you just need to make the connection. Here’s what you do:

  1. While holding down the Ctrl key click Show Fonts and drag it to the First Responder in the Application Scene. Then release the mouse.
  2. A window with a scrollable list of all the available actions will pop up. Look for and select orderFrontFontPanel:. You can also start typing orderFrontFontPanel to find it more quickly.
  3. Take a look at the Connections Inspector with Show Fonts selected. You’ll see the menu is now connected to orderFrontFontPanel: of the first object in the responder chain that responds to this selector.

connect font menu to first responder

Build and run the app, then enter some text and select it. Choose Format / Font / Show Fonts to open the fonts panel (or press Cmd-T). Play with the vertical slider on the right side of the font panel, and observe how the text size changes in real time.

font panel in action

You didn’t write a single line of code, yet you have the power to change the font size. How did that work? That’s because the NSFontManager and NSTextView classes do most of the heavy lifting for you.

  • NSFontManager is the class that manages the font conversion system. It implements the method orderFrontFontPanel, so when the responder chain forwards the message to it, it shows the system’s default font panel.
  • When you change the font attributes in the panel, NSFontManager sends a changeFont message to the First Responder.
  • NSTextView implements changeFont and it’s the first object in the responder chain because you just selected some text. So, when the font attributes change, it automatically modifies the font of the selected text accordingly.

Initialize the Text View with Rich Text

To see the full power of NSTextView, download some formatted text from here, to use as the initial text for the text view.

Open it with TextEdit, select all the text and copy it to the clipboard. Then, open Main.storyboard and select the Text View. Open the Attributes Inspector and paste the copied text into the Text field.
Now, switch on the Graphics and Image Editing check boxes to allow images in the text view.

populate and configure text field

Build and run, and you should see:

window with rich text

The image from the original text you copied is gone! How come?

You can’t add images to the Interface Builder text storage field – so the image was not stored in the storyboard. But you can drag in, or paste images in, to the text view when BabyScript is running. Have a go if you want.

edit image

After you’ve made some changes to the text, or pasted in an image, try to close the window. In the alert box that pops up, chose to save the document. You’ll now see the error alert that you set up right at the start of the tutorial. :]

save alert

Show the Ruler by Default

To show the ruler automatically when a BabyScript window opens, you’ll need an IBOutlet connected to the text view. Open ViewController.swift, and delete the default viewDidLoad implementation. Then add the following code:

@IBOutlet var text: NSTextView!

override func viewDidLoad() {
  super.viewDidLoad()
  text.toggleRuler(nil)
}

This code defines an outlet for the text view, and in viewDidLoad calls the text view toggleRuler method to show the ruler – the ruler is hidden by default.
Now you need to connect the text view to this outlet in Interface Builder.

Open Main.storyboard and click on the ViewController proxy. Hold down Ctrl, drag into the text view until it highlights, and then release the mouse. A small window with the list of Outlets will show. Select the text outlet:

connect text outlet

Build and run, and now each editor window shows the ruler:

ruler is automatic

With two lines of code and the default functionality provided by Cocoa, you have created a mini word processor!

Stand up, stretch, have a drink, and get ready for the next section :]

Modal Windows

Modal windows are the attention seekers of the window world. Once presented, they consume all events until they are dismissed. You use them to do an activity that demands all of the user’s focus. The save and open panels that all macOS apps use are good examples of modals.

There are 3 ways to present a modal window:

  1. As a regular window using NSApplication.runModal(for:).
  2. As a sheet modal from a window using NSWindow.beginSheet(_:completionHandler:).
  3. Via a modal session. This is an advanced topic which won’t be covered in this tutorial.

Sheet modals appear from the top of the window that presents them. The save alert in BabyScript is an example.

Sheet Modal Example

You won’t take sheet modals in this tutorial any further. Instead, in the next sections you’ll learn how to present a detached modal window that shows the word and paragraph count for the active document.

Add a New Window to the Scene

Open Main.storyboard. Drag a new Window Controller from the Object Library into the canvas. This creates two new scenes: a Window Controller Scene and a View Controller Scene for its content:

Select the Window from the new Window Controller Scene and use the Size Inspector to set its width to 300 and height to 150.

set window size

With the window still selected, select the Attributes Inspector and uncheck the Close, Resize and Minimize controls. Then, set its title to Word Count.

The Close button would introduce a serious bug because clicking the button will close the window, but won’t call stopModal, so the app would remain in a “modal state”.

Having minimize and resize buttons in the title bar would be strange. Also, it’s a violation of Apple’s Human Interface Guidelines (HIG).

Now, select the View from the new View Controller Scene and use the Size Inspector to set its width to 300 and height to 150.

set view content size

Setting Up the Word Count Window

Open the Object library and drag 4 Label instances on to the contentView of the Word Count window. Line them up like the image below. Since this window can’t be resized, you don’t have to worry about automatic layout.

add 4 textfields

Select the Attributes Inspector. Change the labels’ titles to Word Count, Paragraph Count, 123456 and 123456 as in the screenshot below. (Since you’re not using autolayout to dinamically adjust the label’s width, you use a long placeholder text like 123456 to make sure the label is wide enough at runtime and the numbers are not truncated). Now change the alignment of all the labels to right justified.

Next, drag a Push Button on to the content view.

drag button to scene

Change the button title to OK.

configure button

Create the Word Count View Controller Class

You’ll create an NSViewController subclass for the Word Count View Controller like this:

  1. Select File / New / File…, choose macOS / Source / Cocoa Class.
  2. In the Choose Options dialog, enter WordCountViewController in the Class field.
  3. Enter NSViewController in the Subclass of field.
  4. Make sure that “Also create XIB for user interface” is unchecked.

add view controller subclass

Click Next and create the new file.

Open Main.storyboard. Select the proxy icon for the word count view controller and open the Identity Inspector. Select WordCountViewController from the Class drop-down.

set custom class

Bind the Count Labels to the View Controller

Next, you’ll use Cocoa Bindings to show the count values in the view controller. Open WordCountViewController.swift, add the following inside the class implementation:

dynamic var wordCount = 0
dynamic var paragraphCount = 0

The dynamic modifier makes the two properties compatible with Cocoa Bindings.

Open Main.storyboard and select the numeric text field for the word count. Then open the Bindings inspector and do the following:

  1. Expand the Value binding by clicking on its disclosure triangle.
  2. Select Word Count View Controller from the Bind To pull down.
  3. Check Bind To
  4. Type wordCount in the Model Key Path

Repeat the same for the paragraph count numeric label, but this time use paragraphCount into the Model Key Path.

Note: Cocoa Bindings is a super useful technique for UI development. If you want to learn more about it, have a look at our Cocoa Bindings on macOS tutorial.

Finally, assign a Storyboard ID to the controller.

Select the Window Controller of the Word Count window. Then, open the Identity Inspector, and enter Word Count Window Controller in the Storyboard ID field.

set storyboard id

Presenting and Dismissing a Modal Window

You now have the storyboard components for the Word Count window ready and waiting. It’s time to open those windows and let some air in :]

In the next few sections you’ll add the code to present the window and to make it go away again. You are almost done. So, hang in there!

Show Me the Modal

Open ViewController.swift and add the following method to the class implementation:

@IBAction func showWordCountWindow(_ sender: AnyObject) {

  // 1
  let storyboard = NSStoryboard(name: "Main", bundle: nil)
  let wordCountWindowController = storyboard.instantiateController(withIdentifier: "Word Count Window Controller") as! NSWindowController

  if let wordCountWindow = wordCountWindowController.window, let textStorage = text.textStorage {

    // 2
    let wordCountViewController = wordCountWindow.contentViewController as! WordCountViewController
    wordCountViewController.wordCount = textStorage.words.count
    wordCountViewController.paragraphCount = textStorage.paragraphs.count

    // 3
    let application = NSApplication.shared()
    application.runModal(for: wordCountWindow)
    // 4
    wordCountWindow.close()
  }
}

Taking it step-by-step:

  1. Instantiate the Word Count window controller using the Storyboard ID you specified before.
  2. Set the values retrieved from the text view’s storage object (word and paragraph count) as the relevant word count view controller properties. Thanks to Cocoa Bindings, the text fields will automatically display those values.
  3. Show the Word Count window modally.
  4. Close the Word Count window once the modal state is over. Note that this statement does not execute till the modal state is completed.

Go Away, Modal

Next, you’ll add code to dismiss the Word Count window. In WordCountViewController.swift, add the following code to the class:

@IBAction func dismissWordCountWindow(_ sender: NSButton) {
  let application = NSApplication.shared()
  application.stopModal()
}

This is an IBAction that will be invoked when the user clicks the OK button on the Word Count window.

In this method you simply stop the modal session you started earlier. A modal session must always be explicitly stopped to return the app to normal operations.

Open Main.storyboard. Click on the OK button, then hold Ctrl down and drag to the proxy icon of the Word Count View Controller. Release the mouse and select dismissWordCountWindow: from the presented list:

connect OK button to action

Add UI to Invoke Modal

Still in Main.storyboard, go to the Main Menu, expand the Edit menu item, and do the following:

  1. From the Object Library, drag a Menu Item to the bottom of the Edit menu.
  2. Select the Attributes Inspector and set the title to Word Count.
  3. Create a keyboard shortcut by entering Command – K as the key equivalent.

add word count menu

Now, you’ll connect the new menu item to the showWordCountWindow method in ViewController.swift.

Click on the Word Count menu item, then hold Ctrl down and drag over to the First Responder in the Application scene. Select showWordCountWindow: from the list.

connect word count menu to first responder

Here, you connected the menu item to the first responder, not directly to showWordCountWindow in ViewController. This is because the application main menu and view controller are in different storyboard scenes, and can’t be connected directly.

Build and run the app, select Edit / Word Count (or press Cmd-K), and the word count window should present itself.

working word count window

Click OK to dismiss the window.

Where To Go From Here?

Here is the final version of BabyScript.

You covered a lot of ground in this windows and window controllers for macOS tutorial:

  • The MVC design pattern in action.
  • How to create a multi-window app.
  • Typical app architecture for macOS apps.
  • How to position and arrange windows with Interface Builder and via code.
  • Passing actions from UI to the responder chain.
  • Using modal windows to display additional information.

And more!

But it’s just the tip of the iceberg as far as what you can do with windows and window controllers. I strongly recommend that you explore Apple’s Window Programming Guide if you want to learn even more about the subject.

For a better understanding of Cocoa and how it works with the types of apps mentioned at the beginning, check out the Mac App Programming Guide. This document also expands upon the concept of multi-window document-based apps, so you’ll find ideas to keep improving BabyScript there.

If you would like to see the complete version, with saving and opening documents working, download this more complete app. It gives you an idea of how little work is needed to implement a complete document based app.

I look forward to hearing your ideas, experiences and any questions you have in the forums below!

The post Windows and WindowController Tutorial for macOS appeared first on Ray Wenderlich.


Custom LLDB Commands in Practice

$
0
0
Searching using Custom LLDB Commands in Practice

LLDB: With this information, nothing is out of reach!

Welcome to a “special edition” article inspired by our new Advanced Apple Debugging & Reverse Engineering book! This article will showcase the end product of some of the awesome tools you can (and hopefully will) build in the book.

In this article, you’ll explore the SpringBoard application while using some custom LLDB debugging commands and scripts I’ll give you to help aid in understanding this program.

What’s SpringBoard you say? It’s the iOS “homescreen” application responsible for launching iOS applications, Siri (mis)interpreting your latest verbal requests, viewing notifications and widgets, and much much more.

In this tutorial, you’ll explore some logic behind the SpringBoard application and see how to leverage debug scripts to do the heavy lifting for you.

Getting Started

You have a tiny bit of setup to take care of before you get to have some fun.

Download the starter package here. This contains a folder of LLDB commands and scripts which you’ll install on your computer.

LLDB will load content by searching in several predefined locations on your computer. One of them is located at ~/.lldbinit.

Use your favorite text editor and open this file. For this particular example, I’ll just use a simple Terminal text editor nano, but feel free to use your own if it’s more convenient.

  1. In Finder, navigate to the directory you’ve downloaded that contains the lldb_commands directory. Keep this Finder window open for a second as you’ll drag and drop a file into Terminal in a moment. In Terminal, open up the ~/.lldbinit using nano or equivalent.
nano ~/.lldbinit

Then press Enter.

Terminal using nano to open .lldbinit

  1. In nano (or equivalent), type the following:
command script import

Nano editor editing lldbinit

Make sure to add a space at the very end, as you’ll add content from the Finder window now.

  1. With the Finder window, open the lldb_commands directory, then search for the file called dslldb.py. Drag this file into the Terminal window.

Dragging dslldb.py into lldbinit

  1. Save your work and close the text editor. For nano, you press Ctrl + O to save, then Ctrl + X to exit.

In summary, here’s what you should do:

Animated dragging dslldb.py file from Finder into lldbinit

The dslldb.py file will search for all Python files in the same directory and load them into LLDB when it starts up. In addition, it looks for any .txt files and adds those commands in as well. We take a deep dive into this stuff in the book, but for now let’s just enjoy what you can do with these commands.

Testing that Everything Worked

In a new Terminal window, type the following:

lldb

This will launch a blank LLDB session in Terminal. Now type the following:

(lldb) help search

This will consult the help documentation for a new command you’ve added called search. Provided everything went correctly, you’ll get some help text for this command.

If you get something like the following:

(lldb) help search
error: 'search' is not a known command.
Try 'help' to see a current list of commands.
Try 'apropos search' for a list of related commands.
Try 'type lookup search' for information on types, methods, functions, modules, etc.

This means the LLDB commands were not successfully installed. Make sure you have no spaces in the directories you installed the LLDB commands in or surround your path in quotes.

Provided the LLDB commands were successfully installed, you’ll have access to the following commands:

  • search: Enumerate all pointers on the heap for a particular class. Can filter objects by a particular module (i.e. UIKit) or by a certain condition.
  • lookup: Perform a regular expression search for classes, functions, or methods.
  • msl: Get the stack trace for the last deallocation or allocation event for a particular pointer.
  • methods: Dump all Objective-C methods for an NSObject subclass (iOS only)
  • ivars: Dump all instance variables for an Objective-C NSObject subclass instance (iOS only)

These are only a small list of what’s possible with LLDB; you’ll discover some more amusing commands while exploring SpringBoard.

Note: If you want the latest and greatest commands I’m working on, check out https://github.com/DerekSelander/lldb. Whenever I need a command, I’ll build it, and stick it up on that repo. You might find some amusing things there.

You don’t need that Terminal window anymore so feel free to kill it and jump to Xcode.

Playing With SpringBoard

I often like to see how developers have created something while in production. By exploring what others have done, I can learn from their implementations and write better code myself.

Unfortunately, Apple ain’t gonna open-source any of their iOS apps anytime soon, so I need other ways to learn how they’ve designed their applications. The iOS Simulator provides several functional examples of iOS applications, which I can use along with LLDB to inspect how they’ve been architected.

A lot of people seem to think normal debugging and reverse engineering applications use a different set of debugging skills. I couldn’t disagree with that idea more. Reverse engineering someone else’s application supercharges your debugging skills, which is why I often teach about debugging through reverse engineering. If you can quickly find something of interest without reading a line of source code, imagine how fast you’d be when you’re tasked on finding a bug within your own application?

Attaching to SpringBoard

With LLDB, it’s possible to connect to any application on your computer (provided you have Rootless disabled). Fortunately, you don’t need to have Rootless disabled to attach to the iOS Simulator applications.

This means you can use Xcode to attach to SpringBoard and use all the shortcuts and commands you are accustomed to.

Open up any Xcode application — yes, any. You’re not going to build this actual application, but instead use the existing windows for exploring the SpringBoard application.

Make sure the iOS 10.3 iPhone 7 Plus Simulator is up and running.

Jump to Xcode. In the Debug menu, select Attach to Process, then choose SpringBoard.

Xcode attaching to a process

Give LLDB & Xcode a second as it attaches to SpringBoard. When successful, you’ll see a pause button show up on the LLDB console in Xcode. Stop the process by clicking on the pause button in the LLDB console.

Xcode pause button in the LLDB Console

You might need to toggle the display of the LLDB console by pressing ⌘ + Shift + Y.

Once the SpringBoard application is paused, type the following into LLDB:

(lldb) dclass

This will dump every single Objective-C class available to the SpringBoard process. As you can see, there’s several classes out there…

Note: I know most of you now only care about Swift and have little interest in exploring Objective-C classes, but Swift borrows heavily from Objective-C code and at the time of writing, SpringBoard doesn’t have any Swift classes within the process. You can hunt for “pure” Swift classes by typing dclass -f SwiftObject in LLDB, or Swift-implemented NSObject subclasses by looking for the period in a class name (i.e. dclass -r \\.). If you want to learn the logic behind this, check out Chapter 21 in the book: “Script Bridging with SBValue & Language Contexts”.

Why not filter the dclass command a bit? Dump every class that’s a subclass of UIView that’s available in the process:

(lldb) dclass -f UIView -m SpringBoard

This will limit your query to only the UIView subclasses implemented inside the SpringBoard executable.

There’s still a lot of UIViews. Filter your search to only display classes that contain the case insensitive phrase “image” inside of the class name.

(lldb) dclass -f UIView -m SpringBoard -r (?i)image

This will only display classes whose name contains the case insensitive phrase “image” inside the class name, implemented inside the SpringBoard executable, which are a subclass of UIView. Crazy right?

What’s that weird (?i) all about? In Advanced Apple Debugging & Reverse Engineering, you’ll learn function signatures unique for Objective-C and Swift code and how to perform smart regular expressions to search for any code of interest.

You’ll only get a couple hits for classes:

Dumping all classes in SpringBoard, with filter: UIView
************************************************************
SBDeckSwitcherIconImageContainerView
SBSwitcherSnapshotImageView
SBIconImageView
SBStarkIconImageView
SBLiveIconImageView
SBClockApplicationIconImageView
SBFolderIconImageView
SBIconImageCrossfadeView
SBIconImageFolderCrossfadeView
SBIconImageAppCrossfadeView
SBIconImageAppLowQualityCrossfadeView
SBDarkeningImageView
SBCornerAnimatingImageView
SBAutoPurgingImageView
SBImageAlertView

From the output, let’s go after that SBIconImageView class. Dump all the methods and properties implemented by the SBIconImageView class:

(lldb) methods SBIconImageView

You’ll get something similar to the following truncated output:

<SBIconImageView: 0x10b472258>:
in SBIconImageView:
  Class Methods:
    + (id) viewMap; (0x10aef017d)
    + (unsigned long) viewMap:(id)arg1 maxRecycledViewsOfClass:(Class)arg2; (0x10aef023c)
    + (id) windowForRecycledViewsInViewMap:(id)arg1; (0x10aef0249)
    + (void) recycleIconImageView:(id)arg1; (0x10aef02a0)
    + (id) dequeueRecycledIconImageViewOfClass:(Class)arg1; (0x10aef0312)
    + (double) cornerRadius; (0x10aeef0e1)

This will not only dump the class methods and instance methods, but also the properties implemented by this class and the address in memory of where this code is loaded in memory.

If you wanted to privately use this SBIconImageView class in your own code, you can use dclass to create an Objective-C header for this private class. Type the following in LLDB:

(lldb) dclass -p SBIconImageView

This will generate an Objective-C header file you can plug into your own app to utilize this class.

Generated Obj-C header file for SBIconImageView

Note: In order to be able to call this SBIconImageView class in your own code, you’d need to load the appropriate dynamic library that’s responsible for this class. In the book, this is covered in Chapter 15, “Hooking & Executing Code with dlopen & dlsym”.

Jump back to that SBIconImageView class, wouldn’t it be great to hunt down all the currently-live objects of that class in memory? Well, with the search LLDB command, you can dynamically hunt for all instances of a class on the heap. In LLDB, type the following:

(lldb) search SBIconImageView

You’ll get something similar to the following truncated output:

(lldb) search SBIconImageView
<__NSArrayM 0x618000858270>(
<SBIconImageView: 0x7ff6ad7492f0; frame = (-1 -1; 62 62); userInteractionEnabled = NO; layer = <CALayer: 0x6100002226a0>>,
<SBIconImageView: 0x7ff6b0a78e30; frame = (-1 -1; 62 62); userInteractionEnabled = NO; layer = <CALayer: 0x608000225520>>,
<SBIconImageView: 0x7ff6ad743d90; frame = (-1 -1; 62 62); userInteractionEnabled = NO; layer = <CALayer: 0x610000221700>>,

This is nice, but where are these classes in SpringBoard? You can easily query all these classes and perform a custom action on them with an option from the search command. Type the following:

(lldb) search SBIconImageView -p '[obj setHidden:YES]'

Jump over to the iOS Simulator to see what you’ve just done.

iOS Simulator with all application icons hidden

Can you accurately guess what class the SBIconImageView is used for?!

Undo your work by unhiding all of the SBIconImageViews.

(lldb) search SBIconImageView -p '[obj setHidden:NO]'

The search command is nice, but it returned results for all applications — that’s way too many. What if you only wanted to find the SBIconImageView responsible for the Messages application?

Using the methods command, you can search through interesting code that can help you determine how to uniquely identify a particular SBIconImageView.

For example the SBIconImageView has a property named icon, which holds a class called SBApplicationIcon. Dump the methods implemented by this class

(lldb) methods SBApplicationIcon

Inside of this class is a property called displayName. You can use this knowledge to quickly hunt down the SBIconImageView by displayName!

In LLDB, type:

(lldb) search SBIconImageView -c '[[[obj icon] displayName] containsString:@"Messages"]'

This will (hopefully) return only one SBIconImageView whose displayName contains "Messages". You’ll get something similar to the following:

<__NSArrayM 0x618000e5dac0>(
<SBIconImageView: 0x7fb7b567e020; frame = (-1 -1; 62 62); userInteractionEnabled = NO; layer = <CALayer: 0x61000023a660>>
)

Copy the reference to the SBIconImageView. In my case, it’s 0x7fb7b567e020, but your reference address will be different. Toggle the view off with the tv command:

(lldb) tv 0x7fb7b567e020

The images for the Messages application should now disappear:

iOS Simulator showing the Messages app icon hidden

While you’re at it, check out all the properties that are being referenced for this instance:

(lldb) ivars 0x7fb7b567e020

The ivars as well as the methods command are built off of code already compiled into an iOS executable. You’re just using this code in an applied way while debugging. You’ll learn about ways to search for this kind of code in Chapter 7: “Image”.

In fact, let’s use one of the final commands you build — lookup — which you’ll create in Chapter 22, “SB Examples, Improved Lookup”. This command will search for all code inside an executable for a particular regular expression name.

In LLDB, type the following:

(lldb) lookup Test

This will spit out a LOT of code. You can actually just get the summary of where this code is with the --summary option instead:

(lldb) lookup Test -s

I got something similar to the following truncated output:

1 hits in: AssistantServices
39 hits in: ChatKit
9 hits in: FrontBoard
5 hits in: VideoToolbox
28 hits in: CoreData
7 hits in: MPUFoundation
5 hits in: CoreDuet
2 hits in: BaseBoardUI
7 hits in: MediaServices
5 hits in: PassKitCore
11 hits in: MusicLibrary
16 hits in: Foundation
6 hits in: Sharing
2 hits in: libsqlite3.dylib
8 hits in: PhotoLibrary

Let’s say I wanted to explore only the BaseBoardUI module. I can use the lookup command to filter queries based upon a module:

(lldb) lookup Test -m BaseBoardUI
****************************************************
2 hits in: BaseBoardUI
****************************************************
-[UIView(BaseBoardUI) bs_isHitTestingDisabled]

-[UIView(BaseBoardUI) bs_setHitTestingDisabled:]

This means I can use this code on any UIView within the SpringBoard application! For example, I could type po [[UIApp keyWindow] bs_isHitTestingDisabled] to try this property out.

Something that isn’t in here is any code based upon the SpringBoard application. This is understandable, because the executable’s code is stripped out, and you have no debugging symbol information. This is different for Frameworks, because they need to keep around this information so when loaded, it knows the correct address.

But that really makes me sad that we can’t search the executable using the lookup command.

Wait! Guess what? You can!

Type the following:

(lldb) lookup Test -X

This will use the Objective-C runtime to perform a regular expression search instead of using the DWARF debugging information!

As you can see, there’s a lot of testing code that gets shipped with the final product of SpringBoard. Try this code out:

(lldb) po [[SBTestDataProvider sharedInstance] publish]

Once you resume the application by pressing the resume button or typing continue in LLDB, you’ll see the following pop up!

iOS Simulator displaying a notification

Yay! Notifications!

So was that a fun debugging session or what?

Where to Go From Here?

As you can see, there’s a lot of power in custom debugging commands. Advanced Apple Debugging & Reverse Engineering will let you take a tremendous leap forward in what you think is possible when debugging.

If you enjoyed what you learned in the tutorial, check out the complete Advanced Apple Debugging & Reverse Engineering book, available on our store.

Here’s a taste of what’s in the book:

Advanced Apple Debugging & Reverse Engineering Book Cover

  • Getting Started: Learn your way around LLDB and its extensive list of subcommands and options.
  • Python Power: Use LLDB’s Python module to create powerful, custom debugging commands to introspect and augment existing programs.
  • Understanding Assembly: Truly understand how code works at an assembler-level and how you can explore code in memory.
  • Ptrace and Friends: Learn how to leverage ptrace, dlopen and dlsym to hook into C and Swift functions to explore code that you don’t have the source for.
  • Script Bridging: Extend the debugger to make it do almost anything you want, and learn how to pass in options or arguments to your debugging scripts.
  • DTrace: Dig deep and hook into a function with a DTrace probe to query a massive amount of process information.
  • …and more!

By the end of this book, you’ll have the tools and knowledge to answer even the most obscure question about your code — or someone else’s.

To celebrate the launch of the book, it’s currently on sale for $44.99 — that’s a $10 discount off the cover price! But don’t wait too long, as the launch deal is only on until Friday, May 19th.

If you have any questions or comments on this tutorial, feel free to join the discussion below!

The post Custom LLDB Commands in Practice appeared first on Ray Wenderlich.

Video Tutorial: Advanced Swift 3 Part 9: Ranges

Video Tutorial: Advanced Swift 3 Part 10: Types as Documentation

Beginning C# with Unity Part 30: Polymorphism

Full-Time Indie iOS Dev and Co-Founder of 1Button: A Top Dev Interview With Thomas Castel

$
0
0

Co-Founder of 1Button, Thomas Castel

Welcome to another installment of our Top App Dev Interview series!

Each interview in this series focuses on a successful mobile app or developer and the path they took to get where they are today. Today’s special guest is Thomas Castel.

Thomas is the co-founder of a 3-person indie app development studio in France called 1Button. Together he and his co-founders have developed over 15 apps, of which 14 have been featured on the App Store worldwide.

In this interview, Thomas explains how he and the 1Button team manages their day to day processes for releasing new apps, and shares some great advice. Let’s dive in!

Indie Developer

Thomas, you’re one of the rare 100% full-time indie developers. Can you explain how you transitioned to being full-time indie developer?

Back in 2010, after graduating from the same software engineering school, Alexandre, Jeremie (the two other co-founders of 1Button) and I were all working in different companies but we were not happy, we wanted to create things and to work on our own projects. So we started to make apps during our free time.

At first, of course, our apps were not successful… We made only $17 with our first app! But little by little, app after app, we started to gain experience and make a little money.

It took us two years to reach the point where I could start working full-time from home. I was the only one working full-time. One year later, Jeremie was able to quit his job and we officially created the company in April 2013. 1Button was born. For the first time we had our own office! Another year later, Alexandre finally quit his job too and the triforce was reunited :]

Thomas, hard at work in the 1Button office.

What’s your typical daily schedule looking like?

  • 6:00: Wake up, have some breakfast.
  • 6:30-7:00: Exercise (not everyday).
  • 8:30-12:00: Start work in the office.
  • 12:00-13:00: Take a break for some lunch.
  • 13:00-17:30: Return back to work.
  • 18:00: Swimming pool (not everyday).
  • 19:00: Have some dinner.
  • 22:00: Go to sleep.

You mentioned it took you 3 years working in a free time before you were all able to quit your jobs and create a company. However, most developers would have given up within that time! How did you manage to keep motivated and positive during the long road it took?

As software engineers, we knew how to develop apps, but we quickly understood that we were completely unable to sell them.

So we focused on improving ourselves in this area, and we saw every little success as a milestone. Even if we didn’t make any money with our first apps, we were very happy when we got 10k downloads for the first time, 100k downloads, 1M downloads, first news on a famous website, etc. This way we had the feeling that each new app was a step forward to the success. Even if there were no visible success, we learnt a lot of things along the way too.

We are very good friends too we do a lot of things together. Recently we traveled in Japan and in California together and we share the same passion for good food and dark chocolate.

Running 1Button

Can you tell me how 1Button started from the past to present?

After officially creating the company, we kept focused on what we did previously. We developed some simple puzzle games and some utilities, like Mr Mood, a minimalist private journal for monitoring user’s moods.

Mr Flap was a great success!

We continued and spent too much time on an over-complicated fast-paced puzzler that miserably failed.

In 2014, during the Flappy Bird buzz, we casually launched Mr Flap, our own attempt on the Flappy Bird concept, that we managed to develop in just 10 days.

It did so well on the App Store that we had to develop an Android version too, it was our first real success, almost out of nowhere. In 2015, among other games, we launched Mr Jump, a minimalist platformer. It did over 10 times better than Mr Flap in terms of downloads and money so we released several updates with new levels and power-ups.

We never slow down and get stuck on the one game, so we started to work on new projects. One of them is Nekosan (‘Mr Cat’ in Japanese), that we launched in 2016. We see it as a spiritual sequel of Mr Jump, but it didn’t reach the same success.

What is your definition of success at 1Button?

We are happy as long as we can live from our passion. But of course, we like it when one of our games is a hit and when everyone talks about it. That’s what happened with Mr Jump, and it was super satisfying to know that thanks to this success we were now completely free to work on any project for many months.

You’re 1 of 3 members of the team at 1Button (Co-Founder). Can you tell me the structure of the company and who plays which role?

As we are only 3, we have a very simple structure with no hierarchy. We went to the same software engineering school so we basically have the same background. But we also have our own specialities, which is great because we do everything internally.

Alexandre, the love of server-side!

Creating a game is not only about coding, it is also about creating images, soundtracks, sound effects, videos, levels, texts, photos, etc. Once the game is finished, we also need to communicate about it, manage the ad networks, etc.

  • Alexandre loves server-side development, so he is usually in charge of the “invisible” projects, such as the tools that we need for our apps (push notifications, ad network mediation…), he also creates the soundtracks for our games.
  • Jeremie creates the sound effects and the videos (trailers…), and he works on the communication plans. As we have a zero-dollar marketing strategy, we send a lot of emails when we launch a game.
  • I design all the graphic files that we need inside the game (characters, items…) and outside the game (banners, icons, artworks…).

The apps you produce at 1Button are very simple, yet visually fun & addictive. Can you explain the process of how you come up with your app ideas, and how you decide which of them to pursue?

We have our own philosophy: create simple apps or games. We never spend more than 3 months on a project. This way we limit the risks in case of failure and gather more experience. Most of our ideas will fit these principles.

We usually start with a quick and dirty prototype. For example, the first prototype of Mr Jump displayed a red rectangle that was able to jump with a tap. We continued and progressively added new elements and tweaked the parameters until we were satisfied.

Most of the time we don’t have a clear vision of what the final product will look like, it is an iterative process.

The Mr Jump initial prototype

Are you taking advantage of any automation at 1Button? If so, can you tell me how and where?

This is not related to our main activity but we developed our own bot that searches for clones of our games on the App Store, Google Play, etc. It even compares the icons! When the bot finds a clone, we manually check if it is an actual copy, and if so, the bot will automatically fill and send the complaint form to make the copy removed from the store.

We have already killed 280 clones thanks to this bot!

1Button’s clone bot in action!

14 out of your 15 published iOS apps has been featured on the App Store in one way or the other worldwide. This is a massive struggle for many developers, so what advice can you give to developers itching to get their app featured?

When we launch an app, we never know if Apple will feature it on the App Store, so we don’t rely on that. The features are managed by an editorial team, which means that it is made by hand.

What helps is to follow the guidelines, use the new/exclusive technologies and, of course, make great apps and games that have never been seen before!

When we met Apple for the first time, they strongly insisted on language support. At the time we were only supporting English and French. They advised us to support more languages, so we looked for a good translation company and we launched our new apps with 14 languages. That helped a lot for being featured in other counties.

Staying Fresh

The app store is growing every day at a rapid speed. How do you keep your ideas fresh and unique so your apps stand out?

We tried to develop our own style and our own visual identity made of simple colors and geometric shapes so that our products are easily identifiable. Even our sound effects have a specific style that is common to all our products.

It’s all in our heads but we often talk about our style. We try to focus on simplicity, which means simplifying both the functionalities (what we can do with the app) and the interface (how we use the app).

When we manage to simplify these aspects, it is easy to create an app that looks simple too. This way we can usually use only a few flat colors and simple geometric shapes, with perfect alignments.

For example, in Mr Jump, thanks to several simplifications we ended up with a full-screen and refined display: as the interaction is only based on one tap to jump (the character runs automatically), we don’t need to display any control buttons, players can tap anywhere. In the same way, we don’t need a pause button, because players would not have enough time to reach it before dying.

The one tap game, Mr Jump!

What does the future look like for 1Button?

We have a rough roadmap for 2017, but we don’t know what we will do next year. We are working on ways to make our activity more durable. For now, each time we launch a product, it is like a one-shot, which is a bit risky.

Are you using Swift in your apps at 1Button & how are you re-using code across multiple apps?

Swift looks extremely modern and it is very appealing, but we are still using Objective-C in our current projects.

In fact, we have a lot of existing code that we developed over years and that we reuse in all our projects. This code would not be compatible with a Swift project for various reasons such as memory management.

All our projects are stored in a dedicated git repository and we have created a sub-repository that all our apps use. This sub-repository contains all the libraries and the classes that we have created to manage various things such as the in-app purchases for example or the ads.

We improve these libraries continually because all our apps are based on them, old apps also benefit from the improvements :]

Where To Go From Here?

And that concludes our Top App Dev Interview with Thomas Castel. Huge thanks to Thomas for sharing his indie life, his neat clone app bot and finally running a successful company 1Button.

We hope you enjoyed this inspiring interview and if you’re thinking of starting your own company or eager to make the leap to become indie to take Thomas’ advice to heart.

If you are an app developer with a hit app or game in the top 100 in the App store, we’d love to hear from you. Please drop us a line anytime. If you have a request for any particular developer you’d like to hear from, please post your suggestion below!

The post Full-Time Indie iOS Dev and Co-Founder of 1Button: A Top Dev Interview With Thomas Castel appeared first on Ray Wenderlich.

Advanced Apple Debugging & Reverse Engineering Wrap-Up — And Last Day for Discount!

$
0
0

We’re wrapping up launch week for Advanced Apple Debugging!

It’s been an exciting week for our newest book, Advanced Apple Debugging and Reverse Engineering.

We led off with with the book announcement, published a sample chapter from the book and even crafted a great tutorial on how to use the tools you’ll build in the book. We’re beat! :]

We love breaking new ground with books, and this one is no exception. Our author, Derek Selander, takes you on a fascinating journey through the deepest levels of tools such as LLDB and DTrace. He shows you how to use Python with these tools to help you explore everything you wanted to know about your own apps — or someone else’s.

Just to recap, here’s a quick overview of what’s in the book:

  • Getting Started: Learn your way around LLDB and its extensive list of subcommands and options.
  • Python Power: Use LLDB’s Python module to create powerful, custom debugging commands to introspect and augment existing programs.
  • Understanding Assembly: Truly understand how code works at an assembler-level and how you can explore code in memory.
  • Ptrace and Friends: Learn how to leverage ptrace, dlopen and dlsym to hook into C and Swift functions to explore code that you don’t have the source for.
  • Script Bridging: Extend the debugger to make it do almost anything you want, and learn how to pass in options or arguments to your debugging scripts.
  • DTrace: Dig deep and hook into a function with a DTrace probe to query a massive amount of process information.
  • …and more!

Response to the Book

We’ve received some great feedback on the book already, judging by the sample of tweets below:

Thanks to everyone who has taken the time to check out the book!

How to Get the Discount

I wanted to remind you that our launch promotion for the book is only on for one more day, ending today, Friday, May 19th. It’s currently on sale for $44.99 — that’s a $10 discount off the cover price!

Head over to our store to grab the PDF version of the book before the sale ends:

The Advanced Apple Debugging & Reverse Engineering team thank you for your support this week — and we hope you enjoy the book!

The post Advanced Apple Debugging & Reverse Engineering Wrap-Up — And Last Day for Discount! appeared first on Ray Wenderlich.

Video Tutorial: Advanced Swift 3 Part 11: ARC with Objects


Eureka Tutorial – Start Building Easy iOS Forms

$
0
0

Many apps let the user enter information via a form interface. Forms can vary in complexity, from simple username and password screens, to more involved interfaces like those for a contact book or calendar.

Eureka is a powerful library that allows developers to rapidly create form interfaces for user input.

This Eureka tutorial will teach you how to use Eureka’s essential building blocks by crafting the interface of a simple to-do app called EurekaToDo. You’ll see how Eureka makes it easy to set up various commonly-used user interface elements such as date pickers, text fields and segmented controls with no boilerplate UIKit code!

In addition:

  • Eureka’s components are very flexible and extensible out-of-the-box and cover the majority of use cases. Eureka makes it easy to implement your custom components if your needs get more specific. Examples of community-generated plugins include a GooglePlacesRow and an ImageRow, which you’ll get to use in this Eureka tutorial.
  • Eureka is a well-documented library with plenty of helpful tips and examples available through its official Github portal.

Getting Started

Download the starter project for EurekaToDo, the to-do list app you’ll be working with for this Eureka tutorial.

In addition to basic view controller transitions, the starter project includes the app’s model and view model layers. Open EurekaToDo.xcworkspace and take a few minutes to browse the project. Here’s a quick overview of important classes:

  • ToDoListViewController: Manages the list of to-do items presented to the user.
  • ToDoListViewModel: The presentation logic for ToDoListViewController.
  • EditToDoItemViewController: Enables the user to add and edit to-do items — it currently doesn’t do much. All the work for this Eureka tutorial will be in this file.
  • EditToDoItemViewModel: The presentation logic supporting EditToDoItemViewController.

You’ll notice the project doesn’t use a storyboard. While Eureka can leverage nib files for custom views, you’ll be amazed by how easy it is to programmatically create and customize common controls.

Note: For this Eureka tutorial, you will be passing values to and from a view model and not the model directly. Although Eureka does not require the use of the Model-View-ViewModel (MVVM) paradigm, MVVM encourages a cleaner, more testable app architecture. For this Eureka tutorial, the view model may be thought of as directly substituting for the app’s model. See the Further Reading section for more on this topic.

Build and run the application. You’ll see a to-do list pre-populated with a single item. Tapping the item takes you to a blank screen (controlled by EditToDoItemViewController) with Back and Save navigation items. Tap the Back button in the top left to return to the to-do list.

Eureka Tutorial

The edit screen currently leaves a lot to be desired. You probably recall EditToDoItemViewController didn’t have much in it. This is where you come in! By the time you’re done, the final project’s interface will look like the picture below:

Eureka Tutorial

Adding Eureka to our View Controller

Open EditToDoItemViewController.swift and replace the current import and class declaration with the following:

import Eureka
import UIKit

class EditToDoItemViewController: FormViewController {

Note: You may need to build the project if the Cocoapod module is not immediately visible to your project.

You’ve imported the Eureka framework and changed the superclass to be FormViewController.

FormViewController is a UIViewController subclass provided with Eureka. It includes a form property, which is an instance of Eureka’s Form class. The Form class is an abstraction of the UITableView object into which you’ll be adding various user interface elements.

A Form instance may contain one or more Section objects. Each section, in turn, may contain one or more Row objects. As you may have guessed from their names, these properties correspond to the sections and rows of the UITableView. Eureka’s Form, Section and Row abstractions provide some very powerful and flexible functionality.

Adding a Section and a Row

In order to add rows to a form, you will first need a Section object to contain them.

You’ll use Eureka’s custom +++ operator to add a Section to the form, and the <<< operator to add rows to a section. Add the following to viewDidLoad(), just beneath the call to super:

//1
form
  +++ Section()	//2
  <<< TextRow() { // 3
    $0.title = "Description" //4
    $0.placeholder = "e.g. Pick up my laundry"
    $0.value = viewModel.title //5
    $0.onChange { [unowned self] row in //6
      self.viewModel.title = row.value
    }
}

Here's a look at what this code does:

  1. Acts on the form object provided by FormViewControler.
  2. Instantiates and adds a Section to the form using Eureka's +++ operator.
  3. Adds a TextRow to the section. As you'd expect, this is a row that will contain some text. The initializer accepts a closure used to customize the row's appearance and events.
  4. Adds a title and placeholder text to the textfield. The title is a left-justified label and the placeholder appears on the right until a value is added.
  5. This sets the initial value of the row to show the to-do item's title.
  6. Eureka's Row superclass comes with a host of callbacks that correspond to various interaction and view lifecycle events. The onChange(_ :) closure is triggered when the row's value property changes. When a change happens, this updates the viewModel's title property to the row's current value.

Build and run the application. When you tap the lone to-do item in the list, the EditToDoItemViewController screen should now look like the picture below. On the edit screen, tap the item, update the text and then Save. The model object updates with your form input!

Eureka Tutorial

In only 10 lines of code, you displayed a model-driven textfield in a tableview.

Now that you have an idea of how Eureka works, time to add some other elements!

Setting the Due Date with a Date Picker

Every to-do list needs to have due dates. Fortunately, Eureka has a row type that displays a date picker when tapped. Add the following to the bottom of viewDidLoad():

+++ Section()
  <<< DateTimeRow() {
    $0.dateFormatter = type(of: self).dateFormatter //1
    $0.title = "Due date" //2
    $0.value = viewModel.dueDate //3
    $0.minimumDate = Date() //4
    $0.onChange { [unowned self] row in //5
      if let date = row.value {
        self.viewModel.dueDate = date
      }
    }
  }

You've added another Section, this time with a DateTimeRow to display the picker. Here's a deeper look at how it's configured:

  1. To format the presentation of the date, set the row's dateFormatter to the static dateFormatter
  2. provided in the starter project.

  3. Most Eureka Row subclasses allow you to set their title property to make the purpose of the row clear to the user.
  4. When the row is initially configured, set its value to the view model's due date.
  5. Use today's date as the minimum date that can be accepted as user input.
  6. Set the newly-selected date to the view model when onChange is triggered.

Build and run the project to confirm the new row is in its own section right below the item title. Tap the row, and a date picker will appear at the bottom of the screen. Note that you can't select a date prior to the present day.

Eureka Tutorial

Selecting the Repeat Frequency

Any worthwhile to-do item interface should let the user specify whether a task is recurring, and at what interval. You will make use of Eureka's PushRow class for this. PushRow accepts an array of options of a given type. Eureka will then take care of generating the supporting interface and navigation to enable the user to make a selection.

Add a PushRow right below the date picker, in the same section:

<<< PushRow<String>() { //1
          $0.title = "Repeats" //2
          $0.value = viewModel.repeatFrequency //3
          $0.options = viewModel.repeatOptions //4
          $0.onChange { [unowned self] row in //5
          if let value = row.value {
            self.viewModel.repeatFrequency = value
          }
        }
     }

By now, some of the above steps should look a little familiar:

  1. Add a new PushRow to the most-recently instantiated section. PushRow is a generic class, so you need to specify that you're using it with type String in angle brackets.
  2. Again, to make the purpose of this selector clear to the user, set its title to "Repeats".
  3. Initialize the row's value with the view model's repeatFrequency property to show the current selection.
  4. As you might have guessed, the options of a PushRow represent the list of possible values the user can select. Set this to viewModel.repeatOptions, an array of strings that have been declared in the starter project. If you Command+Click repeatOptions, you'll see the repeat options are: never, daily, weekly, monthly and annually.
  5. Whenever the row's value changes, update viewModel with the newly-selected value.

Build and run. You'll see that a new row titled Repeats is added to the form.

Eureka Tutorial

Tapping this row transports you to a view where you can select from the provided options. Upon selection, you're popped back to the root task edit view with your selection reflected.

Eureka Tutorial

Adding a Priority Selector

A user should be able to specify how important an item is. To do that, you'll use a SegmentedRow which embeds a UISegmented​Control into a UITableViewCell.

Below the code you just added for the PushRow, add the following:

+++ Section()
      <<< SegmentedRow<String>() {
        $0.title = "Priority"
        $0.value = viewModel.priority
        $0.options = viewModel.priorityOptions
        $0.onChange { [unowned self] row in
          if let value = row.value {
            self.viewModel.priority = value
          }
        }
      }

The code above adds a SegmentedRow with a String type parameter to the form. By now, the rest of the steps outlined should look familiar. Like the row setup you've seen so far, you're setting the title, value, options and onChange(_:) properties using the viewModel.

Build and run. You now have a fully-functioning segmented control to set the item's priority, where "!", "!!" and "!!!" correspond to low-, medium- and high-importance, respectively.

Eureka Tutorial

Setting a Reminder with an Alert Row

The interface requires a way for the user to select when they will be reminded of an upcoming item, such as "30 minutes before," "1 hour before", or "1 day before". You could use a PushRow, as in the repeat frequency example. However, to explore the variety of Eureka's components, you will use an alert controller instead. And guess what? Eureka has an AlertRow for that!

Add the following just below the SegmentedRow:

<<< AlertRow<String>() {
        $0.title = "Reminder"
        $0.selectorTitle = "Remind me"
        $0.value = viewModel.reminder
        $0.options = viewModel.reminderOptions
        $0.onChange { [unowned self] row in
          if let value = row.value {
            self.viewModel.reminder = value
          }
        }
      }

The setup of this row is identical to the rows you have added until this point. However, you also set the additional selectorTitle property, which is the title of the UIAlertController presenting the list of options.

Note: Eureka can also display alert controllers with the ActionSheet style using ActionSheetRow in a similar fashion.

Build and run. When you tap the row titled Reminder, an alert controller is presented, allowing you to select the desired reminder time. You didn't even have to write any UIAlertController code!

Eureka Tutorial

Validation

Still on the task edit view, tap-to-edit the description text field. Delete all characters until you can see the placeholder text, then hit Save. Your to-do item no longer has a title!

Eureka Tutorial

It would be a good idea to make sure the user cannot leave the description blank. Back in viewDidLoad(), find the code where you added a TextRow. Add the following just before the closing bracket of the TextRow closure (and after the onChange closure):

$0.add(rule: RuleRequired()) //1
$0.validationOptions = .validatesOnChange //2
$0.cellUpdate { (cell, row) in //3
  if !row.isValid {
    cell.titleLabel?.textColor = .red
  }
}
  1. Initialize and add a RuleRequired to the TextRow object. This is one of the validation rules provided with Eureka to handle required input in a form. It indicates that a value must be provided in the field to pass validation.
  2. Set the row's validationOptions to .validatesOnChange, meaning the validation rule will be evaluated as the row's value changes.
  3. If the value of the row is not valid, set the row's title color to red to red to alert the user.

Note: You can also add custom rules to handle use cases more specific to our needs, as described in Eureka's documentation.

To make sure the user can't leave the editing screen with an invalid entry, replace the contents of the saveButtonPressed(_:) method with the following:

if form.validate().isEmpty {
  _ = navigationController?.popViewController(animated: true)
}

Eureka has a validate() method that returns an array of any validation errors from all rows with validation rules. If this array is empty, your form has no errors and you can pop the view controller from the navigation stack.

Build and run, and delete the contents of the Description field again. This time, the field label turns red, and the Save button won't allow you to leave until the issue is resolved.

Eureka Tutorial

Adding More Pizazz with Eureka Plugins

A plugin is a custom Row component just like any of the rows already included with the Eureka library. You can browse the plugins created by the community at the Eureka Community Portal.

Let's say you wanted the user to be able to attach an image to a to-do item as a visual aid. Sounds like a job for the ImageRow plugin!

The plugin has already been included in the starter project using the CocoaPods installation instructions found in the plugin readme. To integrate it, start by adding the following import statement to the top of EditToDoItemViewController.swift:

import ImageRow

Note: This plugin requires the addition of the NSCameraUsageDescription and NSPhotoLibraryUsageDescription keys in the project's info.plist file. This has already been done for you in the starter project.

In viewDidLoad(), add a new section with an ImageRow to the form:

  +++ Section("Picture Attachment")
  <<< ImageRow() {
    $0.title = "Attachment"
    $0.sourceTypes = [.PhotoLibrary, .SavedPhotosAlbum, .Camera] //1
    $0.value = viewModel.image //2
    $0.clearAction = .yes(style: .destructive) //3
    $0.onChange { [unowned self] row in //4
      self.viewModel.image = row.value
    }
}

Taking it comment-by-comment:

  1. In the initialization closure, allow the user to select images from their Photo Library, Saved Photos album, or camera if available.
  2. If an image is already attached to this to-do item, use it to initialize the row's value.
  3. Present the "Clear Photo" option with the "destructive" style to indicate that image data may be permanently destroyed when a photo attachment is cleared (when using the camera roll, for example).
  4. As with the previous examples, update the viewModel.image when a new value is set.

Build and run. Tap the row titled Attachment, pick Photo Library from the action sheet, then select an image attachment. The results will be shown in a preview on the Attachment cell.

Eureka Tutorial

Creating a Eureka Plugin

Open EditToDoItemViewModel.swift and check out the categoryOptions array. You can see that the starter project includes possible to-do item categories of Home, Work, Personal, Play and Health. You will create a custom component to allow the user to assign one of these categories to a to-do item.

You will use a Row subclass that provides the default functionality of a PushRow but whose layout is more tailored to your needs. Admittedly, this example is a little contrived, but it will help you understand the essentials of crafting your own custom components.

In Xcode's File Navigator, control click the Views group and create a new file named ToDoCategoryRow.swift. Import Eureka at the top of this file:

import Eureka

Until now, you have been dealing almost exclusively with subclasses of Eureka's Row class. Behind the scenes, the Row class works together with the Cell class. The Cell class is the actual UITableViewCell presented on screen. Both a Row and Cell must be defined for the same value type.

Adding a Custom Cell Subclass

You'll start by creating the cell. At the top of ToDoCategoryRow.swift, insert the following:

//1
class ToDoCategoryCell: PushSelectorCell<String> {

  //2
  lazy var categoryLabel: UILabel = {
    let lbl = UILabel()
    lbl.textAlignment = .center
    return lbl
  }()

  //3
  override func setup() {
    height = { 60 }
    row.title = nil
    super.setup()
    selectionStyle = .none

    //4
    contentView.addSubview(categoryLabel)
    categoryLabel.translatesAutoresizingMaskIntoConstraints = false
    let margin: CGFloat = 10.0
    categoryLabel.heightAnchor.constraint(equalTo: contentView.heightAnchor, constant: -(margin * 2)).isActive = true
    categoryLabel.widthAnchor.constraint(equalTo: contentView.widthAnchor, constant: -(margin * 2)).isActive = true
    categoryLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
    categoryLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
  }

  //5
  override func update() {
    row.title = nil
    accessoryType = .disclosureIndicator
    editingAccessoryType = accessoryType
    selectionStyle = row.isDisabled ? .none : .default
    categoryLabel.text = row.value
  }
}

You've created a custom PushSelectorCell, which derives from UITableViewCell and is managed by PushRow. The cell will display a centered label. Here are some details on how this works:

  1. You'll be displaying string values in this cell, so you provide String as the optional type.
  2. Instantiate the UILabel that will be added to the cell.
  3. setup() is called when the cell is initialized. You'll use it to lay out the cell - starting with setting the height (provided by a closure), title and selectionStyle.
  4. Add the categoryLabel and the constraints necessary to center it within the cell's contentView.
  5. Override the cell's update() method, which is called every time the cell is reloaded. This is where you tell the cell how to present the Row's value. Note that you're not calling the super implementation here, because you don't want to configure the textLabel included with the base class.

Adding a Custom Row Subclass

Below the ToDoCategoryCell class, add ToDoCategoryRow:

final class ToDoCategoryRow: _PushRow<ToDoCategoryCell>, RowType { }

Because Row subclasses are required to be final, PushRow cannot be subclassed directly. Instead, subclass the generic _PushRow provided by Eureka. In the angle brackets, associate the ToDoCategoryRow with the ToDoCategoryCell you just created. Finally, every row must adhere to the RowType protocol.

Now your custom row is all set up and ready to use!

Adding a Dynamic Section Footer

The custom row will be embedded in a "Category" section which will be initially hidden from the user. This section will be unhidden when the user taps a custom table view footer. Open EditToDoItemViewController.swift, and right below the declaration of the dateFormatter constant, add the following:

let categorySectionTag: String = "add category section"
let categoryRowTag: String = "add category row"

The tag property is used by the Form to obtain references to a specific Eureka Row or Section. You'll use this constant to tag and later retrieve the section and row used to manage an item's category.

Next, add the following lines at the end of viewDidLoad():

  //1
  +++ Section("Category") {
    $0.tag = categorySectionTag
  //2
    $0.hidden = (self.viewModel.category != nil) ? false : true
  }
  //3
  <<< ToDoCategoryRow() { [unowned self] row in
    row.tag = self.categoryRowTag
    //4
    row.value = self.viewModel.category
    //5
    row.options = self.viewModel.categoryOptions
    //6
    row.onChange { [unowned self] row in
      self.viewModel.category = row.value
    }
}

This adds a new section that includes your custom ToDoCategoryRow, which is initially hidden. Here are some details:

  1. Add a section to the form, assigning the categorySectionTag constant.
  2. Set the section's hidden property to true if the category property on the view model is nil. The plain nil-coalescing operator cannot be used here as the hidden property requires a Boolean literal value instead.
  3. Add an instance of ToDoCategoryRow to the section tagged with categoryRowTag.
  4. Set the row's value to viewModel.category.
  5. Because this row inherits from PushRow, you must set the row's options property to the options you want displayed.
  6. As you've seen in prior examples, use the row's onChange(_:) callback to update the view model's category property whenever the row's value changes.

Near the top of EditToDoItemViewController, right below the categorySectionTag definition, add the following:

lazy var footerTapped: EditToDoTableFooter.TappedClosure = { [weak self] footer in //1

   //2
   guard let form = self?.form,
     let tag = self?.categorySectionTag,
     let section = form.sectionBy(tag: tag) else {
     return
   }

   //3
   footer.removeFromSuperview()

   //4
   section.hidden = false
   section.evaluateHidden()

   //5
   if let rowTag = self?.categoryRowTag,
     let row = form.rowBy(tag: rowTag) as? ToDoCategoryRow {
     //6
     let category = self?.viewModel.categoryOptions[0]
     self?.viewModel.category = category
     row.value = category
     row.cell.update()
   }
}

EditToDoTableFooter is a view class included in the starter that contains a button with the title Add Category. It also includes TappedClosure, a typealias for an action to execute when tapped. The code you added defines a closure of this type that takes a footer, removes it from the view and displays the category section.

Here is a more detailed look:

  1. To avoid retain cycles, pass [weak self] to the closure.
  2. Safely unwrap references to the view controller and its form and categorySectionTag properties. You obtain a reference to the Section instance you defined with the categorySectionTag.
  3. When the footer is tapped, remove it from the view since the user shouldn't be allowed to tap it again.
  4. Unhide the section by setting hidden to false then calling evaluateHidden(). evaluateHidden() updates the form based on the hidden flag.
  5. Safely unwrap the reference to the ToDoCategoryRow we added to the form.
  6. Ensure the view model's category property and the cell's row value property are defaulted to the first item in the array of options. Call the cell's update() method so its label is refreshed to show the row's value.

The Home Stretch

You're almost at the finish line! At the bottom of viewDidLoad(), insert the following:

//1
let footer = EditToDoTableFooter(frame: .zero)
//2
footer.action = footerTapped
//3
if let tableView = tableView, viewModel.category == nil {
  tableView.tableFooterView = footer
  tableView.tableFooterView?.frame = CGRect(x: 0, y: 0, width: tableView.bounds.width, height: 50.0)
}
  1. Declare an instance of EditToDoTableFooter. You pass a zero frame, because the size will be handled by constraints tied to the cell layout.
  2. footer.action is triggered when the footer button is pressed, and this ensures it fires the code you defined in the footerTapped closure.
  3. If the view model's category is nil, set the table view's tableFooterView property to our newly-instantiated footer. Next, set the footer's frame to the desired dimensions.

Build and run the project. Tap the large, white button with the words Add Category at the bottom of the table view. Voila! The button is replaced by the custom PushRow subclass you created.

Tap this row to choose from a selection of "emoji-fied" categories. Eureka!

Eureka Tutorial

Finishing Touches

The app's users should have the ability to add and delete items. Luckily, the starter project has been set up to do this, and all you have have to do is wire it up.

Open ToDoListViewController.swift and uncomment the following lines of code in addButtonPressed(_:):

  // Uncomment these lines
  //1
  let addViewModel = viewModel.addViewModel()
  //2
  let addVC = EditToDoItemViewController(viewModel: addViewModel)
  navigationController?.pushViewController(addVC, animated: true)
  1. addViewModel() instantiates the view model necessary to add a new to-do item.
  2. EditToDoItemViewController is instantiated with the addViewModel just created, then pushed onto the navigation stack.

Build and run. This time tap the + to generate a blank to-do item. Fill in the details, then save it. It’s about time you picked up your laundry!

Eureka Tutorial

If you were being adventurous, you might have noticed that tapping Back instead of Save had the same effect: the item was added. This is because the model is created as soon as you tap +.

Next, you're going to work on deletion for this case as well as to delete older items.

In EditToDoItemViewController, find deleteButtonPressed(_:) and uncomment the following lines:

//1
let alert = UIAlertController(title: "Delete this item?", message: nil, preferredStyle: .alert)
let cancel = UIAlertAction(title: "Cancel", style: .cancel)
let delete = UIAlertAction(title: "Delete", style: .destructive) { [weak self] _ in
  //2
  self?.viewModel.delete()
    _ = self?.navigationController?.popViewController(animated: true)
    }
//3
alert.addAction(delete)
alert.addAction(cancel)
navigationController?.present(alert, animated: true, completion: nil)

The above code will be executed when the Delete button in the navigation bar is pressed.

  1. Create a UIAlertController with a title, cancel and delete actions.
  2. In the completion handler of the delete action, tell the view model to delete the to-do item currently being edited. Then pop the current view controller off the navigation stack.
  3. Add the cancel and delete actions to the alert controller, and present the alert controller on the navigation stack.

Next, delete the following lines of code from the bottom of deleteButtonPressed(_:):

 // Delete this line
 _ = self.navigationController?.popViewController(animated: true)

This is no longer necessary as you're now handling the pop after deleting the model.

And finally, go the initialize() method and find this line of code:

let deleteButton = UIBarButtonItem(title: "Back", style: .plain, target: self, action: .deleteButtonPressed)

Change the title of the bar button item from "Back" to "Delete" so it reads as follows:

let deleteButton = UIBarButtonItem(title: "Delete", style: .plain, target: self, action: .deleteButtonPressed)

Build and run. Whether you're adding a new item or editing an existing one, tapping Save will take you back to the to-do list only if there are no validation errors (i.e., if the item title is not blank). Tapping Delete will remove the item and take you back to the to-do list.

Eureka Tutorial

Where To Go From Here?

The finished project can be downloaded here.

I hope this Eureka tutorial helped you gain a broad understanding of the advantages and possibilities of using Eureka. I encourage you to check out Eureka's own excellent documentation and in-depth tutorials to continue your journey:

You can learn more about the Model-View-ViewModel (MVVM) architecture with the following resources:

Please share any questions or comments in the discussion below!

The post Eureka Tutorial – Start Building Easy iOS Forms appeared first on Ray Wenderlich.

Using Protocol Buffers in Swift

Video Tutorial: Advanced Swift 3 Part 12: ARC with Closures

Video Tutorial: Advanced Swift 3 Part 13: Unsafe Memory Access

Top 10 Most Popular iOS Tutorials on raywenderlich.com

$
0
0

Top 10 Most Popular iOS Tutorials on raywenderlich.com

Have you ever wondered which iOS tutorials are the most popular on our site? That’s something we’ve wondered as well — and now we have the answer for you!

A long time ago, in an internet far far away, raywenderlich.com started as a small iOS tutorial website. In the early years of the site, we focused on writing iOS tutorials in Objective-C, and we published a couple of new articles each week.

Today the site now hosts over 1,500 tutorials with a huge audience (thank you, friends!), and has grown to include a huge range of subjects beyond iOS and Swift, such as Unity, Android, macOS, Apple Game Frameworks, and more.

It’s always really interesting to see what the most-read articles are, so after sifting through piles of data and crunching the numbers with the ninja internet hamsters that run the site, we’re excited to bring to you the 10 most popular iOS tutorials on raywenderlich.com!

10. Creating and Distributing iOS Frameworks

Charles Proxy Tutorial

By Michael Katz [Tutorial Link]

In iOS 8, and Xcode 6, Apple provided a new project template type that allows you to create frameworks which you can use to modularize, reuse, and encapsulate your code.

You can share and reuse the framework between projects, and they’re also great to compartmentalize code or other components you might want to keep handy in order to avoid rewriting code.

In this tutorial you will learn about:

  • Creating a new framework for the rings widget (similar to the Apple Watch UI component).
  • Migrating existing code, and tests, that you may have.
  • Importing the framework back into the app.
  • Packing it up as a portable CocoaPod.

Frameworks are tremendously powerful, and don’t require you to worry about static or dynamic libraries. If you’ve been interested in reusing code between apps, or projects, give this tutorial a try. Frameworks are awesome!

9. iOS Animation Tutorial: Custom View Controller Presentation Transitions

iOS Animation Tutorial: Custom View Controller Presentation Transitions

By Marin Todorov [Tutorial Link]

Gone are the days of apps using standard iOS components, and APIs. In order to stand out, your application really needs to have polish, and great attention to detail.

Enter view controller presentation transitions, where you can present controllers, and screens, in interactive, unique ways compared to the default presentation mechanisms of iOS.

In this tutorial you will learn:

  • How to create your own custom presentation controller animations to replace the default.
  • How custom view controller transitions work.
  • How to implement transition delegates.
  • How to create a transition animator.

8. Getting Started with Core Data Tutorial

Getting Started with Core Data Tutorial

By Pietro Rea [Tutorial Link]

Most modern apps use some sort of data persistence mechanism. While very basic apps can get away with using property list files or user defaults, most applications will need some sort of database to store the user’s information.

If you are developing a new application and need to decide how to persist your data, then Core Data is the way to go!

Don’t think of Core Data as simply a database wrapper; think of it as an object graph and persistence framework. With Core Data, you don’t need to worry about talking to a SQLite database or executing raw SQL commands.

As a developer, you can stay in Swift-land, work with your database objects as first-class citizens and take advantage of multi-threading, migrations and much more with very little setup or maintenance code needed.

In this tutorial, you will learn how to model data and represent objects in Xcode’s model editor, how to set up Core Data, how to add new records into Core Data, how to fetch a set of records form Core Data, and display data using a table view.

7. Background Modes Tutorial: Getting Started

Background Modes Tutorial: Getting Started

By Chris Wagner [Tutorial Link]

Back in 2010, Apple introduced multitasking on iOS 4. The system, however, was not very straightforward. Applications can only multitask, and run in the background, under specific use cases and in specific scenarios.

If you are looking to implement multitasking features in your applications, then this tutorial is for you. In it, you will learn how to play audio in the background, receive and respond to location updates, perform finite-length tasks (tasks that run for a limited amount of time), and perform background fetches to perhaps update data in your app from a server.

For users, these little things can go a long way towards adopting your app. If you are interested in multitasking, and backgrounding features on iOS, then check out Chris’ tutorial to learn how to get started!

6. SpriteKit Swift 3 Tutorial for Beginners

SpriteKit Swift 3 Tutorial for Beginners

By Ray Wenderlich [Tutorial Link]

One of the first ever tutorials, originally written for Cocos2D using Objective-C, this tutorial has been updated to leverage the power of SpriteKit and Swift 3.

Swift is an incredibly powerful, easy to learn language for developing iOS, macOS, watchOS, and tvOS apps (and even applications for the server with Vapor, Kitura, and others). SpriteKit is one of the best ways to make games on iOS. It’s easy to learn, powerful, and is fully-supported by Apple.

If you are interested in getting started with SpriteKit to make games, then check this tutorial out. You will learn how to make a simple 2D game using the SpriteKit framework.

5. NSURLSession Tutorial: Getting Started

NSURLSession Tutorial: Getting Started

By Ken Toh [Tutorial Link]

NSURLSession is the best way for your application needs to make network requests. Whether it’s downloading or uploading data for your latest social app, or updating a remote database via an HTTP request.

Network requests are a core component of almost all applications. Compared to the old NSURLConnection, NSURLSession has full support for multitasking and backgrounding in iOS (a topic covered in item 7 of this list).

In this tutorial you will learn:

  • How to use NSURLSession to build the Half Tunes app.
  • How to download 30-second previews of selected songs.
  • How to support background transfers and let the user pause, resume or cancel in-progress downloads.

4. Firebase Tutorial: Getting Started

Firebase Tutorial: Getting Started

By Attila Hegedüs [Tutorial Link]

Firebase is a powerful mobile-backend-as-a-service that provides several features for your mobile applications.

There are three main features of Firebase you can use, all without writing a single line of server-side code:

  1. Realtime database
  2. User authentication
  3. Hosting

The realtime database feature of Firebase is one of the coolest, most unique features it offers. No longer do your users have to worry about pull-to-refresh components, or buttons. Firebase automatically pulls the latest data from the network, and updates the connected UI components.

In this tutorial, you’ll learn how to build a collaborative grocery list app that leverages the fundamental features of Firebase. In this tutorial you’ll learn about:

  • Saving data to a Firebase database.
  • Syncing data from Firebase in realtime.
  • Authenticating users.
  • Monitoring online users.
  • Enabling offline support.

Firebase is a really cool tool and one that has plenty to offer. Check out this tutorial to learn how it might help you with your projects.

3. Swift Tutorial Part 1: Expressions, Variables & Constants

Swift Tutorial Part 1: Expressions, Variables & Constants

By Matt Galloway [Tutorial Link]

If you want to get started learning Swift 3, want to brush up on existing skills, or want to expand your knowledge of the language, then this tutorial is the best place to start.

Thanks to the power of Playgrounds you can very easily experiment, learn, tinker, and see what your code does. This tutorial series covers the basics of programming with Swift 3, and this first part covers the concepts of:

  • Commenting code.
  • Printing to the console.
  • Basic arithmetic operations.
  • Math functions.
  • Naming data with variables, and constants.

2. Self-Sizing Table View Cells

Self-sizing Table View Cells

By Bradley Johnson [Tutorial Link]

Tables views are a core construct of almost all iOS applications. Chances are if you’ve worked on a table view, you’ve had to deal with calculating the size of your cells in order to adjust to different heights and different data.

While this approach works, and was certainly needed in the early days of iOS app development, a better approach is now available to you.

In this tutorial, you’ll learn how to create and dynamically size table view cells to fit their contents by levering the power of Auto Layout, and automatic row heights in table views..

It’s the moment you’ve been waiting for!

And the most popular iOS tutorial from the past year is…

1. UICollectionView Tutorial: Getting Started

UICollectionView Tutorial: Getting Started

By Bradley Johnson [Tutorial Link]

If a table view tutorial is our number two item, it’s no surprise that a tutorial on collection views takes the number one spot.

If you’ve never used collection views, think of them as table views with super powers. With collection views you can create interfaces that go beyond vertical tables.

Collection views also connect fantastically with custom view controller transitions, and UIKit dynamics.

In this tutorial, you’ll learn about UICollectionView by creating your own grid-based photo browsing application. You will also learn the basics of using collection views, and its layouts.

There really isn’t anything you can’t build without collection views, and as a core component of iOS and UIKit, you’re most definitely going to have endless hours of fun playing around with them.

More Statistical Factoids

That’s quite the list of tutorials!

If you’re a data-head like we are, then you’ll be interested in some other neat factoids about the site that we gathered along the way:

Where Do Our Readers Come From?

Here are the top ten countries where our readers are based:

It’s pretty cool to see visitors from all over! The development community really has no political barriers and speaks all languages. We all love coding and making our ideas come to life, no matter where we come from.

If you don’t see your country in the chart above, leave a shoutout in the comments below and let us know where you’re from!

What OS Are Readers Using?

Here’s how our readers break down by OS platform:

It’s no a surprise to see macOS topping the top of the list, since that’s what most visitors use for their development tasks. It’s great to see so many Windows users. What is it you’re looking at: Blender? Unity? Android? C#? Or is it something else that brings you here? Let us know!

Where to Go From Here?

Ah — a trip down memory lane is always great. Some of the most popular tutorials were a pleasant surprise to us. Readers like you keep us on our toes when planning new content! :]

If there’s one thing we can take away from these numbers, it’s that demand for iOS development content has continued to grow, and the Swift community — and language — grows only stronger with time.

Thank you so much for your continued support! I wonder which articles will rank as the most popular ones for 2017?

What is your favorite “go-to” tutorial on the site, or the one that you most recommend to others? Please join in the discussion below!

The post Top 10 Most Popular iOS Tutorials on raywenderlich.com appeared first on Ray Wenderlich.

Viewing all 4374 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>