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

Unity Feast Game Jam Winners!

$
0
0

Introducing the Unity Feast!

Jamming with the Unity Game Jam

Last week was an incredible week for the Unity team. After working many months of writing and editing, we presented the latest and greatest tutorials from the Unity team.

During the Unity Feast, we released the following tutorials:

  1. First Course: Introduction to Unity
  2. Second Course: Introduction to Unity 2D
  3. Third Course: Introduction to Unity Animation
  4. Fourth Course: Make a VR Game With Unity and Google Cardboard
  5. Fifth Course: Introduction to Unity Particle Systems
  6. Sixth Course: Introduction to Unity UI System

The feast concluded with our first ever game jam whereby the winner walks away with a free Apple TV and a fifty dollar gift card to buy Unity assets.

Keep reading to learn about the Game Jam and the winners of it.

What was the Unity Feast Game Jam?

The Unity Feast Game Jam was a challenge to make a game in Unity, using a theme we provided.

The challenge was to create a 2D or 3D Unity game around the theme of eating. To make things interesting, we provided five different objects. Participants had to include two of the objects in the game.

unity_gamejam_art

We received a total of thirteen entries who had a lot of fun with the theme. Unfortunately, only five can win prizes.

That said, speaking on behalf of the Unity team, I want to thank everyone who submitted games to us. It was really fun to play them as well as chatting with a bunch of you over the Game Jam Slack channel.

To the Winners!

Here are all the winners for the Game Jam. If you don’t see your game listed, we’ll be doing this again, so keep reading tutorials and practicing those skills. We can’t wait to play your next game!

Fifth Place – Boxing Chef by Esperteyu Games

Screen Shot 2015-11-26 at 1.55.02 AM

Description: In this game you play as a chef whose kitchen is being overrun with both food and bugs. Collect the food while boxing off the bugs that fall from the top of the screen in this fun 2D game.

Team Thoughts:

Fun because who hasn’t wanted to punch a bug? – Todd Kerpelman

There is no bigger satisfaction than punching flies with your bare fists and make them fly through the air. Sometimes a bit too difficult, but still fun. – Barbara Reichart

Prize: A license to 2D Homing Missiles, 2D Laser Pack, and 2D Shooter Bullet and Weapon System.

Fourth Place – Eat to Live! by Shanaka Gunasekara

Runner

Description: Play not one, but two characters in this infinite runner game where you are tasked with eating food while jumping over bugs. Lose one character and you will lose the game.

Team Thoughts:

Challenging gameplay, but also very much fun and not too hard, a perfect causal game – Joachim Baur

Prize: A license to Texture Packer and Sprite Illuminator.

Third Place – Orc Hungry by Tyler Wickiser

Screen Shot 2015-11-26 at 1.38.12 AM

Description: Play as an orc in this 2D game where you must eat food while avoiding tractor driving manic farmers and other obstacles in this well put together albeit hard 2D game.

Team Thoughts:

Cool graphics and interesting levels. – Sean Duffy

Prize: Will receive a license to Shader Forge.

Second Place – Feed the Cat by Quentin Ivanhoe

Screen Shot 2015-11-26 at 1.19.59 AM

Description: Hungry cats must be fed! In this game, food floats towards a hungry cat but bugs try to fly down and steal the food. Shoot down the bugs with your cannon in this fun 2D game.

Team Thoughts:

Your cat needs to be fed. But flies will steal its food. Shoot them with cannon balls. This is not at all an over reaction. No! I really like the over the top theme. – Barbara Reichart

I like it! It’s a pretty challenging game. I like the way you have to shoot the flies to save the food. I love the old movie style dialogue and the “flickering vignette” effect! – Eric Van de Kerckhove

Prize: Will receive a license to UFPS : Ultimate FPS

And the first place winner of the Unity Game Jame …

First Place – Munchies by Daniel Mather

Screen Shot 2015-11-26 at 1.29.35 AM

Description: Eating is your only job in this fun creative game. In it, you play a green little blob that must eat. You can only eat items smaller than you. With each bite you grow larger and larger, but beware your larger enemies who want to eat you!

Team Thoughts:

Really fun, well put together! – Brian Moakley

Eat or be eaten. Eat everything to grow and munch your enemies. Fun to play and even has multiple levels. – Barbara Reichart

Fun! Reminded me of Feeding Frenzy, which is a game I sorely miss. – Todd Kerpelman

Nice level progression difficulty, and a good take on the ‘agar.io’ game style where you must consume items smaller than you. Quite fun to play. – Sean Duffy

I especially liked the “strategic” element introduced by the player’s growth – Joachim Baur

Great game, I like the “you can only eat what’s smaller” mechanic. I was quite amused when I found out you could eat the enemies too! – Eric Van de Kerckhove

Prize: Will receive an Apple TV and a fifty dollar gift certificate.

Huge congrats to the winners! We will be in touch soon to arrange delivery of your prizes.

Once again, a huge thanks to everyone who donated prizes for the Unity Feast! These are all amazing resources for Unity developers that we hand-picked and highly recommend.

And That’s a Wrap!

And that concludes the Unity Feast, we hope you all enjoyed it and got fat and happy along the way!

Congrats to all of the prize winners, and a huge thank you to the companies and developers have donated prizes.

The post Unity Feast Game Jam Winners! appeared first on Ray Wenderlich.


Video Tutorial: In-App Purchase Part 3: Receipts

Video Tutorial: In-App Purchase Part 4: Conclusion

Introducing the OS X Feast!

$
0
0

OS X Feast

Just when you thought Thanksgiving was over, we have another feast at raywenderlich.com!

Recently, we started a new team at raywenderlich.com called the OS X Team, focusing on making high quality OS X Tutorials.

The team has been hard at work over the last few months, and this week we are happy to release the first batch of their tutorials in a special celebration: the OS X Feast!

We’ll be releasing six OS X tutorials over the course of this week. This is a great way to get up-to-speed with OS X development – even if you are a complete beginner.

Here’s a peek at the menu for the upcoming week:

  1. First Course: Mac OS X Development Tutorial for Beginners [Part 1, Part 1, Part 3]
  2. Second Course: Windows and Window Controllers in OS X
  3. Third Course: OS X View Controllers
  4. Fourth Course: Tableviews on OS X

Let’s take a closer look at what’s inside!

First Course: Mac OS X Development Tutorial for Beginners

The first course is a 3-part tutorial series on Mac OS X Development for complete beginners. Previous iOS experience isn’t required (but is helpful)!

You’ll start with an introduction to Xcode, move into an overview of how OS X apps work, and finally create your first OS X app – a fun Magic 8-ball app. Through the process, you’ll learn about the most important concepts of OS X development and you’ll whet your appetite for what’s to come! :]

64_final_bar

Second Course: Windows and Window Controllers in OS X

OS X apps are built around the concept of windows, and in the second course of the feast you’ll be getting up to speed with exactly what they are, what they can do, and how to control them.

While you’re munching away you’ll be building a simple word-processor, demonstrating the power of window controllers on OS X.

WordCountFinal

Third Course: OS X View Controllers

Another course and another app!

This time you’ll build a bookstore app, while discovering the power of view controllers on OS X.

Although view controllers are a relatively recent addition to the OS X platform, they play an incredibly important role. In this tutorial, you’ll quickly get up to speed as you gorge yourself on the third course of the feast.

bottomlabel-constraints

Fourth Course: Tableviews on OS X

The fourth course of the OS X feast features tableviews — one of the most widely used controls.

Table views are great for displaying large quantities of data, and have undergone various improvements over recent releases of OS X. You’ll learn all about them as you build your very own version of Finder!

tableview-dropcell

Where To Go From Here?

If you’ve been wanting to learn OS X development but haven’t gotten around to it, this is a great chance – all of these tutorials are fresh off the presses and a great way to get started.

The OS X team and I hope you enjoy this free set of tutorials, and we’ll be releasing many more in the months to come! :]

The post Introducing the OS X Feast! appeared first on Ray Wenderlich.

Mac OS X Development Tutorial for Beginners Part 1: Intro to Xcode

$
0
0

250x250Want to learn how to develop your own apps for Mac OS X?

Good news – Apple makes developing for OS X incredibly easy – and in this tutorial series we’ll show you how. You’ll learn how to create your first app for OS X – even if you’re a complete beginner.

  1. In this first part you’ll first learn about how to obtain the tools you need to develop for OS X. Then, using an app you’ve downloaded as an example, you’ll take a tour of Xcode, discovering how to run an app, edit code, design the UI and debug it.
  2. In part two, you’ll take a step back from Xcode to learn about the components that make up an OS X app. From how an app starts, through how the UI is constructed all the way to handling user interaction.
  3. You’ll get your hands dirty in the final part – building your first ever OS X app. Starting from nothing, you’ll soon have a simple app up and running on your mac!

So what are you waiting for? The world of desktop apps awaits!

Note: Here’s some guidance of where to begin with this series:

  • If you are new to Swift, this series assumes Swift knowledge, so first check out our Swift tutorials to get a great introduction.
  • If you already have iOS experience, this first part of the series will be review. Take a quick look through the topics to make sure and then skip straight ahead to the next part of the series.
  • Otherwise, keep reading – this series is for complete beginners – no experience of developing for iOS or OS X is required!

Prerequisites

To become an OS X developer, you will need a few things:

  • Mac running OS X. The OS X operating system only runs on Apple computers, so you need a Mac both to develop and run OS X apps. If you’re wondering which Mac to buy, we recommend a Mac Mini with extra memory and a solid state or Fusion drive; it’s the best balance between cost and power.
  • An AppleID. In order to download the tools from the App Store, you’ll need an AppleID.
  • Xcode. This is the IDE and toolchain used to create OS X apps. You’ll learn how to install this in the next section.

Once you’ve built your app, and you want to upload it to the App Store to be distributed, you’ll also need to pay for an Apple developer account. But this is not a requirement until you are ready to send your app out to the world.

Obtaining Tools

Unlike some other platforms, developing for OS X requires the installation of one tool – known as Xcode. Xcode is an IDE that includes everything you need to develop iOS, watchOS and OS X apps.

If you don’t have Xcode already, click on the Apple icon in the upper left of your menu and select App Store to open the Mac App Store.

AppStore2

Search for Xcode and download it:

xcode_mas

Once it has downloaded and installed, open Xcode from your Applications folder. The first time you open Xcode it’ll ask to install some additional components. Go ahead and let it, entering your password if required.

You’ll then be presented with the Xcode welcome screen:

xocde_welcome

Congratulations, you’ve successfully installed Xcode! Read on to learn all about what it can do.

Beta versions of Xcode

Before moving on to describing the power of Xcode, it’s worth taking a few minutes learning about beta versions of Xcode.

When Apple releases new updates to Xcode (often to support new features in OS X, iOS and watchOS) they go through an agressive cycle of beta releases. These releases include the new features, but consequently many bugs. If you are interested in developing an app which leverages these new features, you’ll need to download the latest beta from Apple.

This tutorial requires Xcode 7, since the sample project used in this tutorial has been updated to the Swift 2.0 programming language. There are two cases:

  • If the App Store version of Xcode is Xcode 7 at the time of reading this tutorial, you are all set!
  • If the App Store version of Xcode is Xcode 6 at the time of reading this tutorial, you’ll need to install a beta version of Xcode 7 – keep reading to learn how.

To get the latest beta version of Xcode, visit developer.apple.com, click on Resources, Xcode, and then Download. Follow the link to download the latest version of Xcode beta there.

Note you can install a beta version of Xcode alongside the stable version, so there’s no problem with continuing work on projects that aren’t ready for upgrade.

XcodeBeta

The download is a DMG, so you can install by dragging the Xcode app across into Applications in the usual way. You’ll then have two versions of Xcode in your applications folder:

2Xcode

Run Xcode-beta and then you’re ready to continue on!

Hello World!

Xcode is an Integrated Development Environment (IDE) which means that it is a collection of all the tools you need, from source code editing, compilation through to debugging and UI design.

When you open Xcode it allows you to create a new project, or open an existing one. You can also open an existing project by double clicking on an Xcode project or workspace in Finder:

open_finder

Creating a new app

For most of this tutorial you’ll tour Xcode via a sample app, but first things first – you can’t start learning about a new platform without first creating a “Hello World” app!

To do this, select Create a new Xcode project from the Xcode welcome screen:

xocde_welcome

The template chooser allows you to decide how Xcode will configure your new project. In the OS X \ Application section you can see the three different core OS X app types:

new_project

The three different app types are as follows:

  • Cocoa Application: An OS X desktop app – with a window-based UI. Cocoa is the name of the framework upon which all OS X applications are built.
  • Game: Games built using Apple’s SpriteKit or SceneKit frameworks.
  • Command Line Tool: A utility that runs in a shell, and has a text-based UI.

Select Cocoa Application, and click Next. On the screen that follows, set the Product Name to HelloWorld, check the language is set to Swift and that Use Storyboards is checked:

new_project

Click Next, and choose a location on disk to save your project.

This creates a new, empty project ready for you to craft into your amazing app. The first thing you’ll want to do is build and run it to check that it’s all working.

Running your app

Whether you’ve opened an existing app or created a new one, the most important thing you’ll want to do is to build and run it.

This involves compiling all of the code you’ve written into machine code, bundling up the resources required by the app and then executing it. This process is complex, but luckily Xcode has your back. To build and run your project simply press the play button on the toolbar:

You can also build and run your app with the ⌘R keyboard shortcut.

bar_empty

Note: The first time you ever build and run an app in Xcode, you might well be asked whether you want to Enable Developer Mode on this Mac?. You’re safe to select Enable, at which point you may have to enter your password. Developer mode allows Xcode to attach a debugger to running processes – which will be extremely useful when building your application!

Your HelloWorld app is currently looking a bit empty – and doesn’t even say hello! You’re going to fix that now.

Adding Text

You’re going to update the user interface (UI) of your app to make it into a true “Hello World” app, and to do this you’re going to use a tool called Interface Builder (IB). You’ll learn much more about Interface Builder later in this tutorial – for now, you just need to know enough to add some text to the layout.

Find the Main.storyboard file in the Project Navigator, and click on it:

open_storyboard

This opens the storyboard file in Interface Builder – you can see an outline of your entire app:

hello_world_storyboard

The lower component (entitled “View Controller”) represents the visual appearance of your app. You’re going to add a text label to this to create your “Hello World” app.

Find the Object Library in the lower right part of the Xcode window. Type label into the search box and locate the Label entry:

object_library

Drag a label from the Object Library onto the empty View Controller scene canvas:

drag_label

A label represents a static piece of text – with no user interaction – perfect for your Hello World app. You don’t want it to say “label” though – you’re going to update that next.

To configure the label, select it and then open the Attributes Inspector (the 4th tab) on the right hand side of the Xcode window. Set the title to “Hello OS X!”, and update the font to be size 40:

label_config

You may see that the label is no longer sized correctly – next you’ll fix that and set it to the correct position.

You position UI elements in OS X using a system called Auto Layout – which allows you to specify positions and sizes of UI elements in terms of their relationships. You want to put your “Hello OS X!” label in the center of the window – so you’re going to add constraints to achieve this.

Select the label once again, and click the Align button in the bottom bar (the second from the left). Check both the Horizontally in Container and the Vertically in Container boxes, and ensure that they are both set to 0. Select Items of New Constraints in the Update Frames selection box before finally clicking the Add 2 Constraints button:

constraints

This will update the storyboard to position and size your label correctly.

Build and run your app (either by clicking the play button, or using the ⌘R keyboard shortcut) to see your “Hello World!” Mac OS X app:

hello_osx

Introducing HubEvent

You’ll continue learning how to make projects from scratch and code OS X apps in later parts of this series, but for the rest of this tutorial you’ll focus on learning more about Xcode itself.

To help with that, I’ve created a sample project for you called HubEvent that you’ll work with for the rest of this tutorial. This way you can get a tour of Xcode with a real-world project.

Download the HubEvent starter project, unzip it and double click on HubEvent\HubEvent.xcodeproj in Finder to open it in Xcode.

Build and run HubEvent sample project and you’ll see it compile and then launch:

hubevent

HubEvent uses the public GitHub API to pull down all the events for a user, and displays a summary of them in a table. As you select each row of the table, the raw JSON associated with that event is displayed in the panel below.

Xcode Core Functionality

HubEvent is a fairly simple app, but is complex enough to demonstrate the core functionality of Xcode. The remainder of this tutorial will cover the following:

  • Code Editor. All OS X apps have a code component, and HubEvent is no different. The code in HubEvent is responsible for downloading the data from the GitHub API, and wiring it up to the user interface.
  • Interface Builder. You’ve already used Interface Builder when you build your “Hello World!” app. You’ll learn more about how this powerful tool allows you to build up the split-window UI used in HubEvent.
  • Asset Catalog. All image assets are stored inside asset catalogs – you’ll discover how to replace the standard app icon with something more interesting.
  • Debugging. Everybody makes mistakes when writing code and building apps and Xocde’s debugger makes identifying and fixing bugs a whole lot easier.
  • Documentation. OS X apps are build on top of some extremely advanced system frameworks, and nobody can remember exactly how to use each and every one of them. Luckily Apple creates high-quality documentation and has integrated it with Xcode to make it easy to find answers to your questions.

Code Editor

Apps are built primarily from code, written in the Swift programming language. You can also use Objective-C to write apps for OS X, but Apple introduced Swift in 2014, and was very clear that it is the langauge of the future. HubEvent is written in Swift.

One of the views available in Xcode is the Code Editor, which is activated whenever you open a source code file. To see it, select WindowController.swift from the Controllers group in the Project navigator.

Note: You might need to show the Navigator pane on the left hand side using the buttons in the toolbar, and choose the Project navigator within the navigator pane. The buttons are shown in the above screenshot.

In the main section of the Xcode window, you can now see the source code associated with the Window Controller. Find the following line:

// The shared data model
let sharedDataStore = DataStore(username: "rwenderlich", type: .Network)

This line is selecting the source of the GitHub event data – here choosing Ray’s username (rwenderlich).

Try changing rwenderlich to a different GitHub username – for example sammyd. Then, build and run your app as you did before. You’ll see the new user’s events listed in the app:

hubevent_sammyd

Well done! You’ve changed your first code in an OS X app!

The code editor includes many powerful features to assist you as your write code, including autocompletion and QuickLook documentation.

Interface Builder

Although it is possible to build the user interface of an OS X app entirely in code, since UI is inherently visual, proceeding in this manner isn’t very intuitive.

Xcode includes a tool called Interface Builder (IB), which is a fully-featured visual design tool that allows you to build your UI from reusable components.

The files which make up these visual interfaces are called Storyboards – a name inspired by the film industry. In the same way that a storyboard is used to depict scenes in a film, and the progression through it, a storyboard in an app depicts the scenes and the flow between them.

To see a storyboard in Interface Builder, select Main.storyboard in the Project navigator:

This storyboard includes the layout for the entire app. You can see how the table at the top of the app is split out as a separate entity from the JSON viewer at the bottom.

To get a really quick feel for interface builder, you’re going to change the color of the icon in the left hand column.

Although being zoomed out allows you to get a good view of the entire storyboard, you can’t edit a zoomed out storyboard. Zoom in to the EventList VC scene using ⌘+. This is the scene that contains the table:

eventlist

Use the button in the bottom left corner to Show Document Outline. This is a panel along the left hand side of Interface Builder which shows you the hierarchy of components that make up the current scene.

select_icon

If you click on the purple symbol in the table view, you’ll highlight the corresponding Table Cell View row in the Document Outline. Since you want to access the text field inside this cell, click on the again. Now you’ll have the row selected as in the previous image.

Once you’ve selected this text field, you can configure various attributes associated with it, which determine its appearance.

If the Utilities panel is not visible down the right hand side of Xcode, use the button in the toolbar to show it:

utilities_button

This panel can display many different inspectors, but the one you want now is the Atrributes Inspector. Select it now and you’ll find the Text Color attribute:

attributes_inspector

Tap on the purple color bar, and you’ll see a colors panel. Use this to select a different color – e.g. yellow:

color_panel

Now you can build and run HubEvent again to see the effect your change has had:

hubevent_yellow

Asset Catalog

In addition to code and user interfaces, your app will also need some assets such as artwork. Due to the different screen types (e.g. retina and non-retina), you often need to provide multiple versions of each asset. To simplify this process, Xcode uses Asset Libraries to store and organize the assets that accompany the app.

HubEvent already has the default asset library, called Images.xcassets. Select it in the Project navigator to reveal its content:

asset_library

When you create a new app, the template includes an asset library, with just one entry – the app logo. This is exactly the state of the asset library in HubEvent. You can see the different asset types you can create by right clicking in the left pane of the library:

asset_types

Currently the app icon for HubEvent is the default OS X icon:

original_icon

Since the app icon is provided by the asset catalog, you’re going to replace it with something more appropriate. Click on the AppIcon asset:

appicon

When you provide an app icon for an app, you have to provide it in many different sizes and densities for use around the system. As a demonstration, you’re going to add one of these sizes to see the app icon change.

Use Finder to locate rw_icon.png in the unzipped directory you downloaded. Then drag this from Finder into the Mac 512pt 2x cell in the AppIcon asset:

appicon_updated

Note: Providing a single image in this manner is not generally appropriate. In a real application you should provide all ten versions of the icon.

Now build and run the app again and you’ll see the updated icon in the dock:

new_icon

Debugging

Nobody is capable of writing code that works perfectly every time, and therefore you’re likely to spend time trying to fix problems in your code. You’ll soon find that it’d be really helpful to be able to stop your app at a particular line of code and investigate the values of variables. This is precisely the functionality provided by a debugger.

Once again, Xcode is here to help. It has an integrated debugger that makes runtime investigation of your code really easy. To demonstrate some of its functionality, you’re going to use it.

Open Value Transformers\CodeStringFormattingTransformer.swift by selecting it in the Project navigator.

Find the following line in the code:

return NSAttributedString(string: unescaped, attributes: attributes)

Click in the gutter to the left of this line to insert a breakpoint:

breakpoint

A breakpoint marks the line in your code at which point execution will stop. Your app will pause at this point to allow you to investigate the state.

Build and run the app. You’ll see the app start, before Xcode comes back to the foreground. You’ll see the line you added the breakpoint to highlighted:

highlighted_line

This means that your app has started running, and then reached this line of code. It has paused here to allow you to investigate.

The bottom pane in Xcode shows you the state of the variables at the current point of execution, including their variables.

debug_pane

This particular method is removing escaped characters from the JSON downloaded from the GitHub API. You can see the input string s and the resultant string unescaped.

You can progress to the next line of execution with the stepover button:

stepover

Or to continue the program execution, use the continue button:

continue

Note that continuing will then run the program until it comes across another breakpoint.

To remove a breakpoint, you can drag it out of the gutter until the pointer changes to a x.

Fixing a bug with the debugger

To see how debugging works, you’re going to fix a real-world bug! You’ve had reports that if you change HubEvent to use a disk-based data source instead of network then it ignores your choice – and still queries the network. Your job is to find this bug and fix it.

First, to change the app into disk-mode instead of network-mode, open WindowController.swift, locate the line that creates the sharedDataStore, and update it to match the following:

let sharedDataStore = DataStore(username: "rwenderlich", type: .Disk)

Now run up the app, and confirm that the data is indeed still being pulled from the network (the on-disk data was acquired in April 2015).

To debug this problem, you’re going to add a break point at the point the data store is created to find out what’s happening. Open DataStore.swift, and add a breakpoint on the line that contains super.init().

Run the app and wait for it to pause at the break point. Use the debug browser to locate the dataProvider property within self:

debugging_dataprovider

Notice that the type next to it is GitHubData.GitHubDataNetworkProvider. This doesn’t sound right – why would it be using an object called network when it’s reading off disk.

Now take a look further up the file, and you’ll find where this dataProvider object is created:

switch type {
case .Network:
  dataProvider = GitHubDataNetworkProvider()
case .Disk:
  dataProvider = GitHubDataNetworkProvider()
}

This is a switch statement that decides what kind of provider it needs to create – why does it create a GitHubDataNetworkProvider for the .Disk type? This is the bug!

Replace the .Disk case to match the following:

case .Disk:
  dataProvider = GitHubDataFileProvider()

Now re-run the app, and it’ll pause on the same breakpoint. Check the type of the dataProvider property once again:

debugging_fixed

The type now looks correct – use the Continue program execution button to run the app:

hubevent_disk

Yay! The app is now reading from the disk-based store, rather than over the network. Well done – you’ve fixed your first OS X bug!

Documentation

Xcode has a couple of integrated ways to get access to documentation for system frameworks. The first is the ability to show a tooltip containing the most salient information about a class or method.

As an example, open Controllers\WindowController.swift and inside the transformedValueClass() method, Option-Click on NSString:

tooltip

The second method of accessing documentation shows you the full documentation in a dedicated browser. To access this, either click on the Reference link at the bottom of the tooltip, or click the Window \ Documentation and Reference menu. Then search for NSString to pull up the documentation:

doc_browser

Fixing a bug with documentation

Let’s see how you can use Xcode’s documentation to fix another bug.

When HubEvent first loads, you’ll notice that the divider between the table and the JSON view is positioned very high:

divider_initial

If you try to drag the divider down, you’ll see that it snaps to the middle of the window, and is then immovable. This is the behavior you’d like, but the divider should be in the correct position when the app starts.

You can achieve this by adding a single line to the viewWillAppear() method inside the SplitViewController.swift file. Use the documentation browser to search for NSSplitView, and read about the setPosition(_:, ofDividerAtIndex:) method. Then use this method on the splitView property in the aforementioned method, passing in view.bounds.height / 2.0 for the position.

Solution Inside: Divider Position SelectShow>

 

Where To Go From Here?

Here’s the finished project for this Max OS X development tutorial.

At this point, you have a birds-eye overview of the most important aspects of Xcode. In the next article you’ll learn about the anatomy of an app, and finally move on to creating your first OS X app.

Apple has a huge amount of documentation for OS X – all available on the Developer Portal.

If you have any questions or comments then please join in below or on the forums.

The post Mac OS X Development Tutorial for Beginners Part 1: Intro to Xcode appeared first on Ray Wenderlich.

Mac OS X Development Tutorial for Beginners Part 2: OS X App Anatomy

$
0
0

250x250

Welcome back to our 3-part Mac OS X Development tutorial for beginner series!

  1. In part 1 you first learned how to obtain the tools you need to develop for OS X. Then, using an app you downloaded as an example, you took a tour of Xcode, discovering how to run an app, edit code, design the UI and debug it.
  2. In this second part, you’ll take a step back from Xcode to learn about the components that make up an OS X app. From how an app starts, through how the UI is constructed all the way to handling user interaction.
  3. You’ll get your hands dirty in the final part – building your first ever OS X app. Starting from nothing, you’ll soon have a simple app up and running on your mac!

This article is aimed at developers who have either completed part one of the series, or have experience with Xcode. It assumes little or no knowledge of OS X apps, and if you’re already familiar with the architecture of OS X apps, you might like to skim through before skipping right on to the final part.

By the end of this article you’ll have a good grounding in how the different parts of an OS X app fit together, although not necessarily a wide-ranging understanding of how each of them works.

Note: This part of the series is just background information that you need to know about how OS X apps work; there is no coding involved.

Just sit back, relax, and learn – you’ll get back to coding and make your first OS X app in the next and final part of the series!

How Does an OS X App Start?

Your journey through an OS X app starts right at the beginning – looking at how an app actually starts.

There are three components that you need to be aware of when considering the OS X app start process:

  • App Delegate: The entry point for code. The App Delegate provides methods associated with both the lifecycle of the app, and its interaction with the operating system. This is your first opportunity to run code, and provides you with notifications from OS X, such as Handoff requests, command line arguments and push notifications.
  • Storyboard: Storyboards have a designated “entry point”, and this allows the system to construct the UI at app launch. The entrypoint looks like an arrow on the left hand side of a scene:
    storyboard_entry
    This denotes which of the scenes in the storyboard will form the initial UI of your app.
  • Info.plist: You can have multiple storyboards within your app, so how does OS X know which one it should use as the initial UI? This information (and a load of other useful things) is stored inside the Info.plist file. You can see the relevant entry below:info_plist

    This file contains lots of useful app configuration options, many of which are exposed through the target configuration screen in Xcode. The image below shows the same storyboard setting in a more user-friendly location:

    project_config

Starting an app is slightly more complicated than this, but these three places explain where you can interact and configure your app’s startup. Now that you’ve got your app up and running it’s time to take a look at a very important aspect – its User Interface.

User interface

You’re already aware of the fact that the UI can be provided by a storyboard, but what does this actually mean? In this section you’ll cover the different UI components – what they represent and how they fit together.

app_components

Window

The UI for your app will be contained within one or more window objects. These represent an area of the screen for which your app is responsible for providing the UI. The operating system runs a window manager that handles the moving and resizing of these windows, updating your app as the user makes these changes.

In addition to representing the visualization of your app, the window object also handles passing user events triggered by user interaction with the mouse and keyboard into your app.

Although you can interact directly with a window object, often they’re managed by window controllers – especially when used in conjunction with storyboards.

A window controller is responsible for the loading of the window itself, and allows you to hook into different events throughout the lifecycle of the window.

A storyboard would contain at least one window controller, which is represented as follows:

window_controller

Window controllers are represented by the NSWindowController class, and as you configure your different windows, you would normally create different subclasses to manage their individual behavior.

Views

The window specifies the area of the screen that your app is responsible for drawing on, but not what to draw. This is one of the primary responsibilities of the view – providing you with functionality to draw on the screen.

Views are rectangular in shape, and are represented by the NSView class. Views exist within a hierarchy – i.e. any view can contain zero or more subviews – allowing you to construct a complex layout using much simpler, reusable view components.

View Controllers

In the same way that windows are managed by a window controller in storyboards, views are managed by a view controller class. This links the view hierarchy in with the the model layer, either by manipulating properties directly, or through Cocoa bindings.

In a typical application, a view controller is a reusable component that, when provided a model object of a particular type, would update all of its constituent views to represent the values of its associated model object.

For example, in the previous tutorial you poked around the HubEvent app.

view_controllers

In the above screenshot, you can see that it is made up of two major view controllers – one managing the table view on the top, and the other the detail text view. When you select a row in the table view, it sets the model object on the lower detail view controller, which then updates the text view to display the correct JSON.

View controllers are represented by NSViewController, which provides a full range of lifecycle events – allowing you to perform custom actions at different times. For example you can fire animation as the view is about to appear on the screen with viewWillAppear(), or populate relevant views with data once the view hierarchy has correctly loaded with viewDidLoad().

Your app is likely to be formed from a selection of custom subclasses of NSViewController, each responsible for a different section of a window. They’re an incredibly important aspect of an app – forming the link that allows you to display the underlying data to the user.

View components

You’ve discovered that views are used to draw on the screen – but how is that actually achieved? At the lowest level you can create a custom subclass of NSView and override the drawRect() method to manually draw the content of your view.

This is extremely powerful – allowing you to create completely custom views, but would be arduous if you had to do this to draw some text on the screen!

Luckily, you don’t have to. AppKit contains a large selection of commonly used NSView subclasses that you can use to display content on the screen.

Some of the most useful examples are:

  • Label: Displays static text. Configurable font and appearance
  • Text Field: User-editable text control. Used to collect a string from the user.
    text_field
  • Image View: Draws an image – provided by an NSImage object.
    image_view
  • Push Button: One of the many button types – each of which respond to a user’s mouse click.
    push_button
  • Table View: An example of one of the many view subclasses used for showing not just one data object, but rather a collection of them.
    table_view

These are just a few of the different view subclasses available to you as you build up the user interface of your app. You can discover the entire range in the object library within Interface Builder:

object_library

The raywenderlich.com OS X tutorial team will also be putting together a quick reference guide to different UI components over the coming months – so be sure to check back for that.

Viewing collections

Often you’ll want your app to display UI for multiple model objects at the same time – for example showing a list of upcoming appointments, or a set of photos in an album.

OS X provides two different views that are designed to show collections of model objects – in the form of table views and collection views.

As their name suggests, table views are used to show tabular data, with rows representing individual model objects, and the columns representing attributes on those objects.

table_view_sample

Table views are made up of cells that can be recycled as they scroll on and off screen. Data can be provided either via a data source protocol or using Cocoa Bindings.

Tables support sorting, editing and custom cells, giving you a very powerful view for displaying data.

The more generic collection view is also comprised of a collection of cells, but this time, each cell represents the entire model object. The layout of these cells is completely customizable.

collection_viewcollection_view_circle

Similarly to the table view, the data for a collection view can be provided either via a data source protocol, or through Cocoa Bindings. Cells are also recycled as they disappear out of the view, reducing the memory footprint.

Collection views have built in support for cell selection, animated re-ordering and grouping cells into sections.

Handling user interaction

A key part of any OS X is allowing user interaction through the mouse, trackpad, keyboard and any other of a number of input devices. To assist with designing user input to your app, OS X provides a unified event dispatch model, built around the concept of a responder chain.

Events generated from a keyboard are known as Key Events, and these follow quite a complicated path to arrive at your app. Some key presses don’t event make it to your app – as they are intercepted at the OS level (e.g. power button, screen brightness, volume).

Key events can represents a single key, or a key combination – and when they arrive at your app, they are first checked to see whether they are a keyboard shortcut that’s bound to a menu item.

If not, they are checked to see whether the are used to navigate around the user interface of your app – e.g. tabbing between input fields. If this isn’t the case, then the window works out which of its views is currently “active” (so-called first responder) before passing it the key events. These can either be interpreted as per-view commands or as characters to insert.

Keyboard input is really quite complicated, since it can affect many levels of the system and app architecture, but OS X goes a long way to assist with this processing. In many cases, you’ll find that it behaves as you would expect it out of the box.

Mouse-like events are passed to your application, which establishes which window and hence view they were performed on, before passing them to your custom subclass to allow you to handle them appropriately. The responder class (which views inherit from) includes methods you can override which get called when a clicks and moves the mouse.

Trackpads offer lots of additional gestures to a traditional mouse, so the concept of gesture recognizers has been borrowed from iOS. These can be use to interpret a sequence of multi-finger touches into a semantic action – such as a pan or rotation.

Gesture recognizers offer a much higher level of interpretation of mouse-like events, and they’re associated with views and can intercept all the mouse-like events associated with that view.

The event handling architecture in OS X is quite complicated, but the defaults go a long way to handling many common cases. The power of the responder chain makes it easy to handle events at the highest level possible.

Menus

Menus are collections of different actions that you can associate with your app. Menus can appear in different places, including:

  • Menu Bar this is bar along the top of the screen
    menu_bar
  • Context Menus appear when the user right clicks
    context_menu
  • Dock Menu when the user long-presses the dock icon
    dock_menu

All of these menus can be configured in Interface Builder, allowing you to configure their appearance, the hierarchy they appear in and to associate actions with each item.

ib_menu

Data Layer

The user interface is an enormously important part of your OS X app, but it’s probably not the entirety of your app. Most apps provide a user interface so that users can interact with an underlying data model.

Data models depend heavily on the domain in which your app exists – there’s no magical solution to building a data layer. In fact, it’s often the case that you’ll use the object oriented language features available in Swift to create a set of objects that model the domain of your app.

It’s extremely important that the data layer should be separated out from the user interface, making your software your software more maintainable and less error-prone. OS X supports this architecture through Cocoa Bindings – a technology that wires up model objects to the UI and ensures that they are automatically kept in sync with each other.

You can create a completely separate dynamic framework to contain your data layer – completely separating it from the UI layer. This can allow the same data layer to be used in multiple apps – possibly even shared between an OS X and an iOS app, and increases testability.

Although you can create your own data layer, Apple provides a framework called Core Data. This is a comprehensive framework for creating an object graph to completely model your entire data layer. It supports persistence to disk, data validation, undo and much more.

Core Data has great support for Cocoa Bindings, meaning that it’s really easy to integrate your model editing UI with a Core Data backend to build the bulk of your app really quickly.

Other useful Cocoa functionality

This article has given you a very brief overview of some of the Cocoa concepts that are likely to be used in every single OS X app. This barely scrapes the surface of what is a very rich platform.

Some highlights of other parts of Cocoa that are extremely useful when building powerful OS X apps:

  • Networking: In addition to access to the very lowest level of networking functionality, OS X provides a much higher-level API for handling HTTP requests. The networking model is built around an asynchronous session – seamlessly handling uploads and downloads as a list of tasks.
  • Location: You might associate location-based services primarily with mobile devices, but you have full access to a lot of powerful functionality both about location through Core Location, and for mapping using MapKit.
  • WebKit: Safari is one of the top web browsers, and you can integrate the powerful rendering engine into your own app via WebKit. It also includes the ability to interact with the content, and to render HTML content from a selection of sources.

Where to go from here?

This article has given you an overview of how Cocoa apps for OS X fit together, but it hasn’t given you a great idea of how you can actually use this to get started creating apps. Fear not – for that is the purpose of the next article in this introductory series.

If you’d like to learn more about the theoretical side of building OS X apps then Apple has provided a good guide to Cocoa apps as part of the documentation guides. It’s not especially helpful at the practical aspects of building apps, but if you read it in its entirety then you’ll know an awful lot about Cocoa!

As ever, if you have any questions or comments feel free to get involved on the forums or leave a comment below.

The post Mac OS X Development Tutorial for Beginners Part 2: OS X App Anatomy appeared first on Ray Wenderlich.

Mac OS X Development Tutorial for Beginners Part 3: Your First OS X App

$
0
0

featureImage_250

Welcome back to our 3-part Mac OS X Development tutorial for beginner series!

This introductory series about building apps on OS X has covered a lot of ground. This is what you’ve already learned:

  • Tooling: In part one you learned about the many facets of Xcode – and had a glimpse of how you could use it to start developing for OS X.
  • App Anatomy: The second part covered a lot of the theory behind how OS X app are constructed – from the data layer, through the binary assets, to designing the UI.

In this third and final part, you’re going to dive deep into the world of OS X development, by creating your first ever app!

The app you’re going to build is a magic-8 ball app, to help you make all those difficult decisions in day-to-day life. You’ll start from scratch – first creating a “Hello World!” app before moving on to creating an app to solve all your problems!

Note: This app requires OS X El Capitan and Xcode >=7.1 — make sure you upgrade before trying to follow the tutorial.

Getting Started

Open Xcode and click Create a new Xcode project to start your new app. Choose OS X \ Application \ Cocoa Application:

01_project_template

Set the product name MagicEight, the language to Swift and ensure that the Use Storyboards is checked:

02_project_options

Choose a location on disk to save your project and then click Create to open your empty project.

Build and run MagicEight to check that everything is working:

03_bar_01

Great – so the app runs, but it does absolutely nothing yet. It wouldn’t be right to start a new platform without creating “Hello World!” first…

Hello World!

The user interface for an OS X app is provided by the storyboard file, which you edit using interface builder. This allows you to design the UI in a visual manner, reducing the amount of complex code you have to write.

Open Main.storyboard by selecting it in the Project Navigator in the left-hand pane:

04_project_navigator

You’ll now see the storyboard open in the center panel:

05_storyboard

The template storyboard contains three components:

  • Menu Bar: Controls the menu that appears when the app runs.
  • Window Controller: Manages the default window that appears. Uses one or more view controllers to manage its content.
  • View Controller Responsible for a region of the window–both for display and handling user interaction.

During this introductory tutorial you’ll concentrate your efforts on the view controller.

Adding a Label

First up, you need to add a label to the view controller to display your welcome text. A label is actually a special type of NSTextField that’s designed for displaying a single line of non-editable text–perfect for “Hello World”.

To add your first label:

  1. Click the icon in the toolbar to show the utilities panel on the right-hand side.
  2. Use the icon towards the bottom of the panel to open the Object Library. This, as the name suggests, is a catalog of things you can drag onto the storyboard canvas to construct your layout.
  3. Use the search box at the bottom to search for label.
  4. You’ll see the label object highlighted in the library.

06_object_library

Drag the label from the object library onto the view controller:

07_label_vc

To change the text content of the label, select the Attributes Inspector tab of the Utilities panel, locate the Title field and enter Hello World!:

08_hello_world

You use the attributes inspector to control the appearance and behavior of the different controls that OS X offers. Find the Font entry, and click the T icon to the right to open the font panel. Change the style to Thin and the size to 40. Click Done to save the changes:

09_font

Cast your eyes back over to the view controller canvas and you’ll see something strange:

10_wrong_size

Although you’ve adjusted the text and size of the label, it has remained the same size, causing nearly all of the text to disappear. Why is this?

Basic Auto Layout

You placed the label on the view controller’s canvas, but you haven’t actually told OS X how it should position it. The view controller appears at one size in the storyboard, but once it’s running in the app, the user can change the window size–so you need to specify how the label should be positioned for any window size.

This sounds like it might be a really difficult task, but luckily Apple has your back. OS X uses a powerful layout engine called Auto Layout, in which the relationships between different components of the view are expressed as constraints. These constraints are then interpreted at runtime to calculate the size and position of each element within the view.

Note: Auto Layout is a complex topic, and this introductory tutorial won’t cover it in any great depth. If you’d like to read more on the topic then there are some excellent tutorials on the site targeted to Auto Layout on iOS—luckily the engine is almost identical on the two platforms.

Ensure that the label is selected in the view controller, and then click the Align button in the lower toolbar. Select Horizontally in Container, ensuring the value is set to 0 before clicking Add 1 Constraint to add the constraint:

11_align

This will ensure that the label will always appear in the center of the window, irrespective of its width. You’ll notice that some angry red lines have appeared in the storyboard:

12_angry_red

This is because you’ve provided a constraint that specifies the location of the label in the horizontal direction, but you’ve not provided any information about the vertical axis yet.

Once again, ensure that the label is selected in the view controller, and this time click the Pin menu on the Auto Layout toolbar at the bottom. Enter 30 in the top constraint box and ensure that the I-bar beneath it is solid red. Set the value of Update Frames to Items of New Constraints before clicking Add 1 Constraint:

13_pin

Immediately you’ll notice the view controller update—you can now see the entire label, and the angry red lines have changed to calming blue:

14_happy_storyboard

And that’s your “Hello World” app done (for now). Use the “play” button to build and run, and inspect your handiwork:

15_bar_02

Congratulations! Not very personal though is it? In the next section you’ll discover how to make the traditional greeting a little more friendly.

Handling User Input

In this section you’re going to add a text field to allow the user to enter their name so that you can welcome them personally.

Control Layout

As you did before, use the object library to locate and then drag a Text Field and a Push Button onto the view controller. Position them above the “Hello World!” label:

16_position_textfield

Remember that placing the controls on the canvas isn’t enough for OS X to understand how you want them positioned as the window changes size. You need to add some constraints to convey your wishes.

Select the text field, and then Command-Click the button to select both simultaneously. Click the Stack icon on the Auto Layout toolbar at the bottom of the storyboard:

17_stack

This has created a new stack view containing the text field and the button. A stack view automatically generates the layout constraints required to position the contained views in a line. You can use the attributes inspector to configure many common properties of the stack view.

NOTE: NSStackView has been in OS X since 10.9, but received a significant update in 10.11 (El Capitan)—in line with its introduction (UIStackView) in iOS. Stack views are similar on both platforms, so you can check out the iOS tutorial on stack views to get up to speed. Or hang tight—there’s a tutorial on NSStackView dropping in the next few weeks.

Once you’ve started stacking it’s difficult to stop. This time, you’re going to stack your newly created stack view with the “Hello World!” label—in a vertical stack view.

Use the button to the left of the lower toolbar to show the Document Outline and then locate the “Hello World” control and the existing stack view. Command-click them to select both:

18_document_outline

As you did before, use the Stack button on the bottom toolbar to create a new stack view:

19_stack

While this new stack view is selected, open the Attributes Inspector and set the Alignment to Center X, and the spacing to 20:

20_stack_config

This ensures that the label and the upper stack view are nicely centered and there’s a gap of 20 points between them.

A couple more bits of layout to complete before you can turn your attention to the task of handling user input.

The stack view handles the positioning of its content relative to each other, but it needs to be positioned within the view controller’s view. Select the outer stack view and use the Align auto layout menu to center it horizontally within its container:

21_align

And use the Pin menu to pin the stack view to the top, with a spacing of 30:

22_pin

Finally, to ensure that the text field always has the space for the user’s name, you will fix its width.

Select the text field and use the Pin menu in the bottom toolbar to specify a Width of 100. Click Add 1 Constraint to save the new constraint:

23_textfield_width

With that your layout is pretty much complete—it should look like the following:

24_layout

Now you can turn your attention back to those new controls you added.

Outlets and Actions

Select the text field and open the Attributes Inspector. In the Placeholder field type Name:

25_name

This grayed out text will instruct the user what the field is for, and disappears as soon as they start typing.

Select the button, and again open the Attributes Inspector. Set the Title to Welcome:

26_welcome

That’s the cosmetic aspect done. Time to wire these two controls into code.

OS X provides a way to interact with the storyboard UI from code using outlets and actions:

  • An outlet is a property in code that is connected to a component in the storyboard. This allows you to access the properties of controls within a storyboard from your code.
  • An action is a method on a class in code that is invoked when the user interacts with the components in the UI – e.g. by clicking on a button.

You are going to add outlets for the text field and the label, and an action that will be called when the user clicks the welcome button.

The view controller you’ve been working on already has a skeleton class associated with it in code—in ViewController.swift. This is where you’ll add the outlets and action.

Open the assistant editor using the button in the toolbar:

27_assistant_editor

This will split the screen and show a code file alongside the storyboard. It should be displaying ViewController.swift, but if it isn’t use the jump bar to select Automatic \ ViewController.swift:

28_jump_bar

Right-click-drag (or control-drag) from the text field in the storyboard over to the line above override func viewDidLoad() in ViewController.swift:

29_textfield_outlet

Ensure that Outlet is selected and call the new outlet nameTextField:

30_name_textfield

This will add the following property to ViewController and updates the storyboard to automatically connect the text field when loading the view controller:

@IBOutlet weak var nameTextField: NSTextField!

Repeat exactly the same process for the “Hello World!” label, this time specifying that the outlet should be called welcomeLabel:

31_welcome_label

Now time to turn your attention to the button. Once again Control-drag from the button in the storyboard over to the ViewController class:

32_button_action

This time, change the Connection to Action and name it handleWelcome:

33_action_settings

Click Connect to make the connection and Xcode will add the following empty method to ViewController:

@IBAction func handleWelcome(sender: AnyObject) {
}

This method will be called every time the user clicks the button.

Add the following line to the handleWelcome(_:) method body:

welcomeLabel.stringValue = "Hello \(nameTextField.stringValue)!"

This updates the stringValue property of the welcomeLabel to a welcome message constructed using the stringValue of the nameTextField. stringValue represents the value currently displayed by a text-based control—be it user-entered or defined in the storyboard.

That’s all the code you need to get your personalized version of “Hello World” going! Build and run to give it a try. Once the app has started, try entering your name in the Name box and clicking the Welcome button. You’ll see your very own version of “Hello world!”:

34_hello_sam

Pretty cool eh? Well, the fun doesn’t stop there. Next up you’re going to learn about adding images to your app, to create an amazing magic-8 ball utility!

Assets

You were promised a magic 8-ball app at the start of this tutorial, and so far you’ve seen no mention of a ball. Well, that’s all about to change.

An 8-ball is pretty distinctive, and it wouldn’t be a very exciting 8-ball app without some visualization. Download the images you’ll need to make your app look swish. You’ll find two images inside the zip file—representing the two sides of a magic 8-ball:

35_assets

Image assets are stored in an asset catalog within an OS X app. This catalog manages the different imagery and the different resolutions required for the app icons and the in-app images.

Open Assets.xcassets by selecting it in the project navigator:

36_asset_catalog

You can see that the catalog currently only contains one item – AppIcon. This is where you would put the artwork to give your app a cool icon.

You need to add the downloaded images to the asset catalog. Locate the images in finder, and drag them both into the asset catalog:

37_drag_asset_catalog

This will create two new entries in the asset catalog:

38_added_assets

Notice that there are three “cells” for the images. These cells represent the different screen scales–standard (1x), retina (2x) and retina-HD (3x). Normally you would provide assets for each of these cells, but in this simple project you will provide just one.

The image you’ve been provided is actually designed to be used at retina resolutions (2x), so drag the image from the left-hand cell to the central (2x) cell:

39_drag_retina

Repeat for both of the 8-balls assets, so that the asset catalog looks like this:

40_finished_asset_catalog

Those images are now available to use in your app—both from code and inside the storyboard.

Displaying Images

You’ve already seen how to display text, buttons and text input fields in your app, but how about images? Enter ImageView.

Open Main.storyboard and use the object library to search for image view:

41_image_view

Drag an image view onto the view controller canvas, at the bottom of the stack view. Notice how a horizontal blue line will appear denoting where in the stack view that the new image view will appear:

42_add_to_stack

Open the Attributes Inspector and set the Image property to 8ball:

43_set_8ball

This will update the canvas with the image, read from the asset catalog:

44_vc_with_image

Build and run the app to see how the image appears:

45_bar_03

Well, the image has appeared, but is clipped by the window. You can drag to resize the window in the usual way, but it would be much better if the window was correctly sized when the app starts, and then keeps a fixed size.

Window Size

The initial size of MagicEight’s window is determined by the size of the view controller in the storyboard. Select the view controller’s view in Main.storyboard and open the Size Inspector. Set the Width to 350 and the height to 480:

46_vc_size

Notice that the storyboard canvas now looks strange:

47_stange_vc

This is because the layout constraints need to be re-evaluated.

Use the Resolve Auto Layout Issues menu on the bottom auto layout menu bar and select All View in View Controller \ Update Frames:

48_fix_al

This will re-run the layout engine over the storyboard, and update the preview:

49_fixed_vc

Build and run to see how the app looks now:

50_bar_04

That looks much better. Try resizing the window—you’ll see that you can still manually drag it to sizes that don’t work for MagicEight’s layout.

You have a couple of options here—you can either update the layout so that it adapts nicely as the window changes size (e.g. to resize the image for small windows), or you can fix the window size. You’re going to take the second, easier approach.

Window Sizing

The window controller is responsible for managing the size of the window. Open Main.storyboard and select the window inside the window controller:

51_select_window

Open the Size Inspector and set the Content Size to a Width of 350 and a height of 480. Then check Minimum Content Size and Maximum Content Size ensuring that the the sizes are the same as the content size you entered:

52_content_size

Build and run MagicEight again, and attempt to resize the window. You no longer have control over the window size—it’s now fixed. Mega—just what you wanted.

You can now turn your attention back to the task in-hand—building the “magic” of the magic 8-ball. Well, nearly—there’s a bit more layout to do first.

Handling clicks

When the user clicks on the 8-ball you will switch the image to the other side and display a piece of advice. You need a new label to display this advice.

Open Main.storyboard and find the view controller scene. Use the Object Library to locate a wrapping label and drag it from the library beneath the stack view:

53_wrapping_label

You want this label to be positioned at the center of the magic-8 image, so you need to add some auto layout constraints.

Control-drag from the Multiline Label to the Image View in the Document Outline:

54_adding_constraints

Hold shift and select Center Vertically and Center Horizontally before clicking Add Constraints:

55_center_constraints

The label doesn’t automatically reposition—but you’ve handled this before. Use the Resolve Auto Layout Issues menu on the bottom auto layout toolbar to select All View in View Controller \ Update Frames:

56_fix_al

This repositions the label, and it becomes immediately obvious that you need to do some work on the appearance.

Select the multiline label, and use the Attributes Inspector to set the following:

  • Title: Piece of Advice
  • Alignment: Center
  • Text Color: Keyboard Focus Indicator
  • Font: System 20

57_label_config

Head over to the Size Inspector and set the Preferred Width to Explicit with a value of 75:

58_label_size

To get an idea of what the end product might look like, select the image view, and use the Attributes Inspector to set the Image to magic8ball:

59_change_image

Once again, click the main view and use the Resolve Auto Layout Issues\All Views in View Controller\Update Frames to update the layout:

60_magic8_layout

This is looking pretty good. You need to respond each time the user clicks on the 8-ball—time to discover gesture recognizers.

Gesture Recognizers

You were able to create an action in code that would run every time the user clicks the button. That was possible because buttons are designed to handle clicks—but the same is not true of image views.

Apple has provided a set of gesture recognizers that can be added to any view. These recognizers convert low-level mouse and trackpad input into semantic events—such as click, zoom and rotate.

You will add a click gesture recognizer to the image view, and then create a corresponding action in the view controller’s code.

In Main.storyboard, head over to the Object Library and search for click gesture. Drag the Click Gesture Recognizer out of the library and onto the image view. It will appear like this in the document outline:

61_gesture_recogniser

This gesture recognizer will be activated whenever the user clicks on the image—exactly what you want. You now need to create some new connections, and then you’ll be ready to switch over to code for the final sprint.

IB Connections

In the same way you did before, open up the assistant editor and ensure that it is showing ViewController.swift. Then create two new outlets by control-dragging from the storyboard to the code: one for the image view (call it ballImageView) and one for the multiline label (call it adviceLabel). This adds the following new outlets:

@IBOutlet weak var ballImageView: NSImageView!
@IBOutlet weak var adviceLabel: NSTextField!

You also need an action to wire up the newly-created gesture recognizer. Control-drag from the click gesture recognizer in the document outline, over to the code:

62_gesture_action

Change the Connection to Action and name it handleBallClick:

63_action_config

Click Connect and Xcode will add the following function definition to the ViewController class:

@IBAction func handleBallClick(sender: AnyObject) {
}

You’ve now finished all the work in Interface Builder, so you can switch back to the standard editor, and open ViewController.swift.

Manipulating UI from code

When the user clicks on the 8-ball you want to switch between showing some advice, or showing the “8”. This means that the handleBallClick(_:) will manipulate both the image view and the advice label.

Add the following code to handleBallClick(_:):

// 1:
if(adviceLabel.hidden) {
  // 2:
  adviceLabel.hidden = false
  ballImageView.image = NSImage(named: "magic8ball")
} else {
  // 3:
  adviceLabel.hidden = true
  ballImageView.image = NSImage(named: "8ball")
}
  1. Check whether the adviceLabel is currently visible. hidden is a boolean property on NSView (and hence NSTextField) that allows you to specify whether the view should be visible or not.
  2. If the advice label is currently hidden then show it, and change the image to the magic-side. NSImage(named:) loads the image from the asset catalog, and the image property on NSImageView specifies the image to display.
  3. Conversely, if the advice label is currently visible then hide it and switch the ball back to the “8” side.

Build and run and click the ball to see it switching between showing the “8” and the piece of advice. Pretty neat right? Notice how when you first start the app the advice is already showing? That’s not really what you want, but it’s a simple fix.

Initial Setup

When the app first starts you want to ensure that the advice label is hidden, and the 8-ball image is showing. View controllers have a perfect way of configuring this initial setup—in the form of viewDidLoad().

Once the view controller has finished loading all the view components from the storyboard, it calls viewDidLoad() to give you a chance to perform some final configuration.

In ViewController.swift, find the viewDidLoad() method and add the following body:

adviceLabel.hidden = true
ballImageView.image = NSImage(named: "8ball")

You’ll recognize this code from the click handler action—it just hides the advice label and sets the image to 8ball.

Build and run to check that you can’t see the advice from the outset.

Advice Generator

At the moment, no matter how many times you “shake” the ball, it always gives you the same advice. That’s not especially helpful. Time to add a bit of randomness.

Add the following code as a property inside ViewController—just below the class definition line:

let adviceList = [
  "Yes",
  "No",
  "Ray says 'do it!'",
  "Maybe",
  "Try again later",
  "How can I know?",
  "Totally",
  "Never",
]

This is an array of strings the make up all the different options for advice that the ball can dispense.

Head to the very bottom of the file (not within the ViewController class) and add the following extension:

extension Array {
  var randomElement: Element? {
    if count < 1 { return .None }
    let randomIndex = arc4random_uniform(UInt32(count))
    return self[Int(randomIndex)]
  }
}

This adds a new property to the standard library’s Array type that will return a random element. If the array is empty it returns nil, otherwise it generates a random index using arc4random_uniform() before returning the corresponding element.

Update the first branch (i.e. adviceLabel.hidden == true) of the if statement in handleBallClick(_:) to match the following:

if let advice = adviceList.randomElement {
  adviceLabel.stringValue = advice
  adviceLabel.hidden = false
  ballImageView.image = NSImage(named: "magic8ball")
}

This attempts to get a random piece of advice to display, and if successful updates the stringValue on adviceLabel to show it.

Build and run, and click the 8-ball a few times to start benefiting from the ball’s wisdom:

64_final_bar

Where to go from here

You can download the completed version of MagicEight here.

This Mac OS X development tutorial introductory series has given you a basic level of knowledge to get started with OS X apps–but there’s so much more to learn!

Apple has some great documentation covering all aspects of OS X development – head on over to https://developer.apple.com/library/mac/navigation/

You should also stick around on raywenderlich.com – we’ve got some awesome OS X tutorials lined up for the coming months!

If you have any comments or questions feel free to reach out on twitter, or in the comments section below!

The post Mac OS X Development Tutorial for Beginners Part 3: Your First OS X App appeared first on Ray Wenderlich.

Windows and Window Controllers in OS X Tutorial

$
0
0

Windows250x250

Windows are the “containers” for all the UI associated with all OS X 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. OS X 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 OS X app makes use of MVC (Model-View-Controller), 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 model layer varies according to your app type and design.

In this windows and window controllers in OS X 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. Having said that, it requires basic knowledge of the following topics:

  • Swift
  • Xcode, and in particular, storyboards
  • Creating a simple Mac (OS X) app

If you’re not familiar with any of the above, you might want to brush up with some other tutorials on this site:

Getting Started

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

1-CocoaApp

In the next screen, fill out the fields as indicated below, but enter your own name (or superhero alias) instead of mine.

2-XcodeTemplate

Click Next and save your project.

Build and run, and you will see:

3-FirstWindow

To open more documents, select File / New. All the documents are positioned in the same place, so you’ll only see the top document when you click and drag them around. It’s not a desirable effect, so add fixing this to your to-do list, but don’t dive in yet.

4-Open-Many

You can also use the Windows menu to bring windows to the front.

5-Bring-ToFront

Documents: Under the Hood

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

Document Architecture

A document is a container for data in memory that you can view in a window. Eventually, it can be written to or read from a disk or iCloud. Programmatically speaking, a document is an instance of the NSDocument class that acts as the controller for the data objects—aka model—associated with the document.

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

Visuals are nice too, so here’s a chart that shows how the classes work together:
DocArchitecture

Disabling Document Saving and Opening

The document architecture also provides the saving/opening mechanism for documents.

In Document.swift, you’ll find the empty implementation of dataOfType, for writing, and readFromData for reading. Saving and opening documents is outside the scope of this tutorial, so you’ll make some changes to prevent confusing behavior.

In Document.swift, remove autosavesInPlace:

  override class func autosavesInPlace() -&gt; Bool {
    return true
  }

Now you’ll 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, select File / Open and the finder dialog box, including controls, sidebar, toolbar etc., is there:

OpenDialog

When it has no action defined, a menu item is rendered useless. The same disabling effect happens when there is no object in the responder chain that responds to the selector associated with the action.

Hence, you’ll disconnect actions that are defined for the menu items you need to disable.

no-saving-for-you

In the storyboard, select File / Open in Main Menu in the Application Scene.

Select the Connections Inspector and click Open. As you can see, it connects to the first responder via the openDocument selector, aka the first object to respond to this selector in the responder chain. Delete this connection by clicking on the x as shown below:

TargetAction

Repeat this step for Save, Save As and Revert to Saved.

Build and Run. Toggle the Open menu and check that it looks like this:

7-OpenMenu

Window Position

When you run BabyScript, the window opens near the left edge, but somewhat below the center of the screen.

Why does it choose this location?

Go to the storyboard, and in the outline view select Window, and then select the Size Inspector. Run BabyScript – or bring it to the front – and you should see the following screen:

5-WindowSizeInspector

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 graphically by dragging the gray rectangle just below.

6-QuartzCoordinates

Note: The origin of a visual object (window, view, control, etc.) in Cocoa is the lower-left corner. Values increase as you go up and to the right in the coordinate system.

In contrast, many graphic environments, especially with iOS, the origin is in the upper-left, and values increase going down and to the right.

Suppose that the desired opening position for your window is 200 points offset horizontally and vertically from the top-left. You can set this with Xcode in the window’s Size Inspector or do it programmatically.

Set the Window’s Position with Interface Builder

It’s a safe bet that users will launch BabyScript on various screen sizes. Since your app doesn’t have a crystal ball to see what screen size it will open on at compile time, Xcode uses a virtual screen size and uses a concept similar to Auto Layout to determine the window position at run time.

To set the position, you’ll work with the X and Y values under Initial Position and the two drop-down menus.

Go to Initial Position to set window’s opening position in terms of screen coordinates. Enter 200 for both X and Y and select Fixed from Left and Fixed from Bottom in the upper and lower drop-downs, respectively. This sets the window’s origin at 200 points offset in both the x and y directions.

Build, run and you should see:

Follow these steps to pin the window to the upper-left corner:

  1. Drag the gray rectangle in the preview to the top-left of the virtual screen – this changes the initial position.
  2. Enter 200 for X and for Y, enter the maximum value minus 200, in this case 557.
  3. Select Fixed from Top in the lower drop-down.

The right side of the image below also shows what you should enter and where:

Window757557

Note: OS X remembers window positions between app launches. In order to see the changes you made, you need to actually close the app window – not just rebuild and run.

Close the window(s), and then build and run.

10-Window200x200Xcode

Set the Window’s Position Programmatically

Now you’ll accomplish the same task you did with Interface Builder, but this time you’ll do it programmatically.

The reason to take the “hard way” is two-fold. First, you’ll walk away with a better understanding of NSWindowController. Second, it’s a more flexible and straightforward approach.

At run time, the app will perform the final positioning of the window once it knows the screen size.

In the Project Navigator select the BabyScript group, then select File / New / File... From the dialog that pops up, select OS X / Source / Cocoa Class and click Next.

Create a new class called WindowController and make it a subclass of NSWindowController. The checkbox for XIB should be unchecked, and the Language should be Swift.

11-WindowController

Choose a location to save the new file. Once done, you’ll see a new file named WindowController.swift appear in the group BabyScript.

Go to the storyboard, and in Outline View select Window Controller from the Window Controller Scene. Choose the Identity Inspector, and from the Class drop-down select WindowController.

12-WindowController-2

When windowDidLoad is called the window will have completed loading from the storyboard, so any configuration you do will override the settings in the storyboard.

Open WindowController.swift and replace windowDidLoad with the following:

  override func windowDidLoad() {
    super.windowDidLoad()
    if let window = window, screen = window.screen {
      let offsetFromLeftOfScreen: CGFloat = 20
      let offsetFromTopOfScreen: CGFloat = 20
      let screenRect = screen.visibleFrame
      let newOriginY = CGRectGetMaxY(screenRect) - window.frame.height
        - offsetFromTopOfScreen
      window.setFrameOrigin(NSPoint(x: offsetFromLeftOfScreen, y: newOriginY))
    }
  }

This logic positions the window’s top-left corner 20 points offset in both the x and y directions from the top-left of the screen.

As you can see, NSWindowController has a window property and NSWindow has a screen property. You use these two properties to access the geometry of the window and the screen.

After ascertaining the height of the screen, your window’s frame is subtracted along with the desired offset. Remember the Y value increases as you move upwards on the screen.

visibleFrame excludes the areas taken by the dock and menu bar. If you don’t take this into account, you might end up with the dock obscuring part of your window.

When you enable dock and menu hiding, visibleFrame may still be smaller than frame, because the system retains a small boundary area to detect when to show the dock.

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

Cascading Windows

To further improve your windows’ position, you’ll introduce Cascading Windows, meaning an arrangement of windows that overlap one another while leaving the title bar for each window visible.

Add the following below the definition of WindowController in WindowController.swift:

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

You’re setting the shouldCascadeWindows property of NSWindowController to true by overriding the required init method of NSWindowController.

Build and run the app, and then open five windows. Your screen should look a little bit more friendly:

13-CascadingWindows

Make BabyScript a Mini Word Processor

Now comes the most exiting part of this tutorial. With just two little lines of code and the addition of an NSTextView control to your window’s contentView, you can add functionality that will blow your mind!

The Content View

Upon creation, a window automatically creates two views: an opaque frame view with a border, title bar, etc., and a transparent content view accessible via the window’s contentView property.

The content view is the root of the view hierarchy of a window, and you can replace the default with a custom view. Note that to position the content view, you must use the setContentView method of NSWindow — you can’t position it with the standard setFrame method of NSView.

ContentView

Note: If you’re an iOS developer, please note that in Cocoa, NSWindow is NOT a subclass of NSView. In iOS, UIWindow is a special subclass, of UIView. UIWindow itself is the root of the view hierarchy, and it’s simply playing the role of the content view.

Add the Text View

Remove the text field that says “Your document contents here” from the contentView in the storyboard, by selecting it and pressing delete.

To create the new NSTextField that will form the main part of your UI follow these instructions:

  1. In the storyboard, open the Object Library.
  2. Search for nstextview.
  3. Drag 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.
  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 Size Inspector. Enter 20 for X and Y, 440 for Width and 230 for Height

15-TextViewCreation

Build and run — you should see the following:

16-EmptyText

Look at that friendly, blinking text insertion point inviting you to enter your text! Start your manifesto, or just keep it simple with “Hello World”, and then select the text. Copy it with File / Copy or command – C, and then paste several times, just to get a feeling for the app.

Explore the Edit and Format menu to get the idea what’s available. You might have noticed that the Font / Show Fonts is disabled. You’re going to enable it now.

Enable the Font Panel

In the storyboard, go to the main menu, click on the Format menu, then on Font, then follow with a click 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?

Apparently, the action is already defined in the code imported indirectly by Xcode, you just need to make the connection.

Right-click Show Fonts and drag it to the First Responder in the Application Scene, and then release the mouse. A small window with a scrollable list of all the actions defined will pop up. Look for and select orderFrontFontPanel. You can also start typing it to find it more quickly.

17-ConnectFontPanel

Now, 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.

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

18-FontPanel

Wait, but you didn’t enter yet a single line of code regarding the text view, yet you have the power to change the size. You’re amazing!

Word Processing...Like A Boss

Initialize the Text View with Rich Text

To see the full power of the app, download some formatted text from here, and use it as the initial text for the text view.

Open it with TextEdit, select all and copy it to the clipboard. Go to the storyboard, select the Text View, then Attributes Inspector and paste the text into the Text Storage field.

20-RichText

Build and run, and you should see:

21-EditMe

Use Auto Layout

You do have the ability to scroll text that doesn’t fit the current window, but try to resize the window.

Oops! The text view does not resize with the window.

TextNoGrow

It’s a simple fix with Auto Layout.

Note: Auto Layout assists both you in both Cocoa and iOS with your app’s UI. It creates a set of rules that define the geometric relationship between the elements, and you define these relationships in terms of constraints.

With Auto Layout, you create a dynamic interface that responds appropriately to changes in screen size, window size, device orientation and localization.

There’s more to it than that, but for the sake of this tutorial, all you need to do is follow the few simple steps below — you can learn more about Auto Layout later. Here are a couple of good tutorials to check out: Beginning Auto Layout Tutorial in iOS 7, Part 1 and Part 2.

In the storyboard’s Outline View, select Bordered Scroll View, and click on the Pin button at the bottom-right of the canvas.

Click on each of the four little red bar constraints; the broken faded red will turn to solid red. Click at the bottom on the button that reads Add 4 Constraints.

PinTextView

Build and run, and watch how both the window and text view resize together:

22-AutoLayoutFixed

Show the Ruler by Default

To show the ruler automatically when a window opens, you’ll need an IBOutlet in the code. Select Format / Text / Show Ruler from the menus. In ViewController.swift, add one line into the viewDidLoad method toggleRuler, and add an IBOutlet above the method as shown below:

  @IBOutlet var text: NSTextView!
 
  override func viewDidLoad() {
    super.viewDidLoad()
    text.toggleRuler(nil)
  }

Now you’ll connect the text view to the view controller in the storyboard.

In the storyboard, right-click on the ViewController, hold and drag into the text view until it highlights, and then release the mouse. A small window with the list of Outlets will show itself. Select the text outlet:

23-TextConnect

Build and run, and now the window by default shows the ruler by default:

RulerShowing

So just as I promised, with two lines of code and the storyboard, you have created a mini word processor – Chapeau, Apple!

Modal Windows

You can make a window run in a modal fashion. The window still uses the app’s normal event loop, but input is restricted to the modal window.

There are two ways to utilize a modal window. You’ll call the runModalForWindow method of NSApplication. This approach monopolizes events for the specified window until it is gets a request to stop, which you can invoke by stopModal, abortModal or stopModalWithCode.

For this case, you’ll use stopModal. The other way, called a modal session, is not covered by this tutorial.

Add a Word Count Window

You’ll add a modal window that counts words and paragraphs in the active window. It has to be modal because it’s associated with a specific window and a specific state.

 

From the Object Library, drag a new window controller to the canvas. This creates two new scenes: a window controller scene and a view controller scene:

NewScenes

Select Window from the new window controller scene and use the Size Inspector to set its width to 300 and height to 150. Select View from the new view controller scene and resize it to match the window:

WordCountReduced

Since Word Count is a modal, having the close, minimize and resize buttons in its title bar would be bizarre, and a violation of HIG (Apple’s Human Interface Guidelines).

For the Close button, it would also introduce a serious bug because clicking the button will close the window, but won’t call stopModal. So, the app will forever stay in a “modal state”.

Removing Buttons from a Modal

In the storyboard, select the Word Count window and choose Attributes Inspector. Uncheck Close, Minimize and Resize. Also change the Title to Word Count.

WordCountAppearance

Now you’ll add four label controls and a push button from the Object Library to the contentView of the Word Count window.

Select the Attributes Inspector. Change the labels’ titles to Word Count, Paragraph Count, 0 and 0 respectively. Also change the alignment for the two 0 labels to right justified. Change the push button title to OK.

WordCountFields

Next on the list is creating a subclass for the Window Count ViewController. Select File / New / File.., choose OS X / Source / Cocoa Class. In the Choose Options dialog, enter WordCountViewController in the Class field and NSViewController in the Subclass of field.

WordCountViewController

Click Next and create the new file. Confirm that WordCountWindowControll.swift is now in the project navigator.

Go to the storyboard. Select the proxy icon for the view controller in the view controller scene for word count. Open the Identity Inspector, and select WordCountViewController from the Class drop-down. Note how the name on the canvas and the Outline View changed from the generic name to Word Count View Controller.

SetWCViewController

Create the Count Labels

Now you’ll create outlets for the two labels that show the count values — the two 0 labels. Under the class definition for WordCountViewController.swift, add the following:

  @IBOutlet weak var wordCount: NSTextField!
  @IBOutlet weak var paragraphCount: NSTextField!

In the storyboard, right-click on the proxy icon for the word count view controller, drag over the top-most 0 label and release when the control highlights. From the Outlets list that pops up, select wordCount.

Repeat the same for the lower 0 label, but this time select paragraphCount. Check for each of the labels in the Connections Inspector that the Outlets are connected like this:

WordCountConnected

In a few moments, you’ll add code to programmatically load the word count window controller. This requires that it have a storyboard ID. Select the window controller of the word count window from the storyboard. Select the Identity Inspector, and in Storyboard ID enter Word Count Window Controller:

WCControllerStoryboardId

Show Me the Modal

Now for the basic logic to show the modal window. In the document window’s view controller, find and select ViewController.swift add the code below under viewDidLoad:

  @IBAction func showWordCountWindow(sender: AnyObject) {
 
    // 1
    let storyboard = NSStoryboard(name: "Main", bundle: nil)
    let wordCountWindowController = storyboard.instantiateControllerWithIdentifier("Word Count Window Controller") as! NSWindowController
 
    if let wordCountWindow = wordCountWindowController.window, textStorage = text.textStorage {
 
      // 2
      let wordCountViewController = wordCountWindow.contentViewController as! WordCountViewController
      wordCountViewController.wordCount.stringValue = "\(textStorage.words.count)"
      wordCountViewController.paragraphCount.stringValue = "\(textStorage.paragraphs.count)"
 
      // 3
      let application = NSApplication.sharedApplication()
      application.runModalForWindow(wordCountWindow)
    }
  }

Take 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 in the word count window count outlets
  3. Show the word count window modally

Note: In step two, you passed data between two view controllers. This is similar to what you’d usually do in a prepareForSegue method when a segue is involved in the transition. Since showing a modal window is done directly with a call to runModalForWindow and there’s no segue involved, you pass the data just before the call.

Go Away, Modal

Now you’ll add code to dismiss the word count window. In WordCountViewController.swift, add the following method below the paragraphCount outlet:

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

This is an IBAction that should be invoked when the user clicks OK on the word count window.

Go to the storyboard, right-click on OK, then hold and drag to the proxy icon of the word count view controller. Release the mouse and select dismissWordCountWindow: from the presented list:

ConnectOK

Add UI to Invoke It

The only thing left to present the window is adding the UI to invoke it. Go to the storyboard, and in the Main Menu click Edit. From the Object Library, drag a Menu Item to the bottom of the Edit menu. Select the Attributes Inspector and set the title to Word Count.

WCMenu

Take a moment to create a keyboard shortcut by entering command – K as the key equivalent.

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

Go to the storyboard, right-click on the Word Count menu item, hold and drag over First Responder in the application scene. Select showWordCountWindow from the list.

ConnectWCMenuItem

Note: You might wonder why you connected the menu item to the first responder, but not directly to showWordCountWindow. It’s because the document view’s main menu and view controller are in different storyboard scenes, and as such, can’t be connected directly.

Build and run the app, select Edit / Word Count, and voila, the word count window presents itself.

WordCountFinal

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 OS X tutorial! But it’s just the tip of the iceberg as far as what you can do with windows and window controllers.

You covered:

  • The MVC design pattern in action
  • How to create a multi-window app
  • Typical app architecture for OS X apps
  • How to position and arrange windows with Interface Builder and programmatically
  • Using Auto Layout to resize a view with its window
  • Using modal windows to display additional information

And more!

I strongly recommend that you explore the huge amount of documentation provided by Apple in El Capitan’s Mac Developer Library. In particular, reference the Window Programming Guide.

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

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

The post Windows and Window Controllers in OS X Tutorial appeared first on Ray Wenderlich.


1000th Tutorial Giveaway Winner!

$
0
0
Our 1000th Tutorial - Time to Celebrate!

Our 1000th Tutorial – Time to Celebrate!

Recently, we had a post to celebrate our 1000th tutorial on this site.

In the post, we asked everyone a question: “How has raywenderlich.com made a difference in your life?”

I was overwhelmed by the kind and positive feedback from everyone – you guys and gals rock! I feel so lucky to be a part of such an amazing community :]

We selected one of the folks who responded to win a free ticket to our upcoming tutorial conference RWDevCon 2016, along with an invitation to our team-only pre-conference fun day.

Keep reading to find out who the lucky winner is – plus some runners up!

Runners Up

There were so many kind words from the community that we felt one prize wasn’t quite enough – we wanted to select some runners up as well.

Diego Vidal

“In my country, Colombia, there aren’t a lot of “local” resources to learn to develop iOS apps, so when I found this page I was truly excited!

In my bookshelf I now have almost all of your books, and thanks to the huge effort that you put on teaching others, I am now the Lead iOS Developer in my company, located in Bogotá, Colombia.

I truly can say that I have become the developer that I am today because of you, and because the motivation that I had reading all of your books. Keep doing all the great things that you do, you are really making a difference in a lot of people’s lives, like mine :)”

Jairo Cepeda

“Wow, just WOW. I am speechless to see raywenderlich.com come this far. I’ve been following the site for a couple of years now and I am SO THANKFUL for all I’ve learned here, regardless of whether I win the ticket.

There is not a single app I’ve worked on (released or not) that did not directly benefit from this site. Therefore, I am so glad to be part of this community. Congratulations Ray and the team!”

Ernandes Mourao

“Today my brain can’t think iOS and raywenderlich.com as two separate things. You guys have been my main reference for the past 4 years: your articles/books have made my iOS dev life easier and exciting since then. I’ll always be here to support you guys. Keep it up and congrats for the 1000th tutorial.”

Thanks everyone – each runner up will receive a free raywenderlich.com “Eat, Drink, Swift” t-shirt! :]

Grand Prize Winner

And now it’s time to announce our grand prize winner… Yusuke Hozumi! Here’s what Yusuke had to say:

“This website has seriously changed my life in a positive way. I learned how to program last year when Apple announced Swift at WWDC 2014. I read through the Swift documentation from Apple and I was heavily confused and I was getting ready to stop learning programming and live a boring day to day, paycheck to paycheck job.

One day, one of my friends recommended me to this website, at least to check it out before I give up programming. Well, I pretty much got addicted to this website!

I’m on this website 24/7 teaching my self new things, reviewing things that I learned. The iOS Apprentice has made it easy for me to study and learn. Thanks to this book and video tutorials on this website I have a job lined up to become an iOS Developer starting early next year.

Thanks to this website I don’t have to live a boring day to day life. I know I’m still learning but this website made it possible for me to dream about my future of becoming one of the presenters teaching about new API’s at Apple’s WWDC.

Sorry to make it little cheesy sounding but this is how this website changed my life! Thank you and please keep up the great work in pushing out quality tutorials for all the other apprentice developers out there just like me!”

Thank you Yusuke and we look forward to hanging out with you at RWDevCon 2016! :]

Where To Go From Here?

Once again, there were so many great responses on our 1000th tutorial celebration post and every one of them touched our hearts. Thank you so much for all of your kind comments – this reminds us why we’re making tutorials in the first place.

Thanks again to everyone for reading raywenderlich.com and making this all possible. Back to your regularly scheduled tutorials! :]

The post 1000th Tutorial Giveaway Winner! appeared first on Ray Wenderlich.

OS X View Controllers Tutorial

$
0
0

Learn how to control the UI with this OS X View Controllers Tutorial!

When writing any code, it’s important to get clear separation of concerns — functionality should be split out into appropriate smaller classes. This helps keep code maintainable and easy to understand. Apple has designed the frameworks available on OS X around the Model-View-Controller design pattern, and as such has provided various controller objects that are responsible for managing the UI.

View controllers are responsible for hooking up the model layer to the view layer, and have an incredibly important role in the architecture of your OS X app.

In this OS X view controllers tutorial you’ll discover the wide range of functionality that is baked into vanilla view controllers, along with learning how you can create your own view controller subclasses to build up your app in an easy-to-understand manner. You’ll see how the life cycle methods allow you to hook into important events for the UI of your app, together with how view controllers compare with window controllers.

To follow this tutorial you’ll need the most recent version of OS X and Xcode installed on your mac. There’s no starter project — you’ll build a great app from scratch! You might like to read Gabriel Miro’s excellent tutorial on windows and window controllers before embarking upon this view controllers tutorial, but it’s not a requirement.

Enough introduction — let’s kick off with some theory!

Introducing View Controllers

A view controller is responsible for managing a view and its subviews. In OS X, view controllers are implemented as subclasses of NSViewController.

View controllers have been around for a while (Apple introduced them with OS X 10.5), but before OS X 10.10 they weren’t part of the responder chain. That means, for example, that if you had a button on a view controller’s view, the controller would not receive its events. After OS X 10.10, however, view controllers became very useful as building blocks for more complex user interfaces.

View controllers allow you to split the content of your window into logical units. The view controllers take care of those smaller units, while the window controller handles window-specific tasks like resizing or closing the window. This makes your code way easier to organize.

Another benefit is that view controllers are easy to reuse in other applications. If a File Browser with a hierarchical view on the left is controlled by a single view controller, you can use it in another application that needs a similar view. That’s time and energy saved, which you can now devote to drinking beer!

Window Controller or View Controller?

You may be wondering when to use only a window controller, and when to implement view controllers.

Prior to OS X 10.10 Yosemite, NSViewController was not a very useful class. It did not provide any of the view controller functionality you could expect — for instance, that found in UIViewController.

With the changes introduced since, like the view life cycle and the inclusion of the view controllers in the responder chain to receive events from its view, Apple is promoting the Model View Controller (MVC) pattern in the same way it’s currently doing with iOS Development. You should use view controllers to handle all the functionality of your views and subviews and the user interaction. Use window controllers to implement the functionality associated to the application windows, like setting up the root view controller, resizing, repositioning, setting the title, etc.

This approach will help in building a complex user interface by dividing the different parts of the UI into several view controllers and using them like building blocks to form the complete user interface.

View Controllers in Action

In this tutorial, you’ll write an application called RWStore that lets you select different books from raywenderlich.com store. Let’s get started!

Open Xcode and choose to create a new Xcode project, and select OS X \ Application \ Cocoa Application from the templates menu. Click Next.

SelectTemplate

Name your project RWStore. On the options screen, make sure that Swift is selected as Language and the Use Storyboards checkbox is checked. You don’t need Unit and UI Tests, so uncheck the corresponding checkboxes. Click Next and save your project.

TemplateSettings

Download the project resources. The zip file contains images for the books and a Products.plist file containing an array of dictionaries with the information for a product, like the name, description, and price. You will also find a source code file named Product.swift. This file contains the Product class, that reads the product information from the plist file. You’re going to add these to RWStore.

Select the Assets.xcassets folder in the Project Navigator and drop the downloaded images into the column containing the app icon.

AddAssets

Drag and drop Products.plist and Product.swift into the Project Navigator on the left. Make sure that Copy items if needed is checked.

AddProductsPlist

Build and run the app. You should see the main window of your application.

window-empty

It’s empty now, but don’t worry — this is just the starting point.

Creating the User Interface

Open Main.storyboard, select View Controller Scene, and drag a pop-up button into the view. You’ll use this pop-up button to display the list of products.

add-popup

Set its position using auto layout. The pop-up button should occupy the full width of the view and stay pinned to the top, so select the pop-up button and click the Pin button located in the bottom bar.

In the pop-up that appears, select the trailing constraint and set its value to Use Standard Value. Repeat for the top and leading constraints.

AddPopupButton

To complete the UI, add a view to show the product details. Select a container view and drag it below the pop-up button.

add-container

A container view is a placeholder for another view that is not available in Interface Builder or is provided by another View Controller.

Now we’ll set up the auto layout constraints for this view. Select the container view and click on the Pin button. Add top, bottom, trailing, and leading constraints with a value of 0. Click the Add 4 constraints button.

container-constraints

Select the view of your view controller and click the Resolve Auto Layout Issues button to the right of the Pin button. Select All Views in Controller/Update Frames. Your view should look like this:

FinishedVC

Now you’ll create an action that will be called when the button selection changes. Open the Assistant Editor (you can also use the keyboard shortcut [alt] + [cmd] + [Enter]) and make sure that ViewController.swift is open. Control-drag from the pop-up button into ViewController.swift and add an Action Connection. In the pop-up view, make sure the connection is an Action, the name is valueChanged, and the type is NSPopUpButton.

popup.action-drag

popup.action-nuevo

On the canvas, the view controller is connected to the container view with an embed segue. Your app will use a custom view controller, so you can delete the auto-generated one: select the view controller associated with the container view and press delete.

delete-viewcontroller

Tab View Controllers

Now we’ll add the view controller used to display the product info: a Tab View Controller. A Tab View Controller is a view controller subclass (NSTabViewController); its view contains a tab view with two or more items and a container view. Behind every tab is another view controller whose content is used to fill the container view. Every time a new tab is selected, the Tab View Controller replaces the content with the view of the associated view controller.

Select a Tab View Controller and drag it on on the canvas.

drag-tabcontroller

The tab controller is now on the storyboard, but it’s not used yet. Connect it to the container view using an embed segue; control-drag from the container view to the Tab View Controller.

control-drag-tabview

Select embed in the menu that pops up.
Embed

With this change, when the app runs the area of the container view is replaced with the view of the Tab View Controller. Double-click on the left tab of the Tab View and rename it Overview. Repeat to rename the right tab Details.

rename-tabs

Build and run the app.

tabview-empty

Now the tab view controller is shown, and you can select between the two view controllers using the tabs. This isn’t noticeable yet because the two views are exactly the same, but internally the tab view controller is replacing them when you select a tab.

Overview View Controller

Next up you need to create the

Go to File\New\File…, choose the OS X\Source\Cocoa Class, and click Next. Name the class OverviewController, make it a subclass of NSViewController, and make sure Also Create XIB for user interface is not selected. Click Next and save.

add-overview

Return to Main.storyboard and select Overview Scene. Click the blue circle on the view and change the class to OverviewController in the Identity Inspector on the right.

OverviewVC

Drag three labels onto the OverviewController’s view. Place the labels on the top left side of the view, one below each other. Add an image view on the top right corner of the view.

Note: By default, the image view has no borders and can be a bit difficult to find in the view. To help during the layout process, you can set an image. With the image view selected, open the Attributes Inspector and select games in the Image field. This image will be replaced in runtime with the proper product image in the tutorial code

Select the top label. In the Attributes Inspector, change the font to System Bold and the size to 19.

The view should now look like this:

overview-finished-ui

It’s time to use the superpowers of auto layout to make this view look great.

Select the image view and click the Pin button on the bottom. Add constraints for top and trailing with the standard value, and constraints for width and height with a value of 180.

image-constraints

Select the top label and add bottom, top, leading, and trailing constraints using the standard value.

toplabel-constraints

Select the label below and add constraints for trailing and leading using the standard value.

middlelabel-constraints

Repeat for the last label, adding constraints for leading, trailing and bottom, using the standard value. For the top constraint, make sure that the image view is selected (so that the top is aligned to the image view instead of the super view), and use the standard value.

bottomlabel-constraints

Note: If you can’t see the image view in the selection menu, you may need to make the label wider, so that the end of the label is under the image view.

Click on the Resolve Auto Layout button in the bottom bar and select All Views in Controller/Update Frames. Your view should look like this:

overview-after-layout

After all your hard work on the interface, it’s finally time to see the result, so build and run.

build-run-overview

Click on the tabs and see how the tab view controller shows the appropriate view controller. It works right out of the box and without a single line of code!

Add Some Code

It’s time to get your hands dirty adding some code to show the products details in the view. In order to refer to the labels and image view from code you need to add an IBOutlet for each of them.

First, open the Assistant Editor and make sure OverviewViewController.swift is selected. Control-drag from the top label into OverviewController.swift and add an outlet named titleLabel. Ensure the type is NSTextField.

title-outlet

Repeat the process with the other two labels and the image view to create the rest of the outlets with the following names:

  1. priceLabel for the label in the middle.
  2. descriptionLabel for the bottom label.
  3. productImageView for the image view.

Like most UI elements, labels and image views are built of multiple subviews, so make sure that you have the correct view selected. You can see this when you look at the class for the outlet: for the image view it must be NSImageView, not NSImageCell. For the labels, it must be NSTextField, not NSTextFieldCell.

To show the product information in the overview tab, open OverviewController.swift and add the following code inside the class implementation:

//1
let numberformatter = NSNumberFormatter()
//2    
var selectedProduct: Product? {
  didSet {
    updateUI()
  }
}

Taking this code bit-by-bit:

  1. numberformatter is an NSNumberFormatter object used to show the value of the price, formatted as currency.
  2. selectedProduct holds the currently selected product. Every time the value changes, didSet is executed, and with it updateUI().

Now add the updateUI method to OverviewController.swift.

private func updateUI() {
  //1
  if viewLoaded {
    //2
    if let product = selectedProduct {
      productImageView.image = product.image
      titleLabel.stringValue = product.title
      priceLabel.stringValue = numberformatter.stringFromNumber(product.price)!
      descriptionLabel.stringValue = product.descriptionText
    }
  }
}
  1. Checks to see if the view is loaded. viewLoaded is a property of NSViewController, and it’s true if the view is loaded into memory. If the view is loaded, it’s safe to access all view-related properties, like the labels.
  2. Unwraps selectedProduct to see if there is a product. After that, the labels and image are updated to show the appropriate values.

This method is already called when the product changes, but also needs to called as the view is ready to be displayed.

View Controller Life Cycle

Since view controllers are responsible for managing views, they expose methods that allow you to hook into events associated with the views. For example the point at which the views have loaded from the storyboard, or when the views are about to appear on the screen. This collection of event-based methods are known as the view controller life cycle.

The life cycle of a view controller can be divided into three major parts: its creation, its lifetime, and finally its termination. Each part has methods you can override to do additional work.

Creation

  1. viewDidLoad() is called once the view is fully loaded and can be used to do one-time initializations like the configuration of a number formatter, register for notifications, or API calls that only need to be done once.
  2. viewWillAppear() is called every time the view is about to appear on screen. In our application, it is called every time you select the Overview tab. This is a good point to update your UI or to refresh your data model.
  3. viewDidAppear() is called after the view appears on screen. Here you can start some fancy animations.

Lifetime

Once a view controller has been created, it then enters a period during which it it handles user interactions. It has three methods specific to this phase of its life:

  1. updateViewConstraints() is called every time the layout changes, like when the window is resized.
  2. viewWillLayout() is called before the layout() method of a view controller’s view is called. For example, you can use this method to adjust constraints.
  3. viewDidLayout() is called after layout() is called.

In all three methods, you must call the super implementation at some point.

Termination

These are the counterpart methods to creation:

  1. viewWillDisappear() is called before the view disappears. Here you can stop your fancy animations you started in viewDidAppear().
  2. viewDidDisappear() is called after the view is no longer on the screen. Here you can discard everything you no longer need. For example, you could invalidate a timer you used to upate your data model on a periodic time base.

 

Life cycle in practice

Now that you know the most important things about a view controller’s life cycle, it’s time for a short test!

Question: Every time OverviewController’s view appears, you want to update the UI to take into account that a user selected a product when the Details tab was selected. Which method would be a good fit?

Solution Inside SelectShow>

 

Open OverviewController.swift and add this code inside the class implementation:

override func viewWillAppear() {
  updateUI()
}

This overrides the viewWillAppear to update the user interface before the view becomes visible.

The number formatter currently uses default values, which doesn’t fit your needs. You’ll configure it to format numbers as currency values; since you only need to do this once, a good place is the method viewDidLoad().

In OverviewController add this code inside viewDidLoad():

numberformatter.numberStyle = .CurrencyStyle

For the next step, the main view controller needs to react on product selection and then inform the OverviewController about this change. The best place for this is in the ViewController class, because this controller owns the pop-up button. Open ViewController.swift and add a these properties inside the ViewController class implementation:

private var products = [Product]()
var selectedProduct: Product!

The first property, products, is an array used to keep a reference to all the products. The second, selectedProduct, holds the product selected in the pop-up button.

Find viewDidLoad() and add the following code inside:

if let filePath = NSBundle.mainBundle().pathForResource("Products", ofType: "plist") {
  products = Product.productsList(filePath)
}

This loads the array of products from the plist file using the Product class added at the beginning of the tutorial, and keeps it in the products property. Now you can use this array to populate the pop-up button.

Open Main.storyboard, select View Controller Scene, and switch to the Assistant Editor. Make sure ViewController.swift is selected, and Control-drag from the pop-up button to ViewController.swift to create an outlet named productsButton. Make sure the type is NSPopUpButton.

popup-outlet

Return to ViewController.swift and add the following code to viewDidLoad() :

//1
productsButton.removeAllItems()
//2
for product in products {
  productsButton.addItemWithTitle(product.title)
}
//3
selectedProduct = products[0]
productsButton.selectItemAtIndex(0)

This piece of code does the following:

  1. It removes all items in the pop-up button, getting rid of the Item1 and Item2 entries.
  2. It adds an item for every product, showing its title.
  3. It selects the first product and the first item of the pop-up button. This makes sure that everything is consistent.

The final piece in this puzzle is reacting to the pop-up button selection changes. Find valueChanged(_:) and add the following lines:

if let bookTitle = sender.selectedItem?.title,
  let index = products.indexOf({$0.title == bookTitle}) {
  selectedProduct = products[index]     
}

This code tries to get the selected book title and searches in the products for the index of the title. With this index, it sets selectedProduct to the correct product.

Now you only need to inform OverviewController when the selected product changes. For this you need a reference to the OverviewController. You can get a reference within code, but first you have to add another property to ViewController.swift to hold that reference. Add the following code inside the ViewController implementation:

private var overviewViewController: OverviewController!

You can get the instance of OverviewController inside prepareForSegue(_:, sender:), which is called by the system when the view controllers are embedded in the container view. Add the following method to the ViewController implementation:

override func prepareForSegue(segue: NSStoryboardSegue, sender: AnyObject?) {
  //1
  let tabViewController = segue.destinationController as! NSTabViewController
  //2
  for controller in tabViewController.childViewControllers {
    //3
    if controller is OverviewController {
      overviewViewController = controller as! OverviewController
      overviewViewController.selectedProduct = selectedProduct
    } else {
      //More later
    }      
  }
}

This code does the following:

  1. Gets a reference to the Tab View controller.
  2. Iterates over all its child view controllers.
  3. Checks if the current child view controller is an instance of OverviewController, and if it is, sets its selectedProduct property.

Now add the following line in the method valueChanged(_:), inside the if let block.

overviewViewController.selectedProduct = selectedProduct

Build and run to see how the UI updates when you select a different product.

Detail View Controller

Now we’ll create a view controller class for the Details tab.

Go to File\New\File…, choose OS X\Source\Cocoa Class, and click Next. Name the class DetailViewController, make it a subclass of NSViewController, and make sure Also Create XIB for user interface is not selected. Click Next and save.

create-detailviewcontroller

Open Main.storyboard and select Details Scene. In the Identity Inspector change the class to DetailViewController.

detail-vcname

Add an image view to the detail view. Select it and click on the Pin button to create its constraints. Set width and height constraints to a value of 180, and a top constraint to the standard value.

detail-imageview-pin-constraints

Click on the Align button in the bottom bar and add a constraint to center the view Horizontally in the Container.

detail-image-align-constraint

Add a label below the image view. Change the font to bold and the size to 19, then click on the Pin button to add constraints for top, leading, and trailing, using the standard values.

detail-middlelabel-constraing

Add another label below the previous one. Select it, and click on the Pin button first to and add also constraints for top, leading and trailing, using standard values.

detail-bottom-label-constraint

Drag an NSBox under the last label. Select it and add constraints for top, leading, trailing and bottom, using standard values.

detail-box-constraints

Open the Attributes Inspector and change the box font to bold and the size to 14. Change the title to “Who is this Book For?”.

NSBoxSettings

An NSBox is a nice way to group related UI elements and to give this group a name you can see in Xcode’s Identity Inspector.

To complete the UI, drag a label inside the content area of the NSBox. Select the label and click on the Pin button to add constraints for top, leading, trailing, and bottom, all using the standard value.

detail.label-inbox-constraint

After updating the frames, the UI should look like this:

detail-finished-ui

To create the outlets for those controls, open the Assistant Editor and make sure that DetailsViewController.swift is open. Add four IBOutlets, giving them the following names:

  1. productImageView for the NSImageView.
  2. titleLabel for the label with the bold font.
  3. descriptionLabel for the label below.
  4. audienceLabel for the label in the NSBox.

With the outlets in place, add the implementation to show the product detail. Add the following code to DetailViewController class implementation:

// 1
var selectedProduct: Product? {
  didSet {
    updateUI()
  }
}
// 2
override func viewWillAppear() {
  updateUI()
}
// 3
private func updateUI() {
  if viewLoaded {
    if let product = selectedProduct {
      productImageView.image = product.image
      titleLabel.stringValue = product.title
      descriptionLabel.stringValue = product.descriptionText
      audienceLabel.stringValue = product.audience
    }
  }
}

You’re probably familiar with this code already, because it’s very similar to the Overview view controller implementation. This code:

  1. Defines a selectedProduct property and updates the UI whenever it changes.
  2. Forces a UI update whenever the view appears (when the detail view tab is selected).
  3. Sets the product information (using updateUI) in the labels and image view using the appropriate outlets.

When the product selection changes, you need to change the selected product in the detail view controller so that it updates the UI. Open ViewController.swift and add a property to hold a reference to the the detail view controller. Just below the overviewViewController property, add the following:

private var detailViewController: DetailViewController!

Find valueChanged(_:) and add the following inside:

detailViewController.selectedProduct = selectedProduct

This updates the selected product property of the view controller when the pop-up selection changes.

The last change is inside prepareForSegue(_:, sender:). Find the comment //More later and replace with the following:

detailViewController = controller as! DetailViewController
detailViewController.selectedProduct = selectedProduct

This updates the selectedProduct when the detail view is embedded.

Build and run, and enjoy your finished application!

Where to Go From Here

You can download the final project here.

In this OS X view controller tutorial you’ve learned the following:

  • What a view controller is and how it compares to a window controller
  • Creating a custom view controller subclass
  • How to connect elements in your view to a view controller
  • How to manipulate the view from the view controller
  • The lifecycle of a view controller, and how to hook into the different events

In addition to the functionality you’ve added to your custom view controller subclasses, there are many built-in subclasses provided for you. To see what built-in view controllers are available, take a look at the documentation.

If you’re not already read it, you should take a look at Gabriel Miro’s excellent tutorial on windows and window controllers.

View controllers are one of the most powerful and useful aspects of architecting an OS X app, and there’s plenty more to learn. However, you’re now equipped with the knowledge to go out there and start playing around building apps — which you should do now!

If you have any questions or comments, please join the forum discussion below.

The post OS X View Controllers Tutorial appeared first on Ray Wenderlich.

Self Improvement for Coders, and OS X Development – Podcast S05 E03

$
0
0
Meditation, exercise, cooking, and OS X. This episode has it all!

Meditation, exercise, cooking, and OS X. This episode has it all!

Join Mic, Jake, and Marin as they discuss self improvement for coders, before moving onto OS X development!

[Subscribe in iTunes] [RSS Feed]

Our Sponsor

This episode was brought to you by the kind folks over at Harvest.

Harvest is a time tracking tool built for understanding where your time is going. And for developers, it takes the pain out of time tracking. You can create a free 30-day trial at getharvest.com.

After your trial, enter code RAY to save 50% off your first month.

Interested in sponsoring a podcast episode? We sell ads via Syndicate Ads, check it out!

Show Notes

Contact Us

Where To Go From Here?

We hope you enjoyed this episode of our podcast. Be sure to subscribe in iTunes to get notified when the next episode comes out.

We’d love to hear what you think about the podcast, and any suggestions on what you’d like to hear in future episodes. Feel free to drop a comment here, or email us anytime at podcast@raywenderlich.com.

The post Self Improvement for Coders, and OS X Development – Podcast S05 E03 appeared first on Ray Wenderlich.

OS X NSTableView Tutorial

$
0
0

Create awesome user interfaces with table views!

Table views are one of the most ubiquitous controls in OS X applications, with familiar examples being Mail’s message list and Spotlight’s search results. They allow your Mac to represent tabular data in an attractive way.

NSTableView arranges data in rows and columns. Each row represents a single model object within a given data collection, and each column displays a specific attribute of a model object.

In this OS X NSTableView tutorial, you’ll use a table view to create a functional file viewer that will bear a striking resemblance to Finder. As you work through it, you’ll learn a lot about table views, such as:

  • How to populate a table view
  • How to change its visual style
  • How to react to user interaction, like a selection or double-click

Ready to create your first table view? Read On!

Getting Started

Click here to download the starter project and open it in Xcode.

Build and run to see what you’re starting with:

build-run-empty

You have a blank canvas from which you’ll create a cool file viewer. The starter app already has some of the functionality you’ll need to work through this tutorial.

With the application open, choose File/Open… (or use the Command+O keyboard shortcut).

build-run-fileopen

From the new window that pops up, choose any folder you want and click the Open button. You’ll see this in Xcode’s console:

Represented object: file:///Users/tutorials/FileViewer/FileViewer/

This message shows the selected folder’s path, and the code in the starter project passes that URL to the view controller.

If you’re curious and want to learn more about how things are implemented, here’s where to go looking:

  • Directory.swift: Contains the implementation of the Directory struct that reads the content of a directory.
  • WindowController.swift: Contains the code that presents you with the folder selection panel and passes the selected directory to the ViewController.
  • ViewController.swift: Contains the implementation of the ViewController class and is where you’ll spend some time today. It’s where you’ll create the table view and show the file list.

Creating the Table View

Open Main.storyboard in the Project Navigator. Select the View Controller Scene and drop a table view from the Object Library into the view.

drop-tableView

Next, you need to add some constraints. Click the Pin button in the Auto Layout toolbar. In the popup that appears, set the constraints as follows:

  • Top, Leading and Trailing: 0.
  • Bottom: 22, making sure to select View in the constraint’s option menu.

tableview-constraints

Click the triangular Resolve Auto Layout Issues button in the Auto Layout toolbar, and under the Selected Views section click on Update Frames.

tableview-updateframes

You’ve just preempted any Auto Layout warnings in the canvas by updating the frames of the views to match their constraints.

Take a moment to have a look at the structure of a newly created table view. As you probably gathered from its name, it follows typical table structuring:

  • It’s made up of rows and columns
  • Each row represents a single item within the data model collection
  • Each column displays specific attributes of the model
  • Each column can also have a header row
  • Header rows describe the data within a column

Screen Shot 2015-11-04 at 7.45.06 AM

If you’re familiar with UITableView on iOS, you’re treading familiar waters, but they’re much deeper here in OS X. In fact, you might be surprised by the number of individual UI objects in the object hierarchy that make up an NSTableView.

NSTableView is an older and more complex control than a UITableView, and it serves a different user interface paradigm, specifically, where the user has a mouse or trackpad.

The main difference with UITableView is that you have the possibility of multiple columns and a header that can be used to interact with the table view, for example, ordering and selecting.

Together, NSScrollView and NSClipView, respectively scroll and clip the contents of the NSTableView.

There are two NSScroller objects — one each for vertical and horizontal scrolling across the table.

There are also a number of column objects. An NSTableView has columns, and these columns have headers with titles. It’s important to note that users can resize and reorder columns, though you have the power to remove this ability by setting its default to disabled.

Anatomy of NSTableView

In Interface Builder, you’ve seen the complexity of the view hierarchy of the table view. Multiple classes cooperate to build the table structure, which usually ends up looking like this:

Artboard 1

These are the key parts of an NSTableView

  • Header View: The header view is an instance of NSTableHeaderView. It’s responsible for drawing the headers at top of the table. If you need to display a custom header, you can use your own header subclasses.
  • Row View: The row view displays the visual attributes associated with every row in the table view, like a selection highlight. Each row displayed in the table has its own instance of the row view. An important distinction to make is that rows do not represent your data; that the cell’s responsibility. It only handles visual attributes like selection color or separators. You can create new row subclasses to style your table view differently.
  • Cell Views: The cell is arguably the most important object in a table view. At the intersection of a row and column, you find a cell. Each one is an NSView or NSTableCellView subclass, and its responsibility is to display the actual data. And guess what? You can create custom cell view classes to display the content however you’d like.
  • Column: The columns are represented by the NSTableViewColumn class, which is responsible for managing width and behavior of the column, such as resizing and repositioning. This class is not a view, but a controller class. You use it to specify how columns should behave, but you don’t control the visual styles of the columns with it because the header, row and cell views have got things covered.

Note: There are two modes of NSTableView. The first is a cell-based table view called an NSCell. It’s like an NSView, but older and lighter. It comes from earlier days of computing when the desktop needed optimizations in order to draw controls with minimal overhead.

Apple recommends using view-based table views, but you’ll see NSCell in many of the controls in AppKit, so it’s worth knowing what it is and where it comes from. You can read more about NSCell in Apple’s Control and Cell Programming Topics

Well, now that was a nice little jog into the basic theory behind table view structure, and now that you get all that, it’s time to go back to Xcode and get to work on your very own table view.

Playing With Columns in a Table View

By default, Interface Builder creates a table view with two columns, but you need three columns to display name, date and size file information.

Go back to Main.storyboard.

Select the table view in the View Controller Scene. Make sure that you select the table view and not the scroll view that contains it.

tableview-select

Open the Attributes Inspector. Change the number of Columns to 3. It’s as simple as that! Your table view has now three columns.

Next, check the Multiple checkbox in the Selection section, because you want to select multiple files at once. Also check Alternating Rows in the Highlight section. When enabled, this tells the table view to use alternating row colors for its background, just like Finder.

tableview-attributes

Rename the column headers so the text is more descriptive. Select the first column in the View Controller Scene.

tableview-selectcolumn

Open the Attributes Inspector and change the column Title to Name.

tableview-changetitle

Repeat the operation for the second and third column, changing the Title to Modification Date and Size, respectively.

Note: There is an alternative method for changing the column title. You can double-click directly on the header on the table view to make it editable. Both ways have exactly the same end result, so go with whichever method you prefer.

Build and run. Here’s what you should see:

tableview-empty

Changing How Information is Represented

In its current state the table view has three columns, each containing a cell view that shows text in a text field.

But it’s kind of bland, so spice it up by showing the icon of the file next to the file name. Your table will look much cleaner after this little upgrade.

You need to replace the cell view in the first column with a new cell type that contains an image and a text field.

You’re in luck because Interface Builder has this type of cell built-in.

Select the Table Cell View in the Name column and delete it.

tableview-deletecell

Open the Object Library and drag and drop an Image & Text Table Cell View into either the first column of the table view or the View Controller Scene tree, just under the Name table view column.

tableview-dropcell

Now you’re whipping things into shape!

Assigning Identifiers

Every cell type needs an assigned identifier. Otherwise, you’ll be unable to create a cell view that corresponds to a specific column when you’re coding.

Select the cell view in the first column, and in the Identity Inspector change the Identifier to NameCellID.

tableview-identifier

Repeat the process for the cell views in the second and third columns, naming the identifiers DateCellID and SizeCellID respectively.

Populating the Table View

Note: There are two ways that you can populate a tableview—either using the datasource and delegate protocols you’ll see in this OS X NSTableView tutorial, or via Cocoa bindings. When you start a project ensure that you choose between the two approaches. We’ll have tutorials on the site in the future that cover using Cocoa Bindings

The table view currently knows nothing about the data you need to show or how to display it, but it does need to be looped in! So, you’ll implement these two protocols to provide that information:

  • NSTableViewDataSource: tells the table view how many rows it needs to represent.
  • NSTableViewDelegate: provides the view cell that will be displayed for a specific row and column.

population-diagram

The visualization process is a collaboration between the table view, delegate and data source:

  1. The table view calls the data source method numberOfRowsInTableView(_:) that returns the number of rows the table will display.
  2. The table view calls the delegate method tableView(_: viewForTableColumn:, row:) for every row and column. The delegate creates the view for that position, populates it with the appropriate data, and then returns it to the table view.

Both methods must be implemented in order to show your data in the table view.

Open the assistant editor and Control-drag from the table view onto ViewController class implementation to insert an outlet.

tableview-outlet-1

Make sure that the Type is NSTableView and the Connection is Outlet. Name the outlet tableView.

tableview-outlet-2

You can now refer to the table view in code using this outlet.

Implement the required data source method in the ViewController by adding this code at the end of ViewController.swift:

extension ViewController : NSTableViewDataSource {
  func numberOfRowsInTableView(tableView: NSTableView) -> Int {
    return directoryItems?.count ?? 0
  }
}

This creates an extension that conforms to the NSTableViewDataSource protocol and implements the required method numberOfRowsInTableView(_:) to return the number files in the directory, which is the size of the directoryItems array.

Now you need to implement the delegate. Add the following extension at the end of ViewController.swift:

extension ViewController : NSTableViewDelegate {
  func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {
 
    var image:NSImage?
    var text:String = ""
    var cellIdentifier: String = ""
 
    // 1
    guard let item = directoryItems?[row] else {
      return nil
    }
 
    // 2
    if tableColumn == tableView.tableColumns[0] {
      image = item.icon
      text = item.name
      cellIdentifier = "NameCellID"
    } else if tableColumn == tableView.tableColumns[1] {
      text = item.date.description
      cellIdentifier = "DateCellID"
    } else if tableColumn == tableView.tableColumns[2] {
      text = item.isFolder ? "--" : sizeFormatter.stringFromByteCount(item.size)
      cellIdentifier = "SizeCellID"
    }
 
    // 3
    if let cell = tableView.makeViewWithIdentifier(cellIdentifier, owner: nil) as? NSTableCellView {
      cell.textField?.stringValue = text
      cell.imageView?.image = image ?? nil
      return cell
    }
    return nil
  }
}

This code declares an extension that conforms to the NSTableViewDelegate protocol and implements the method tableView(_:viewForTableColumn:row). It’s then called by the table view for every row and column to get the appropriate cell.

There’s a lot going on the method, so here’s a step-by-step breakdown.

  1. If there is no data to display, it returns no cells.
  2. Based on the column where the cell will display (Name, Date or Size), it sets the cell identifier, text and image.
  3. It gets a cell view by calling makeViewWithIdentifier(_:owner). This method creates or reuses a cell with that identifier. Then it fills it with the information provided in the previous step and returns it.

Next up, add this code inside the viewDidLoad() method:

tableView.setDelegate(self)
tableView.setDataSource(self)

Here you tell the table view that its data source will be the view controller and that setDelegate(_:) and setDataSource(_:) will call its methods.

The last step is to tell the table view to refresh the data when a new directory is selected.

First, add this method to the ViewController implementation:

func reloadFileList() {
  directoryItems = directory?.contentsOrderedBy(sortOrder, ascending: sortAscending)
  tableView.reloadData()
}

This helper method refreshes the file list.

First, it calls the directory method contentsOrderedBy(_:ascending) and returns a sorted array with the directory files. Then it calls the table view method reloadData() to tell it to refresh.

Note that you only need to call this method when a new directory is selected.

Go to the representedObject observer didSet, and replace this line of code:

print("Represented object: \(url)")

With this:

directory = Directory(folderURL: url)
reloadFileList()

You’ve just created an instance of Directory pointing to the folder URL, and it calls the reloadFileList() method to refresh the table view data.

Build and run.

Open a folder using the menu File\Open File… or the Command+O keyboard shortcut and watch magic happen! Now the table is full of contents from the folder you just selected.

tableview-datapopulated

Nice job!

But nothing in life is ever that easy, right? Look carefully, because there is a peculiar thing going on with the cells. All the text is truncated, even when there is ample horizontal space.

End truncation. End it now!

That’s because view cells created by Interface Builder have no Auto Layout constraints by default, but you need them to make the cells adapt to the column width.

Adding Constraints to View Cells

Open Main.storyboard. Select the image view located inside the cell view for the Name column, and click on the Pin button to add the following three constraints:

  • Leading: 3
  • Height: 17
  • Width: 17

imageview-constraints

Keep the image selected and click the Align button in the Auto Layout toolbar. Add a Vertically in Container alignment constraint.

imageview-constraints2

Select the text field in this cell view, which is called Table View Cell and is an NSTextField Class type.

Screen Shot 2015-11-03 at 11.43.19 PM

Add the following constraints:

  • Leading: 7
  • Trailing: 3
  • Vertically in Container alignment constraint
textfield-name-constraint1 imageview-constraints2

Repeat this process for the text fields in the Modification Date and Size cells, adding the following constraints to these text fields:

  • Leading: 3
  • Trailing: 3
  • Vertically in Container alignment constraint.
textfield-name-constraint3 imageview-constraints2

Build, run and then select a folder.

build-run-autolayout

Now you can resize the columns and see that the text is not truncated where there is ample space. Awesome!

Table View Interaction

In this section, you’ll work with some interactions to improve the UI.

Responding to User Selection

When the user selects one or more files, the application should update the information in the bottom bar to show the total number of files in the folder and how many are selected.

In order to be notified then the selection changes in the table view, you need to implement the tableViewSelectionDidChange(_:) method in the delegate. This method will be called by the table view when it detects a change in the selection.

Add this code to the ViewController implementation:

func updateStatus() {
 
  let text:String
  // 1
  let itemsSelected = tableView.selectedRowIndexes.count
 
  // 2
  if ( directoryItems == nil ) {
    text = ""
  }
  else if( itemsSelected == 0 ) {
    text =   "\(directoryItems!.count) items"
  }
  else
  {
    text = "\(itemsSelected) of \(directoryItems!.count) selected"
  }
  // 3
  statusLabel.stringValue = text
}

This method updates the status label text based on the user selection.

  1. The table view property selectedRowIndexes contains the indexes of the selected rows. To know how many items are selected, it just gets the array count.
  2. Based on the number of items, this builds the informative text string.
  3. Sets the status label text.

Now, you just need to invoke this method when the user changes the table view selection. Add the following code inside the table view delegate extension:

func tableViewSelectionDidChange(notification: NSNotification) {
  updateStatus()
}

When the selection changes this method is called by the table view, and then it updates the status text.

Build and run.
build-run-selection

Try it out for yourself; select one or more files in the table view and watch the informative text change to reflect your selection.

Responding to Double-Click

In OS X, a double-click usually means the user has triggered an action and your program needs to perform it.

For instance, when you’re dealing with files you usually expect the double-clicked file to open in its default application and for a folder, you expect to see its content.

You’re going to implement double-click responses now.

Double-click notifications are not sent via the table view delegate, instead, they’re sent as an action to the table view target. But to receive those notifications in the view controller, you need to set the table view’s target and doubleAction properties.

Note: Target-action is a pattern used by most controls in Cocoa to notify events. If you’re not familiar with this pattern, you can learn about it in the Target-Action section of Apple’s Cocoa Application Competencies for OS X documentation.

Add the following code inside the viewDidLoad() method of the ViewController:

tableView.target = self
tableView.doubleAction = "tableViewDoubleClick:"

This tells the table view that the view controller will become the target for its actions, and then it sets the method that will be called after a double-click.

Add the tableViewDoubleClick(:) method implementation:

func tableViewDoubleClick(sender: AnyObject) {
 
  // 1
  guard tableView.selectedRow >= 0 , let item = directoryItems?[tableView.selectedRow] else {
    return
  }
 
  if item.isFolder {
    // 2 
    self.representedObject = item.url
  } else {
    // 3  
    NSWorkspace.sharedWorkspace().openURL(item.url)
  }
}

Here’s the above code broken out step-by-step:

  1. If the table view selection is empty, it does nothing and returns. Also note that a double-click on an empty area of the table view will result in an tableView.selectedRow value equal to -1.
  2. If it’s a folder, it sets the representedObject property to the item’s URL. Then the table view refreshes to show the contents of that folder.
  3. If the item is a file, it opens it in the default application by calling the NSWorkspace method openURL()

Build, run and check out your handiwork.

Double-click on any file and observe how it opens in the default application. Now choose a folder and watch how the table view refreshes and displays the content of that folder.

Whoa, wait, did you just create a DIY version of Finder? Sure looks that way!

Sorting Data

Everybody loves a good sort, and in this next section you’ll learn how to sort the table view based on the user’s selection.

One of the best features of a table is one- or two-click sorting by a specific column. One click will sort it in ascending order and a second click will sort in descending order.

Implementing this particular UI is easy because NSTableView packs most of the functionality right out of the box.

Sort descriptors are what you’ll use to handle this bit, and they simply instances of the NSSortDescriptor class that specify the desired attribute and sort order.

After setting up descriptors this is what happens: clicking on a column header in the table view will inform you, via delegate, which attribute should be used, and then the user will be able sort the data.

Once you set the sort descriptors, the table view provides all the UI to handle sorting, like clickable headers, arrows and notification of which sort descriptor was selected. However, it’s your responsibility to order the data based on that information, and refresh the table view to reflect the new order.

You’ll learn how to do that right now.

Woot!

Add the following code inside viewDidLoad() to create the sort descriptors:

// 1
let descriptorName = NSSortDescriptor(key: Directory.FileOrder.Name.rawValue, ascending: true)
let descriptorDate = NSSortDescriptor(key: Directory.FileOrder.Date.rawValue, ascending: true)
let descriptorSize = NSSortDescriptor(key: Directory.FileOrder.Size.rawValue, ascending: true)
 
// 2
tableView.tableColumns[0].sortDescriptorPrototype = descriptorName;
tableView.tableColumns[1].sortDescriptorPrototype = descriptorDate;
tableView.tableColumns[2].sortDescriptorPrototype = descriptorSize;

This is what this code does:

  1. Creates a sort descriptor for every column, complete with a key, e.g., Name, Date, Size, that indicates the attribute by which the file list can be ordered.
  2. Adds the sort descriptors to each column by setting its sortDescriptorPrototype property.

When the user clicks on any column header, the table view will call the data source method tableView(_:sortDescriptorsDidChange:oldDescriptors:), at which point the app should sort the data based on the supplied descriptor.

Add the following code to the data source extension:

func tableView(tableView: NSTableView, sortDescriptorsDidChange oldDescriptors: [NSSortDescriptor]) {
  // 1
  guard let sortDescriptor = tableView.sortDescriptors.first else {
    return
  }
  if let order = Directory.FileOrder(rawValue: sortDescriptor.key! ) {
    // 2
    sortOrder = order
    sortAscending = sortDescriptor.ascending
    reloadFileList()
  }
} reloadFileList()

This code does the following:

  1. Retrieves the first sort descriptor that corresponds to the column header clicked by the user.
  2. Assigns the sortOrder and sortAscending properties of the view controller, and then calls reloadFileList(). You set it up earlier to get a sorted array of files and tell the table view to reload the data.

Build and run.

build-run-sort

Click any header to see your table view sort data. Click again in the same header to alternate between ascending and descending order.

You’ve built a nice file viewer using a table view. Congratulations!

Where to Go From Here

You can download the completed project here.

This OS X NSTableView tutorial covered quite a bit, and you should now feel much more confident in your ability to use table views to organize data. In addition, you also covered:

  • The basics of table view construction, including the unique qualities of headers, rows, columns and cells
  • How to add columns to display more data
  • How to identify various components for later reference
  • How to load data in the table
  • How constraints and truncation are related
  • How to respond to various user interactions

There is a lot more you can do with table views to build elegant UI for your app. If you’re looking to learn more about it, consider the following resources:

If you have any questions or comments on this tutorial, feel free to join the discussion below in the forums! Thanks for joining me again!

The post OS X NSTableView Tutorial appeared first on Ray Wenderlich.

New Video Tutorial Series: Saving Data in iOS in Swift

$
0
0
Learn how to save data in iOS!

Learn how to save data in iOS!

Today, we are happy to announce that Brian Moakley has ported our popular Saving Data in iOS series from Objective-C to Swift.

From saving simple text files to using Core Data, iOS provides a variety of different options on persisting your data. This series explores all the various different savings methods and shows how you can start implementing them in your app.

This series is now fully up-to-date to Swift 2 and Xcode 7, and all 12 parts of the series are available today. You can check them out here:

Brian and I hope you enjoy this newly updated series – and thanks to everyone for subscribing! :]

The post New Video Tutorial Series: Saving Data in iOS in Swift appeared first on Ray Wenderlich.

Call for Applicants – Readers’ App Awards 2015!

$
0
0
Enter your app for our third annual Readers Apps Awards!

Enter your app for our third annual Readers Apps Awards!

This is just a quick note to let you know that our fourth annual Reader’s Apps Awards are coming up soon, where we recognize some of the best apps made by fellow raywenderlich.com readers.

And the best part is it’s not too late for you to enter your app in the competition! :]

We have a great set of judges lined up this year to look at all the entries:

readersappawards_2015_judges

Keep reading to learn more about the the categories, the prizes, and how to enter!

Categories and Prizes

To be eligible to win, you must be an active reader of this site and the tutorials or books must have helped you in some way to develop your app. Priority is given to subscribers, active forum members, and others we can verify are actual readers of this site.

Also, your app must have come out this year (in 2015), obviously.

Each app is eligible for every category but can only win one category. Ryan will be selecting the finalists for each category from ALL the submissions and then the judges will select the winners. :]

Grand Prize

  • Best Reader’s Game: Best game overall in terms of game play, polish, and graphics. Bonus points for GameCenter, tvOS support, etc.
  • Best Reader’s App: Best app overall in terms of usefulness, polish, and interface. Bonus points for Universal Binary, iCloud, platform advantage (taking advantage of iOS specific features), etc.

Honorable Mentions

  • Most Addicting: The App/Game that you can’t stop playing with.
  • Most Hilarious Idea: Its got that LoL factor :]
  • Most Surprisingly Good: The App/Game you didn’t think would be as good as it is at first glance.
  • Most Technically Impressive: The App/Game with particularly cool/impressive tech.
  • Most Visually Impressive: The App/Game that just looks really good!

All winners get a free PDF of their choice from our site – plus massive bragging rights! :]

How to Enter

If you want a chance at winning, here’s what you should do:

  • Eligibility requirements: Again, to be eligible to win, you must be an active reader of this site and the tutorials or books must have helped you in some way to develop your app. Priority is given to subscribers, active forum members, and others we can verify are actual readers of this site.
  • If you’ve ever submitted your app for review on the site in the past: You’re already in the running! You don’t need to do anything, Ryan remembers all! ;]
  • If you haven’t submitted your app yet this year: You can do so right here!

Note to be considered for this year’s Readers Apps Awards, you must submit your app before next Friday, December 11th. If you don’t make it, there’s always next year ;]

Best of luck to everyone, and stay tuned for the rewards announcements, which will be before Christmas! :]

The post Call for Applicants – Readers’ App Awards 2015! appeared first on Ray Wenderlich.

Video Tutorial: Monetizing Your App with iAd Part 1: Introduction to iAd


watchOS 2 by Tutorials Update Now Available!

$
0
0

watchOS 2 by Tutorials Now Available!

This is just a quick note to let you know we have released an update to watchOS 2 by Tutorials (version 1.2).

Here’s what’s new in this version of watchOS 2 by Tutorials:

  • Fixed an issue with chapter 7, Tables, caused by an outdated version of SwiftyJSON;
  • Fixed an issue with chapter 7, Tables, where outlets couldn’t be created because the Xcode project contained two controllers with the same name;
  • Fixed an issue with chapter 22, HealthKit, that affected the way the energy and distance samples were being added together for use in a workout’s total;
  • Fixed an issue with chapter 22, HealthKit, to help reduce the choppiness of the timer transitions.

Here’s how you can get the update:

  • If you’re a watchOS 2 by Tutorials PDF customer, you can download the update for free on your My Loot page (version 1.2).
  • If you haven’t picked up a copy of the watchOS 2 by Tutorials yet, grab your copy now.

The team and I hope you enjoy this update!

The post watchOS 2 by Tutorials Update Now Available! appeared first on Ray Wenderlich.

Staying Motivated as a Work From Home Developer

$
0
0

Do you work from home? That’s really cool! A lot of people would love to be in your position.

Working from home has its advantages, but there are certainly drawbacks as well. Staying motivated can be a big challenge for many people, due to the many distractions at home, a sense of isolation, and the lack of a boss who pops her head into your cubicle at the most inopportune times to keep you on your toes.

There’s no science to telecommuting; there’s no official list of do’s and don’ts. This article won’t teach you how to work from home, but it contains some common practices many home-based workers follow.

Some practices may apply to you, and some won’t; some of the practices that many avoid may actually work really well for you! What’s important is that you have to figure out and decide what’s best for you.

Without further ado, here is a list of some things the raywenderlich.com team and I have learned over the years about working effectively from home! :]

Note: Special thanks to the raywenderlich.com Tutorial Team members who shared their advice for this article: Ray Wenderlich, Kelvin Lau, Janie Clayton, Ray Fix, Derek Selander, Richard Turton, Mic Pringle, Aaron Douglas, Cesare Rocchi, Brian Moakley and Adrian Strahan.

Your Environment

You’re going to spend a lot of time in your working environment, so it makes good sense to put some thought into where you work.

Choosing Your Office

Even when working from home, you need a place which you can call your office. It doesn’t always have to be the same place, and there’s no rules as to what defines an office: it can be a dedicated room, a corner of the living room or a spot in the garage. However, many suggest that you define and reserve a certain area of your home as your office, and always use it as your primary working location.

Janie Clayton prefers to set aside a whole area of her house for work purposes only. That way her brain knows once she enters that area, it’s time to work. Adrian Strahan suggests that everybody in your house should know that when you’re in your office area, you’re at work and they should refrain from disturbing you as much as possible.

I have a dedicated room for an office, but I usually spend at least a couple hours out of every day working in the living room. If you want to break the monotony of spending a whole day in one room and you have a laptop, try moving to a different place on occasion – it can be another room, a chair with a nice view, a café or any other place where you can relax and still work.

02_dev_cafe

Creating Transitions

In a traditional office job, you transition to work mode when you leave your home and travel to the office. Cesare Rocchi suggests you create your own rites of passage, which can be anything that helps your brain recognize the transition; during the summer months, his approach is to water his plants.

Janie Clayton‘s transition pattern is brewing tea. Yours can be anything that works for you: turn the radio or TV on or off, open a certain window, close the office door, have a shower, or just head to your office and sit. Whatever you choose should be a pattern your brain can recognize as the beginning of your work session.

If you use a computer for leisure activities such as playing games or watching movies, it’s a good idea to avoid using your work computer for these activities and get a second computer – if you can afford it. Moving to a different computer could become part of your transition pattern. It might help eliminate those moments where you say to yourself: Why am I wasting my time playing Battlefield when I should be doing work?

Choosing Clothing

OK, it’s your home, and you have the right to dress however you like. Nonetheless, dressing for work might be a valuable part of your transition, along with taking a shower. Regardless of where you work, it’s probably best to smell fresh! :]

Personally, I rarely work in pyjamas, preferring to dress before turning on my Mac. I don’t go to the level of formal business attire, but I choose something I wouldn’t necessarily wear outside and something that I wouldn’t feel embarrassed to be caught in if unexpected guests showed up. This is probably the only ritual I rigorously follow in my own transition.

05_teleworking_with_kids

Fixed or Flexible Time?

There’s a lot of variation on the subject of working hours; on one side, you have fixed hours like you’d see in an office situation. On the other side, you have complete freedom of working hours – even the middle of the night if you so choose!

In many cases, working hours depend on your employer or client agreements, as they might require a particular window of availability window each day.

Mic Pringle prefers to have a structured routine with fixed working hours every day, just as if he was working in a traditional office. This particular approach greatly helps in the transition to work mode.

I set a predefined number of hours to work every day, and I let external events (mostly family-driven) change my work schedule as required. In the event my schedule is interrupted, I simply work into the evening until I reach my daily goal. If isn’t possible, I usually reserve part of the weekend to catch up the hours lost during the week.

True, that’s more of an anti-routine pattern, but I feel comfortable enough to stick with it until there’s a good reason for a change.

Many variables affect working hours:

  • Start time
  • End time
  • Number of hours
  • External events
  • Distractions
  • Family
  • Mood

The key point here is to prioritize each of these areas in a way that works for you. For me, it’s the number of hours, followed by family and external events. For you it could be start and end time, or start time and number of hours, or any other combination. If you have kids, you might need to give your family a higher priority and adjust your start and end times accordingly.

Managing Distractions

Managing distractions

Human and environmental distractions in a home office typically differ from those in a traditional office, but digital distractions are pretty much the same between the two: email, chat, Twitter, Facebook, and others can be real time sinks. The degree of distraction can be even higher for remote workers since no one’s looking over their shoulders to see what they’re up to.

I consider myself lucky because I’m a digital introvert; I seldom use Facebook, and I consider Twitter an invaluable work tool but I don’t let it take control of my time. Notifications of events can be checked out in only a few seconds, at the risk of temporarily losing contact with the task in front of me; however, badge counters that indicate the number of new tweets, Skype messages and unread emails I haven’t dealt with are like hammers knocking on my head! :]

If you find yourself frequently distracted, you should think about softening your notifications or disabling them outright. For temporary distraction-free mode, the easiest solution is to close all apps that generate digital interference; a simple reboot will re-enable them all.

Time management solutions, such as the pomodoro technique, can help you ignore distractions and give you a predefined time when you are free to process non-work-related items. No matter which time management solution you use, the trick is to focus on a specific task for a fixed period of time with regular, time-limited breaks. This helps improve focus and productivity.

There are tools you can install on your computer to monitor which apps you use and for how long; they provide reports that help you figure out how much of your time is spent on distracting or unproductive activities. I’ve recently installed RescueTime, and it’s already starting to reveal bad habits I should probably change.

Handling Environmental Noise

Environmental noise is a very subjective topic; some people need absolute silence to focus, whereas others, like me, consider silence itself too “noisy” and disturbing. But how do you fill the silence without the noise becoming distracting? There’s the standard background music approach, but the following solutions work for many people as well:

  • Radio
  • Podcast
  • Television
  • Monotone sound generator
  • Iterative or minimalistic music
  • Environmental noise

A friend of mine prefers a hair dryer, of all things; its monotonic sound, combined with the air flow directed toward his face, helps to isolate his mind from the surrounding world.

If music is too invasive, you might find ambient sound generators an excellent alternative. They can make you feel like you’re in a café, or other public places that have a constant but soft murmur in the background. A good one to try is Coffitivity with different background crowd noises to choose from.

Whatever your habit or preference is, be sure your place of work is conducive to and accepting of the background noise you choose!

01_dev_home

Your Work Style

Just as there are multiple ways to manage your work environment, there are many ways to manage your work tasks as well.

Tracking Tasks and Time

When I’m in work mode, I always track my time, regardless of what I am doing. That helps me to understand how I spend my time, and what the ratio is between the time spent doing project work and the time spent doing other tasks such as reading emails, learning, reading blogs and catching up on accounting or invoicing tasks. There are several tools to simplify or automate time tracking; the one I use is Toggl.

Ray Fix creates a work log every hour, detailing what he did in that time interval.

Ray Wenderlich suggests keeping a time log notebook. When you begin a task, write down the time, such as “10:00”. When you finish the task and are ready to begin a new one, write down the end time and what you did. Your line will now read like “10:00-10:30 – Added feature X”. Try logging everything you do, including email reading, work breaks, or any other task you perform. You’ll find that it has two benefits:

  • You’ll find physically recording your time improves your focus on a task.
  • You can look back on your time later and see where your time is spent in a day.

Learning

For developers, learning how to solve a problem is sometimes seen as more important than learning about the problem. Staying up-to-date with recent trends, patterns, and other updates in the development sphere is not just important to your personal growth; the quality of the work you turn out depends on it. It’s also beneficial to keep an eye on other current technologies, even if they don’t appear to be directly related to your work.

Anything you learn, even if you don’t find the subject matter enthralling, contributes to your knowledge. Learning what you don’t like has a purpose as well: it helps you appreciate what you do like! :]

Finally, continuous learning means you’re investing in yourself. It’s in your best interest to make yourself future-proof.

Motivating Yourself

Motivation can be a big challenge when working from home. Sometimes the acquired virtual freedom and flexibility isn’t enough to stay motivated, for work-related reasons, such as lack of work, or personal reasons such as issues going on in your life. There’s probably no recipe to stay motivated that works for everybody.

If you’re like me, you might find your motivation in having fun with what you’re doing. There’s nothing else I’d rather do than write code; I can easily see myself doing this for the next 1, 5 or 10 years.

Learning is another motivation for me; sometimes it’s directly related to the work I’m doing, and other times it isn’t.

Ray Fix thinks creating artificial deadlines or demoing your project to a friend or a group can work as a deterrent against the lack of motivation. Rewarding yourself with treats for staying on task can also be beneficial.

For Ray Wenderlich, external motivations can help stay focused. Perhaps you can visit a co-working spot where you can discuss your work with other like-minded workers. You could publicly post your deadlines for your projects to help you stay accountable. Or you could put up a calendar on the wall, and mark off each day you make progress. There are lots of ways to put external checks in place to ensure you keep the momentum going.

Kelvin Lau finds inspiration in Malcolm Gladwell’s 10,000 hour rule. He states that to gain mastery in any field, one must attain roughly 10,000 hours of experience. Kevin has set this as one of his core goals as a programmer: to program in Swift and Cocoa for 10,000 hours.

So even if he’s dealing with an irritating bug, Kelvin knows every minute spent on it goes towards the 10,000 hour goal. It really helps counter the idea of “wasting time”, since all Swift and Cocoa tasks count towards the 10,000 hours. As long as he’s doing something related to programming in Swift, there’s no notion of wasted time in his mind. That includes watching videos, reading tutorials and contributing to StackOverflow.

Setting achievable goals shouldn’t be underestimated, in Brian Moakley‘s opinion. Having unrealistic goals won’t help you stay motivated, particularly if you already think you’re going to fail. Ray‘s suggestion is to do the smallest possible step.

If you’re feeling overwhelmed by a project, it’s probably because you’re looking at the final goal, which can feel so far away. The step can even be as small as opening Xcode! Break down your tasks into the smallest steps possible, and rest assured that as long as you make incremental progress, you’ll eventually finish your task.

Lack of motivation can also be caused by competition. Cesare Rocchi recommends avoiding comparing yourself to others, or comparing yourself with somebody in the same rank. If you have family and/or kids, you can’t compare yourself to a 20-year-old whiz kid living in Silicon Valley; she’s likely to accomplish more work, or have more exposure and opportunities than you would in the same time frame.

Such a comparison is easy to make, especially when you work on competing products in the same digital space. It’s an unfair comparison, it’s likely to make you feel frantic, and it will suck your “motivation juice” dry.

Note: For more on the pitfalls of comparison, check out Ray’s AltConf talk on the subject – and learn a funny story about Ray’s past!

Staying Flexible

Staying flexible

In absence of external constraints, working from home frequently means that you’re the Commander-in-Chief of your work place and master of your domain…as long as your spouse or partner isn’t around, that is! :]

Having control over your work environment doesn’t necessarily mean all rules go out the window. Whether they are strict or permissive, you should have a set of rules and stick to them. It can take time to build such a list, as rules come with experience, and they can change and evolve over time.

As you might guess, there are no “good” or “bad” rules; it’s really about rules that work for you. If you feel a structured routine works best for you, go for it. If you feel like being flexible, make that the order of the day.

I believe flexibility is one of the most important rules. As I mentioned above, external events, mood and inspiration define my schedule and drive the priority and timeline of my tasks, although hard limits like deadlines can affect how flexible I can be.

Some ideas that can help you be more flexible are:

  • When you can’t solve a problem, switch context. If you work on two or more projects, change to another project. You can also read some blogs, or watch a video such as one from the last WWDC. When you return to the problem, the solution quite often magically presents itself to you, and you’ll wonder why you didn’t see it in the first place!
  • Don’t force yourself to work if you realize you aren’t making progress. Take a longer break, and do something else non-work-related: meet up with a friend, watch a movie, play a game, or choose something to distract yourself.
  • Change up your working hours; some people are more productive late at night when their mind wanders and is more creative. Some people prefer the quiet focus of the early-morning hours.
  • If you feel you need a nap during your work day, and it doesn’t interfere with your work, just do it! Many creative and productive people make naps a part of their daily routine.
  • If you can’t take a break from work, switch up your environment: work in a bar or pub, move into another room or even outside, turn the TV on if it doesn’t distract you, or take another short break such as a quick walk.
  • Do you need to keep an eye on your kids while you work? If it doesn’t interfere with your work schedule, take a break and spend some time with them; you’ll enjoy it, and they’ll appreciate your attention. You can always do some extra work in your off-hours to catch up.

Communicating Effectively

Meetings – they are typically labeled as boring and a waste of time. Fortunately, remote workers live in a digital world, so most meetings aren’t attended in-person. However, even meetings over Skype or Hangouts can be a time sink, particularly if they recur every day and take a substantial amount of time. There are lots of ways to communicate outside of meetings that generally fall into one of two categories:

  • Synchronous (phone, voice chat, video conferencing)
  • Asynchronous (instant messaging, mail, collaborating tools)

You don’t have to stick with just one tool; you can use the best tool at hand to communicate effectively. For interactive discussions, use voice or video. For non-urgent questions, use email. If it’s an urgent question with a simple answer, use instant messaging.

Asynchronous messaging lets you stay on task while communicating simple questions and directions; this translates into better use of your time.

Your Health

Every person assumes their health is something they’ll have their entire life – until they don’t have it anymore. Below are some great ideas to help maintain your physical and mental health.

Staying Physically Active

As developers, we spend a lot of time glued to a chair, staring at a monitor. Since home-based workers don’t need to commute, catch buses or traverse flights of stairs to get to the subway, it’s easy to spend most of the day without moving too much.

04_dev_treadmill

Sitting all day is a bad habit of the modern age. Bodies need to move; extended sitting can lead to serious health problems. Fortunately, it’s easy to stave off these health issues by following a few simple rules:

  • When you go out, avoid elevators and use the stairs instead.
  • Spend some time walking during the day.
  • Do some running regularly, or get involved in other sports or physical activities.
  • Use a standing desk, moving or dancing frequently while you work.
  • Go the distance and adopt a a treadmill desk; Aaron Douglas wrote an excellent blog post on that subject.

Whenever you notice your body or brain asking for a break, listen to it. Your body is pretty smart! :]

Interacting with Others

Working from home can be isolating if you’re not careful, but luckily there are some solutions for that.

Derek Selander recommends making sure you go outside, or finding a group on Meetup.com to force yourself to socialize in person.

Similarly, Brian Moakley suggests you meet up with like-minded people in your area. Face-to-face time with other humans is equally as important as any work you do.

Kelvin Lau shares that sentiment: take time to interact with other developers. It really helps you cement your knowledge and broaden your mind.

I agree with them all. Don’t you?

03_dev_island

But what if there aren’t any meetups in your area? Take the initiative and start your own.

If there aren’t enough developers in your main area of interest to justify a meetup, then make it less restrictive: if you’re an iOS developer, create a meetup open to all mobile developers, or all developers in general. The cross-talk between people working with different technologies can be a terribly interesting opportunity for learning.

Where to Go From Here?

I consider working from home a privilege, but it does have its disadvantages. There’s no universal set of rules to maximize your productivity and minimize the impact on your personal life; guidelines for working from home are highly subject to individual preferences and your personal situation.

As a basic framework, when working from home you should do the following:

  • Find your own time model: fixed or flexible, or somewhere in-between.
  • Find your own working pace: focused periods of work with frequent breaks.
  • Find your own rules: whether flexible or more structured, rules and routines help you work more efficiently.

You are a unique professional, and as such, only you know what’s best for you. Your rules don’t have to be – and shouldn’t be – the same as mine or anyone else’s.

I encourage you to share your experience. Let us know what problems you’ve faced and how you’ve solved them in the comments below!

The post Staying Motivated as a Work From Home Developer appeared first on Ray Wenderlich.

Swift Apprentice Update Now Available!

$
0
0

Swift Apprentice Now Available!

This is just a quick note to let you know we have released an update to the Swift Apprentice (version 1.2).

Here’s what’s new in this version of the Swift Apprentice:

  • Bug fixes: Thanks to our eagle-eyed editors and readers, we managed to squash a variety of typos and syntax errors. In some places, we tidied and tightened up some of the language to make the explanations more clear and concise. If you find any errors in this edition, please let us know on the forums!
  • Mini-exercise solutions: As always in our books, we like including challenges at the end of chapters to give you a chance to try what you just learned. In the Swift Apprentice, we also included mini-exercises throughout the chapter: quick questions to test your knowledge. In this update, you’ll find full solutions to the mini-exercises in addition to the challenge solutions that were included in the first release.

Here’s how you can get the update:

  • If you’re a Swift Apprentice PDF customer, you can download the update for free on your My Loot page (version 1.2).
  • If you haven’t picked up a copy of the the Swift Apprentice yet, grab your copy now.

The team and I hope you enjoy this update!

The post Swift Apprentice Update Now Available! appeared first on Ray Wenderlich.

Introduction to Open Source Swift on Linux

$
0
0

Introduction to Open Source Swift on Linux

Less than a week ago, the Swift world woke up to an early Christmas present — open source Swift — that you can run on Linux!

And there was even a present inside the present: Apple announced new projects and tools intended to make Swift an incredibly practical choice for Linux development. This creates exciting possibilities, such as running Swift on platforms from Linux servers right down to five-dollar Raspberry Pi Zeros, or in the kajillions of other environments that host Linux.

In this tutorial, you’ll set up a Linux environment on your Mac, install Swift, and compile and run some basic Swift examples on Linux. Then you’ll take stock of the new bits offered by Apple, and finish off with a look into into the misty crystal ball of time, and guess what this all means for the future.

This tutorial does not require any previous knowledge of Linux and you don’t even need Linux installed yet – but if you also have Ubuntu running, all the better! All you need is a Mac running at least OS X El Capitan and an interest in open source Swift. Let’s get started!

Installing Swift on Linux

If you’re already running Ubuntu 14.04 LTS or Ubuntu 15.10, either directly or in a VM on Mac or Windows, you can simply follow the instructions on swift.org to download and install Swift for Linux and skip to the next section.

If you’re not running one of the above versions of Ubuntu, follow the instructions below to install Virtualbox and Ubuntu on your Mac. This will use less than 1 GB of disk space and confine Linux to a virtual machine — without affecting your current OS X installation.

Installing VirtualBox

VirtualBox is a free, open-source application that lets you run other operating systems as virtual machines in parallel with OS X.

Go to the VirtualBox downloads page, and download the disk image for VirtualBox 5.0.10 or later. Double-click the downloaded DMG and run the VirtualBox.pkg package installer:

swift-on-linux.VirtualBoxdDiskImage

Installing and Using Vagrant

Vagrant is a command-line interface to VirtualBox; it can download virtual machine images for you, run provisioning scripts, and coordinate the interaction between OS X and the machine by setting up things like networking and shared folders.

Go to the Vagrant downloads page and download Vagrant for Mac OS X. Double-click the downloaded DMG disk image and run the Vagrant.pkg package installer:

swift-on-linux.VagrantDiskImage

Now you’ll need a Vagrantfile to tell Vagrant exactly which version of Linux you want to use and how to install Swift on that version of Linux.

Create an empty directory in your Documents folder (or wherever makes sense for your workflow) and name it vagrant-swift. Inside that directory, create a file named Vagrantfile and add to it the lines below:

Vagrant.configure(2) do |config|
  ## 1
  config.vm.box = "https://cloud-images.ubuntu.com/vagrant/trusty/20151201/trusty-server-cloudimg-amd64-vagrant-disk1.box"
 
config.vm.provision "shell", inline: <<-SHELL
    ## 2
    sudo apt-get --assume-yes install clang
    ## 3
    curl -O https://swift.org/builds/ubuntu1404/swift-2.2-SNAPSHOT-2015-12-01-b/swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu14.04.tar.gz
    ## 4
    tar zxf swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu14.04.tar.gz
    ## 5
    echo "export PATH=/home/vagrant/swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu14.04/usr/bin:\"${PATH}\"" >> .profile
    echo "Swift has successfully installed on Linux"
  SHELL
end

Now to run your Vagrantfile. Open Terminal on your Mac (found in the /Applications/Utilities folder), change to the vagrant-swift directory that contains the Vagrant file above, then enter the following command to run your script:

vagrant up

Sit back and wait while Vagrant performs the following steps based on your Vagrantfile:

  1. Downloads a disk image of Ubuntu LTS 14.04 (as published by Canonical, the Ubuntu company, on December 1, 2015). It will only perform this download once and then cache the image for later use. You will likely see an “Attempting to find and install…” message for the Box file, followed by a message about “Adding it directly…”.
  2. Runs the downloaded disk image in virtualization.
  3. Installs clang, Apple’s C compiler, which has components the Swift compiler requires.
  4. Downloads Swift (as distributed by swift.org on December 1st, 2015) and uncompresses it.
  5. Configures the default user’s home PATH variable, so it can run the swift binary, REPL, and other tools.

If this completes successfully, the final message will say that “Swift has successfully installed on Linux”.

Next, you’ll need to connect to your Linux virtual machine. In the same vagrant-swift directory, execute the following command:

vagrant ssh

You should now find yourself at an Ubuntu prompt as a user called “vagrant”. To verify that you can access Swift and it’s functioning properly, execute the following command:

swift --version

You should see something like the following:

vagrant@vagrant-ubuntu-trusty-64:~$ swift --version
Swift version 2.2-dev (LLVM 46be9ff861, Clang 4deb154edc, Swift 778f82939c)

Tada! Swift on Linux. It’s a Christmas miracle! :]

We're pretty sure Tiny Tim would have appreciated open source Swift.

We’re pretty sure Tiny Tim would have appreciated open source Swift.

Compiling a Program

You’ve installed Swift on Linux. Now it’s time to compile and run something.

Of course, hallowed coding tradition dictates that your first program do nothing but say “Hello, world”. And in true developer form, you’ll do it the easiest way possible. :]

Switch to the Linux shell prompt and execute the following command:

cat > helloworld.swift

Now enter the following single line of Swift code:

print("Hello, world")

Press Enter once followed by Ctrl-D to create the file:

Execute ls in the shell to show the directory listing and confirm that you have created a file named helloworld.swift.

Now execute the following command at the shell prompt to invoke the swift compiler and compile your program:

swiftc helloworld.swift

Execute ls -l h* at the shell prompt to see detailed information on all files beginning with h:

-rwxrwxr-x 1 vagrant vagrant 13684 Dec  4 17:55 helloworld
-rw-rw-r-- 1 vagrant vagrant    22 Dec  4 17:55 helloworld.swift

helloworld has x’s in the first column as it’s an executable file. Execute the following command to run helloworld:

./helloworld

You’ll see the following output:

Hello, world

Lightning and thunderbolts! You’ve run Swift on Linux. So easy! :]

But what does this all mean? What can you really do with Swift on Linux? To answer these questions, put the brakes on this runaway freight train of cross-platform, bleeding-edge and technological euphoria, and take a moment to review what it is that Apple has actually released.

What Apple Has Released

Apple has released five categories of software to date:

1) The Swift compiler (source code and executable binaries), debugger, and interactive prompt (i.e., REPL).

This is the heart of the Swift language itself. Apple has released the source code for the the Swift compiler, the same swiftc program that Xcode uses to compile Swift for iOS and Mac apps.

2) The Swift standard library

This is (almost) exactly the same standard library that’s been used since Swift’s release. It defines strings, collection types, protocols, and other fundamental constructs. Have you been yearning to see how the standard library implements a basic type, like Double or Array? Now you can.

But of course, the Swift standard library alone doesn’t get you very far. How many Swift applications have you written where you don’t import UIKit? Probably not very many. The functionality of Foundation, at a minimum, is indispensable for writing useful software (instead of, you know, “Hello, world”, or the five-millionth example of the factorial function). All of this makes it very promising that Apple has also released …

3) Swift Core Libraries

These are brand new, cross-platform, Objective-C-free re-implementations of existing Apple libraries. They provide higher-level functionality such as networking, file system interaction, date and time calculation. A caveat: they’re not quite finished. But that’s not all. Apple has also released …

4) Swift Package Manager

The Swift package manager is a bit like Carthage; it can download dependencies, compile them, and link them together to create libraries and executables.

5) Other Components

If you browse Apple’s Github page, you can find other components as well: a Swift wrapper for libdispatch (aka, Grand Central Dispatch), notes on the future plans for Swift 3.0, even a parser/renderer for the Markdown dialect CommonMark.

What Apple Hasn’t Released

That’s quite a pile of functionality — but what hasn’t Apple released?

Well, there’s no Xcode, no AppKit and no UIKit. There’s no Core Graphics, no Core Animation, no AVFoundation, nor many of the other familiar core Objective-C libraries. Basically, most of what you need to create beautiful iOS or Mac apps isn’t here yet.

But what Apple has released is quite significant. Consider the Core Libraries project. Why did Apple take the trouble of re-implementing its own mature, battle-tested Foundation libraries?

The fact that the Core Libraries project doesn’t rely on the Objective-C runtime suggests that Apple is creating the underpinnings for Swift to replace Objective-C completely in the long run. And the fact that it’s cross-platform by design suggests Apple is seriously hoping people will use the language for Linux software development — at least for server software, if not for GUI apps.

But the package manager is most significant of all. Before diving into the reasons why, take a quick kick at the tires and see what it does.

Using the Swift Package Manager

The package manager defines a simple, common-sense directory structure for any Swift code that you would like to build into an executable or library. You’ll look at that format using your VirtualBox install of Ubuntu and Vagrant.

First, execute the following command at the shell prompt to create a directory helloworld-project and dive into it:

mkdir helloworld-project && cd helloworld-project

Now execute the following to to create an empty file named Package.swift:

touch Package.swift

The presence of this file indicates that the current directory defines a Swift package.

Now create a directory for source code files with the following command:

mkdir Sources

Next, execute the following to copy your old program, helloworld.swift, into Sources/ with the new name main.swift:

cp ../helloworld.swift Sources/main.swift

The directory structure of helloworld-project now defines the most basic package possible, and should look as follows:

.
├── Package.swift
└── Sources/
    └── main.swift

Execute the following command to build the package:

swift build

You should see the following:

vagrant@vagrant-ubuntu-trusty-64:~/helloworld-project$ swift build
Compiling Swift Module 'helloworldproject' (1 sources)
Linking Executable:  .build/debug/helloworld-project

This creates a new, hidden folder for build products — .build. Your directory structure should now look like the following:

.
├── .build/
│   └── debug/
│       ├── helloworld-project*
│       ├── helloworld-project.o/
│       │   ├── build.db
│       │   ├── helloworld-project/
│       │   │   ├── main.d
│       │   │   ├── main~partial.swiftdoc
│       │   │   ├── main~partial.swiftmodule
│       │   │   ├── main.swiftdeps
│       │   │   ├── master.swiftdeps
│       │   │   └── output-file-map.json
│       │   ├── home/
│       │   │   └── vagrant/
│       │   │       └── helloworld-project/
│       │   │           └── .build/
│       │   │               └── debug/
│       │   ├── llbuild.yaml
│       │   └── Sources/
│       │       └── main.swift.o
│       ├── helloworldproject.swiftdoc
│       └── helloworldproject.swiftmodule
├── Package.swift
└── Sources/
    └── main.swift

You can verify this hidden folder structure by executing ls -aR.

The most important file here is .build/debug/helloworld-project, which is marked with an asterisk above to indicate that it’s executable. This is your executable, which you can run now just by entering it’s name on the command line, like so:

vagrant@vagrant-ubuntu-trusty-64:~/helloworld-project$ .build/debug/helloworld-project
Hello, world

Cool. But what’s all that other gunk in the directories used for?

All of those intermediate build products are indications of the true scope of the package manager’s functionality. Remember — it’s more than just a compiler. In its capacity as a build tool (like make), the package manager is responsible for compiling multiple files required for a single package and linking them together.

In its capacity as a package manager (like Carthage or CocoaPods), it also has the responsibility of linking together multiple packages and fetching dependent packages on the Internet. This implies the package needs some concept of versioning and compatibility (e.g, “Which dependency can meet my needs?”), and of location (e.g., “Where do I get it?”).

For a less-trivial example, take a look at Apple’s own sample project; it’s an app that simulates the dealing of a deck of cards.

Install Git, change to a new directory, and get the top-level package with the following shell commands:

cd ~
sudo apt-get --assume-yes install git
git clone https://github.com/apple/example-package-dealer.git
cd example-package-dealer

Crack open the Apple project and have a look; you’ll see it includes almost nothing:

.
├── CONTRIBUTING.md
├── main.swift
├── Package.swift
└── README.md

However, Package.swift is not empty this time; it includes a small snippet of Swift that declares this package depends on version 1 of another package, example-package-deckofplayingcards, which in turn lives at a URL on github, and that package in turn depends on others, and so on.

The net result is that if you call swift build for the example project, you’ll get more than 400 files, as the build tool downloads those other package repositories, compiles them, and links them together.

Apple provides more details on the package manager on the new Swift.org website. Below is a quick list of notable points about the new package manager:

  • Uses a simple directory structure for package layout and a simple Swift-based manifest file, as opposed to Xcode, which allows any directory structure, but requires a proprietary Xcode project file to track the freeform chaos this implies.
  • Uses semantic versioning, the defacto standard for declaring package versioning and compatibility information
  • Is tightly integrated with Swift’s notion of a module, which Apple uses for Objective-C and has promoted as a standard for C.
  • Overlaps with some of xcodebuild’s functionality.
  • Performs transitive dependency analysis, but doesn’t yet handle dependency conflicts.
  • Builds executable and static libraries, but doesn’t yet handle dynamic libraries.
  • Uses git, but has no support for other version control system yet.
  • Includes a very thoughtful community proposal document, which describing the thinking behind its design.

If you’ve used CocoaPods, Carthage, or other package managers, this will all seem quite familiar. And indeed, technically, it is nothing new. But it is new to Apple, and this is notable. So let us gaze into the mists of time and ask …

What Does All This Mean?

Why does a package manager matter so much? It’s because a package manager is more than just a tool. Package managers tend to be inextricably tied to the technical community surrounding a software ecosystem, since they define how people interact with each other in the fundamental business of helping each other to make software.

Would the Ruby or Node communities be the same without the gem and npm package managers? No. And it’s no exaggeration to say that CocoaPods has brought iOS developers closer together by making it easier to share work and help each other.

Apple has a bit of a reputation for communicating to developers; it’s not known for supporting channels for feedback from developers or encouraging developer interaction. A good example of this is the Radar bug tracking system, which functions like an interplanetary black hole, silently gobbling up information, and leaving behind no trace visible from the external universe.

But a package manager is inevitably a piece of community infrastructure; it’s something other developers will use to interact with each other, not with Apple. So it’s a bit of a departure for Apple to take the lead in promoting such a tool.

It’s also a good sign that the tool looks and feels like a normal package manager that uses semantic versioning, Git, and other conventional tools and patterns which originated outside of Apple. Apple’s even replaced Radar with a new bug tracking system for Swift based on JIRA, which allows developers to actually view known bugs. And there’s also a long document that solicits contributions from the open source community and establishes a process and a community code of conduct.

It really feels like the Swift team has rolled out the welcome mat! I imagine it as an eerily opalescent welcome mat, with hairline grey trim, which magically hovers exactly one centimer above the ground so it never gets dirty. Others may see it differently. :]

Welcome to Swift Open Source!

The package manager feels like a sign of the broader spirit behind this open source release. With this open source release, Apple hasn’t just thrown a bunch of code “over the wall”. Apple’s taken the first steps toward supporting production uses of Swift on Linux. And more than that, they’ve made big steps toward encouraging and welcoming others to help with this effort.

Exiting the Virtual Machine

When you’re done with your virtual machine, just use logout to exit the shell, and call vagrant suspend to freeze it for later use, or vagrant destroy to blow it away completely and free up the disk space.

Where to Go From Here?

In this tutorial, you’ve installed Linux, installed Swift on Linux, compiled code using Swift on Linux, and taken a quick look at Apple’s package management tool. The fact that you can now run Swift on Linux is incredibly interesting, but the fact that Apple seems to be actually encouraging it, and providing technical and community support for it, is awesome! :]

You’ve only had a really quick look at Swift on Linux, but a lot of the new tooling such as the package manager has consequences for Swift on OS X as well; it’s now easier to share code and to build command line tools. It’s hard to imagine this doesn’t at least hint of new directions in Xcode. The new repositories, the exposure of the roadmap and discussion process for future Swift development are promising — and surprising — developments.

There are interesting days to come!

What are your thoughts on this new paradigm for Swift development? Share your thoughts with us below!

The post Introduction to Open Source Swift on Linux appeared first on Ray Wenderlich.

RWDevCon Student Scholarships: Applications Now Available!

$
0
0

RWDevCon Scholarship

Many of us on the tutorial team started programming early in life, so we’re always happy to do all we can to encourage students to get into programing at a young age.

Today, we are happy to announce some exciting news – we are offering 5 student scholarships for RWDevCon 2016!

The 5 lucky students will win a free ticket to the conference and will get to attend our team-only pre-conference fun day.

Attending RWDevCon 2016 is an amazing opportunity for students – through two days packed full of high quality hands-on tutorials, you’ll bring your iOS development skills up-to-date, learn a ton, and have a blast.

Keep reading to find out who’s eligible, how to apply, and who to thank for this great opportunity!

Eligibility and How To Apply

To be eligible to win, there are three requirements:

  • You must be born on or after March 12, 1995 (i.e. you’re 21 years or younger when the conference ends; this is primarily intended for high school or early college students).
  • You also must be able to attend the conference and the pre-conference fun day (March 10-12, 2016).
  • You must be able to pay for your own travel and hotel expenses (they are not included; the scholarship includes a ticket to the conference and an invitation to the team-only pre-conference fun day only).

To apply, simply:

  • Write a tutorial related to iOS or Swift Language development, and post it to your own blog. If you don’t have a blog, I recommend you post it on Medium.
  • Then send us an email with a link to your tutorial, a scanned ID that shows your birthday on it, and confirm that you meet the three requirements listed above.

We will choose the authors of the 5 best tutorials as winners, based on writing skills, technical skills, and the “cool factor” of the subject of the tutorial.

Entries are due in a little over a month – January 11, 2016 – so get writing! :]

Introducing the Patrons

The RWDevCon 2016 scholarships are sponsored by 5 generous patrons of the iOS community, who bought a special ticket that included the cost of the student tickets. Along with me, these patrons will be judging the applicants for the scholarships.

I asked each of our patrons to write some advice for students studying programming. Here’s what they had to say:

Steve Daly, Software Developer

SteveDaly

“When writing a program, it helps if you act as if the program is going to eventually be read, modified or maintained by somebody else. This makes it easier for you if you need to revisit the code after being away from it for a long time.”

Larry Ketchersid, CEO of Media Sourcery, Inc; owner of JoSara MeDia

LarryKetchersid

“You’ll learn more working with others than in isolation. Learning from someone is great, but also try teaching someone what you’ve learned; whether the subject is programming, cooking, martial arts or anything, you’ll find that you truly understand a topic when you attempt to explain it to someone else, and hear their questions on what you are trying to convey. It’s also a great way to give back to the programming community.”

Kevin Legg, Co-Owner of Five Pack Creative

KevinLegg

“Work on things you are passionate about and don’t forget to have fun. Do good things even when not required and you will go far.”

Carey McLean, Innovation Software Engineer

CareyMcLean

“When you start learning to program, the task may seem impossible. Just remember, the word itself says I’m possible! Make a plan to learn, develop and execute. You’ll be amazed at what you can accomplish. :-)”

Walter Tyree – Computer Whisperer

WalterTyree

“The best part about learning programming is that the basic concepts are mostly unchanged for years but; there are always new things being invented. Every few months, you have the opportunity to become the world’s leading expert in something.”

Where To Go From Here?

If you, or a student you know, wants to take advantage of an amazing learning opportunity that will pay some major dividends in life, don’t miss this chance!

Start writing your tutorial now, and send it to us along with a scanned ID and a confirmation that you meet the 3 requirements by January 11, 2016.

We wish the best of luck to all of the applicants, and we look forward to seeing you at RWDevCon 2016!

Note: Don’t have an RWDevCon 2016 ticket yet? You should think about getting yours soon – there are currently less than 20 tickets left!

The post RWDevCon Student Scholarships: Applications Now Available! appeared first on Ray Wenderlich.

Viewing all 4370 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>