Sublime Text 2 - Package Control installed but the list not shown

I am using Sublime Text 2 for Mac. I have installed the Package Control for Sublime Text 2, following the instructions from&nbsp;<a href="https://sublime.wbond.net/installation#st2" target="_blank">https://sublime.wbond.net/installation#st2</a>&nbsp;without any trouble. However, when I open up&nbsp;<code>Ctrl</code>+<code>Shif</code>+<code>P&nbsp;</code>to search for available packages, it does not show any.

I am using Sublime Text 2 for Mac. I have installed the Package Control for Sublime Text 2, following the instructions from https://sublime.wbond.net/installation#st2 without any trouble. However, when I open up Ctrl+Shif+to search for available packages, it does not show any.

See the image screenshot here

Do you have any solutions for it? I try restart Sublime but it doesn't solve the problem.

Getting Started with macOS Programming

Getting Started with macOS Programming

Let’s go together to build our first macOS application!

Dear readers, let me welcome you and start by saying that this tutorial is the beginning of a new journey and new explorations, as it’s the first of a series of tutorials on a new topic: macOS programming!

Developing for macOS and creating desktop applications is a wonderful process if you want to go down that road. If you are coming from an iOS background like me, then you will find exciting and challenging at the same time to be able to make apps for both systems. What makes it even better is one simple fact: There are lots of common things between iOS and macOS programming. Several frameworks and SDKs, the language itself (Swift), even the coding style that one has used to remain almost the same. But macOS programming is not meant for people being iOS developers already. New programmers who have started learning Swift and they want to make their own desktop applications can follow along as well!

Starting from this tutorial we are going to meet and learn key concepts on macOS programming. I am planning to present various topics for which I will highlight their most important concepts and I will show techniques, how-to and best practices. It is obvious that it would take a series of books to cover everything about macOS programming, not just a series of tutorials. However, what I’m going to show you starting from this tutorial and onwards not only will get you started, but it will enable you to build full applications and it will put you on the right track so you know how to look further on topics you are interested in. Whenever possible, we will be going through the making process of a new macOS app that will have some usefulness at the end. Something that you can take with you when finish reading each post.

So, once again welcome to a new exciting journey! Let’s go together to build our first macOS application!

Our Roadmap

In this post we are going to see the basics of a macOS app through the creation of a simple, but at the same time useful for many developers app: A font viewer that will let us choose font families and it will be displaying the PostScript names of the available fonts. Clarifying why this is useful: The PostScript name is the font name we write in code when creating a NSFont object. Usually it’s not the same to the font’s file name, and without knowing the PostScript it’s impossible to create font objects in code or to add custom fonts into projects. There’s a manual process to reveal PostScript names as described here, but why not to have a macOS app that will let us get it instantly?

Our menu today contains a lot of key stuff:

  • How to create a new macOS project.
  • What the most important parts of the generated project are.
  • What is a window controller and how to configure its contained window, including size, position, title, and a lot more.
  • How to add graphical controls into a view controller.
  • How to interact with those graphical controls, update their values and react on actions triggered by them.
  • How to create additional window controllers.
  • How to change a window’s appearance so it looks like a utility or auxiliary panel.
  • How to load and present and close a window programmatically.

There are even more things to discuss in this post in addition to those listed above. We will talk about new classes that will be proved extremely valuable for our cause, we will talk about the custom logic that we will implement in the various parts of the app, and we will see small or big details that will produce at the end a complete project.

Here is what you are going to have in your hands by the time you will leave here:

Creating Your First Mac App

Launch Xcode, and then choose to create a new project:

In the first step of the guide that appears next do the following:

  • How to create a new macOS project.
  • What the most important parts of the generated project are.
  • What is a window controller and how to configure its contained window, including size, position, title, and a lot more.
  • How to add graphical controls into a view controller.
  • How to interact with those graphical controls, update their values and react on actions triggered by them.
  • How to create additional window controllers.
  • How to change a window’s appearance so it looks like a utility or auxiliary panel.
  • How to load and present and close a window programmatically.

Once you do so, it’s time to “baptise” the project and set all the rest initial information. Since we’re going to create our custom font viewer, why not to call it just like that, Font Viewer? Set that as the value to the Product Name field, and configure the other properties such as Team, Organization Name, Organization Identifier. Generally, make sure that your window looks like the next one:

Finally, choose a place to save the project on your disk, and finish with the creation process.

Running The App

While having Font Viewer project open in Xcode, press Cmd + R on your keyboard to run the app. Here’s what you’ll see appearing on your screen:

Congratulations! You just ran your first macOS app!

It’s an empty window for now, but it doesn’t matter as we will change that. Look and play around with it. You will notice that standard behaviour and attributes are assigned by default to the window, such as resizing, moving or going full screen. Also, there’s the main menu at the top bar, where some common functionalities are provided already, while some others are just disabled as they don’t trigger any action.

Exploring The Project

If you have prior experience to iOS development, you will find out that a macOS project looks pretty much the same to an iOS project. Project Navigator lists all files and groups, tabs like General, Capabilities, Build Settings, etc are here too, and generally everything looks familiar. Displayed settings and options are specific to macOS though.

In the Project Navigator you will find all files and groups that Xcode creates by default for a Cocoa App. What is new here (comparing again to iOS projects), is an .entitlements file. This is a property list file that contains rights an app is granted with. Most of the times there is no need to edit it manually. Changes made through the Capabilities tab update this file automatically.

Other than that, two code files are created automatically. AppDelegate.swift and ViewController.swift. We will add more code to ViewController.swift in a while. There is also:

  • How to create a new macOS project.
  • What the most important parts of the generated project are.
  • What is a window controller and how to configure its contained window, including size, position, title, and a lot more.
  • How to add graphical controls into a view controller.
  • How to interact with those graphical controls, update their values and react on actions triggered by them.
  • How to create additional window controllers.
  • How to change a window’s appearance so it looks like a utility or auxiliary panel.
  • How to load and present and close a window programmatically.

Looking at the General tab of the Font Viewer target, in the Identity section you can find the Bundle Identifier, as well as the Version and Build Number. But what is more interesting here, is the Application Category popup, where you can find all available app categories also found on App Store. This is the place where we set the category of our app. Which category would be suitable for us here? We could assign it under Developer Tools since it’s going to display font information, but we could also have it in the Utilities category. Right now it doesn’t really matter as we are not going to publish it, but remember to choose a category for your app before you send it to the App Store (it’s still okay if you don’t, you can choose app category on the App Store as well, but why not to do it here?).

Looking a bit lower you will see the Deployment Info section. Here you specify the minimum macOS version required by your app to run. You can have it run on macOS Mojave only (10.14), or enable it running on High Sierra (10.13) or older versions too. Keep that option in mind if you ever want to support older operating systems.

Take your time to go through every aspect of the project. Switch to the Capabilities tab, and see what kind of options are available, or go to Build Settings and see if you find something interesting there too. Once you finish your exploration, let’s take a few moments to see what Main.storybard file contains.

Exploring The Main.storyboard

Clicking on the Main storyboard file in the Project Navigator, the automatically created, default user interface will be revealed in Interface Builder. Any Cocoa based app contains three default scenes:

  • How to create a new macOS project.
  • What the most important parts of the generated project are.
  • What is a window controller and how to configure its contained window, including size, position, title, and a lot more.
  • How to add graphical controls into a view controller.
  • How to interact with those graphical controls, update their values and react on actions triggered by them.
  • How to create additional window controllers.
  • How to change a window’s appearance so it looks like a utility or auxiliary panel.
  • How to load and present and close a window programmatically.

Let’s focus on some interesting details now. Click on the window in the window controller scene, and open Attributes Inspector in the inspectors panel of Xcode. This is what you should be seeing:

For some of them, just enabling or disabling options has immediate visual effect on the window. For some others it has not. Let me highlight the most important ones, but if you find yourself needing information for options not mentioned below, feel free to search for them on the web.

  • How to create a new macOS project.
  • What the most important parts of the generated project are.
  • What is a window controller and how to configure its contained window, including size, position, title, and a lot more.
  • How to add graphical controls into a view controller.
  • How to interact with those graphical controls, update their values and react on actions triggered by them.
  • How to create additional window controllers.
  • How to change a window’s appearance so it looks like a utility or auxiliary panel.
  • How to load and present and close a window programmatically.

Leaving the rest options to their default settings makes sure that a window fits to the general macOS environment and it follows workflows that users are already familiar with. Of course, you can find additional information about them and their purpose if you wish so, I just highlighted the most important ones here.

With the window still being selected, show the Size Inspector. Here, you can set the content size of the window, the allowed maximum and minimum size, as well as the initial place of the window on screen.

Setting the content size (width and height) makes the obvious, it changes the window’s default content size. By leaving the Minimum Content Size and Maximum Content Size unchecked, users can resize the window and make it as small or as big they want. To limit the minimum content size so users cannot decrease it further than that, just enable the Minimum Content Size checkbox and specify values for the min width and height. Similarly, enable the Maximum Content Size checkbox to prevent your window grow more than the values you specify.

To keep a constant content size and disallow resizing, then set the exact same values to both minimum and maximum content size.

By default a window is displayed to the bottom left side of the screen. You can change that by either dragging the window sample in the small screen preview window, or just change the initial position X and Y values. Just remember: coordinates in macOS are not like iOS. The Y=0 point is the bottom side of the screen, not the top.

Windows can also be shown centered on the screen. To do that, click on the Proportional Horizontal and Proportional Vertical popup buttons, and select Center Horizontally and Center Vertically respectively. The screen sample in the Size inspector will be updated, and you can verify that by running the app; the window will be shown on the center of the screen.

Setting Up The UI

After that quick walkthrough to the macOS project, let’s do some real work on our app. For starters, select the default Window and open the Size Inspector in the inspectors panel. Change the Content Size to 370×250. Then, select the view controller’s view and do the same.

Now let’s add the graphical controls to the default view of the view controller.

Begin by clicking on the Library Button on Xcode to open the Objects Library:

In the Objects Library, type popup in the top search field:

Choose the Pop Up Button item, and drag and drop it to the view controller’s view. Select the popup control you just dragged to the view controller, and press Cmd + D on your keyboard to duplicate it.

Select both popup buttons, and add the following constraints: Top: 20, Leading: 20, Trailing: 20, Height: 21.

Following the above steps, let’s add also a push button and a label:

  1. Open the Objects Library again, and type button.
  2. Drag and drop a push button to view controller’s view below the popups.
  3. Set its constraints: Trailing: 20, Bottom: 20, Width: 120, Height: 21.
  4. Double click on the button to change its title to: Display All
  5. Open the Objects Library one last time, and type label in the search field.
  6. Drag and drop a label object into the view controller, under the popups but above the push button.
  7. Set the following constraints for the label: Top: 20, Leading: 20, Trailing: 20, Height: 80.

At the end, your view should be similar to this one:

The first popup button will be displaying all available font families on the system, while the second will contain all available font types (such as bold, italic, etc) for any selected font family in the first popup.

Label will show the PostScript name of the selected font family and type, formatted accordingly.

Lastly, the “Display All” button will be used to show all available font types of a font family at once. More about that later.

IBOutlet Properties And IBAction Methods

We will come to the need to interact with the controls we just added soon, so it’s necessary to create and connect IBOutlet properties and IBAction methods to them. Open the ViewController.swift file, and to the top of the class add the next IBOutlet property declarations:

@IBOutlet weak var fontFamiliesPopup: NSPopUpButton!
&nbsp;
@IBOutlet weak var fontTypesPopup: NSPopUpButton!
&nbsp;
@IBOutlet weak var sampleLabel: NSTextField!

Also, define the following IBAction methods:

@IBAction func handleFontFamilySelection(_ sender: Any) {
&nbsp;
}
&nbsp;
&nbsp;
@IBAction func handleFontTypeSelection(_ sender: Any) {
&nbsp;
}
&nbsp;
&nbsp;
@IBAction func displayAllFonts(_ sender: Any) {
&nbsp;
}

Back to the Main.storyboard file, select the view controller object in the document outline:

In the inspectors panel, select to open the Connections inspector, where you will find all the IBOutlet properties and IBAction methods previously declared. Make the connections as follows:

  • How to create a new macOS project.
  • What the most important parts of the generated project are.
  • What is a window controller and how to configure its contained window, including size, position, title, and a lot more.
  • How to add graphical controls into a view controller.
  • How to interact with those graphical controls, update their values and react on actions triggered by them.
  • How to create additional window controllers.
  • How to change a window’s appearance so it looks like a utility or auxiliary panel.
  • How to load and present and close a window programmatically.

Before we make the simple user interface we just created usable, let’s take a look at the controls we just added. By default, each popup button contains three items, where each one is a menu item (more about menus and menu items in a future post). These can be changed either by double clicking on the popup button and then by double clicking on each item, or by selecting the popup button and spotting each item to the Document Outline.

In this demo application, we will change the menu items programmatically, but Interface Builder is a good option to do that if you have a constant set of items that are not meant to be changed on the fly.

Note: Popup button items can be always updated programmatically regardless of whether an initial set of real items has been set through Interface Builder.

In the Attributes inspector you can find all configurable properties of the popup button (after selecting one). For example, you can define the default selected item, or to set font properties and text alignment.

Similarly, label’s and button’s properties can be changed in the Attributes inspector too if you select the label or button object in the view controller. Feel free to look around and experiment a bit by changing any properties you want. It doesn’t matter if you “damage” any control by accident; just delete it and create a new one by following the steps described above.

Another interesting point is the object hierarchy and the actual contained objects in the Document Outline pane. One would expect to find there only the popup buttons, the label and the push button along with their constraints. However, if you start expanding the objects tree you will notice that there are more objects than those we specifically added. Apart from the menu items of the popups (which is fine to be found there since a menu item is actually another Cocoa control created automatically), you will also find a cell object going in pair with each control. For example, the fontFamiliesPopup is a NSPopUpButton object, but it contains a NSPopUpButtonCell item which in turn contains the menu items. Likewise, the label which is a NSTextField object contains a NSTextFieldCell item.

So, what is the purpose of those “Cell” objects?

Generally speaking, a cell object (any “…Cell” subclass) is responsible for implementing the actual Cocoa control and its functionalities. All those subclasses inherit from the same ancestor, NSCell, which implements several common properties and methods regarding the appearance and behaviour of controls. Even though we will be interacting with the popup buttons, the label and the push button objects directly in this app, behind the scenes any visual changes and updates will be handled by the matching cell subclasses.

Practically speaking now, we don’t have to worry about them as we won’t have to deal with any cell subclass. Just one general warning: make sure to connect IBOutlet properties to the actual controls and not their cell counterparts. It’s a common mistake that can happen if you perform the outlet connection by pressing Control and drag-and-dropping from Interface Builder to the Assistant Editor (code) and you don’t pay attention to what the origin (source) object of the dragging is.

Bringing App To Life

Building the UI, even a simple one, is an achievement. But without code, not much can happen.

Initial Configuration

Open the ViewController.swift file, where we’ll get started by implementing a function in the ViewController class that will perform some initial setup to the UI.

Go after the default view controller methods and add the following:

func setupUI() {
&nbsp;&nbsp;&nbsp;&nbsp;fontFamiliesPopup.removeAllItems()
&nbsp;&nbsp;&nbsp;&nbsp;fontTypesPopup.removeAllItems()
&nbsp;&nbsp;&nbsp;&nbsp;sampleLabel.stringValue = ""
&nbsp;&nbsp;&nbsp;&nbsp;sampleLabel.alignment = .center
}

In the first two lines we remove all default items from the two popup buttons. In the other two lines we empty the default text of the label, and we center it. Notice that the property to set the label’s text is stringValue; don’t look for a property called text or something like that.

Next step is to populate the first popup button with actual values: All font families existing in the Mac. We will achieve that by getting to know a new class called NSFontManager. It is responsible for several things including the Font panel and Font menu found in many apps, keeping record of the currently selected font, triggering font changes, and more. Among its “duties”, important information about available font families and font attributes is also included!

NSFontManager is used through a shared instance programmatically. A property named availableFontFamilies can give us what we need: A collection (array) with all the available font families!

Right next we define a new method that uses the NSFontManager class and adds the found family names as items to the fontFamiliesPopup:

func populateFontFamilies() {
&nbsp;&nbsp;&nbsp;&nbsp;fontFamiliesPopup.removeAllItems()
&nbsp;&nbsp;&nbsp;&nbsp;fontFamiliesPopup.addItems(withTitles: NSFontManager.shared.availableFontFamilies)
}
&nbsp;

Now, both of methods we implemented above have to be called once the app is started, and before the view gets appeared. Go right after the viewDidLoad() method and add the following:

override func viewWillAppear() {
&nbsp;&nbsp;&nbsp;&nbsp;super.viewWillAppear()
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;setupUI()
&nbsp;&nbsp;&nbsp;&nbsp;populateFontFamilies()
}

6

7

override func viewWillAppear() {

    super.viewWillAppear()

 

    setupUI()

    populateFontFamilies()

}

 

Let’s see what we’ve done so far. Run the app and open the first popup, you will find all available font families in it!

Handling Actions

NSFontManager class seems to be quite useful, as there are more interesting properties and methods to explore and use. One such method that is particularly interesting is called availableMembers(ofFontFamily:). It returns an array where each item is another array ([[Any]]) with four distinct values:

  1. Open the Objects Library again, and type button.
  2. Drag and drop a push button to view controller’s view below the popups.
  3. Set its constraints: Trailing: 20, Bottom: 20, Width: 120, Height: 21.
  4. Double click on the button to change its title to: Display All
  5. Open the Objects Library one last time, and type label in the search field.
  6. Drag and drop a label object into the view controller, under the popups but above the push button.
  7. Set the following constraints for the label: Top: 20, Leading: 20, Trailing: 20, Height: 80.

An item-array is called a member of the font family. The following example taken from Apple Documentation illustrates what availableMembers(ofFontFamily:) returns:

(("Times-Roman", "Roman", 5, 4),
("Times-Italic", "Italic", 6, 5),
("Times-Bold", "Bold", 9, 2),
("Times-BoldItalic", "Bold Italic", 9, 3)
)

Putting the above in different words, with *availableMembers(ofFontFamily:)* we can get all font variations that a font family supports, and display them on the *fontTypesPopup* popup button.

Before we make the actual use of the above method, let’s declare the following two properties to the ViewController class, they’ll become handy a bit later:

var selectedFontFamily: String?
&nbsp;
var fontFamilyMembers = [[Any]]()

What we need to do now is to make it possible to keep the selected font family and get its contained members every time the fontFamiliesPopup selection gets changed. This must be done in the handleFontFamilySelection(_:) IBAction method:

@IBAction func handleFontFamilySelection(_ sender: Any) {
&nbsp;&nbsp;&nbsp;&nbsp;if let fontFamily = fontFamiliesPopup.titleOfSelectedItem {
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selectedFontFamily = fontFamily
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if let members = NSFontManager.shared.availableMembers(ofFontFamily: fontFamily) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fontFamilyMembers.removeAll()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fontFamilyMembers = members
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
}
&nbsp;

At first, we get the title of the item that gets selected in the fontFamiliesPopup; it matches to the font family name. We keep it in the selectedFontFamily property.

Next, we get all available members of the selected font family using the availableMembers(ofFontFamily:) method of the NSFontManager class. Those members are kept in the fontFamilyMembers class property. It’s important to remove any previous items existing in that array! We don’t want data from a previously selected font family to remain while we are selecting another one! That’s why removeAll() is called prior to assigning members to fontFamilyMembers.

However, just keeping the selected font family name and its members makes no real difference. We need to populate them to the fontTypesPopup so we see and use the font variations of each family. Why don’t we create a new method to do that? Add the next one to the ViewController class:

func updateFontTypesPopup() {
&nbsp;&nbsp;&nbsp;&nbsp;fontTypesPopup.removeAllItems()
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;for member in fontFamilyMembers {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if let fontType = member[1] as? String {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fontTypesPopup.addItem(withTitle: fontType)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
}

Here is what is going on in the above method:

  1. Open the Objects Library again, and type button.
  2. Drag and drop a push button to view controller’s view below the popups.
  3. Set its constraints: Trailing: 20, Bottom: 20, Width: 120, Height: 21.
  4. Double click on the button to change its title to: Display All
  5. Open the Objects Library one last time, and type label in the search field.
  6. Drag and drop a label object into the view controller, under the popups but above the push button.
  7. Set the following constraints for the label: Top: 20, Leading: 20, Trailing: 20, Height: 80.

You might want to run the app now and see the available font variations after having selected a font family first. Do it, and soon enough you will end up to an unpleasant result: The fontTypesPopup does not get any value at all! But why?

Well, the previous method does, indeed, populate the available members of a font family to the fontFamiliesPopup, but where exactly is it called? Nowhere yet!

Back to the handleFontFamilySelection(_:) IBAction method, which should be updated so it calls the updateFontTypesPopup() when the available members have been retrieved using the availableMembers(ofFontFamily:) method:

@IBAction func handleFontFamilySelection(_ sender: Any) {
&nbsp;&nbsp;&nbsp;&nbsp;if let fontFamily = fontFamiliesPopup.titleOfSelectedItem {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selectedFontFamily = fontFamily
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if let members = NSFontManager.shared.availableMembers(ofFontFamily: fontFamily) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// ...
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;updateFontTypesPopup()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
}

Great, now you can run the app, select a font family, and then see the available members in the second popup!

So far so good, but we still have some more distance to run and get to finish line. When selecting a font member from the second popup, an actual sample should be shown in the sampleLabel label. We can make that happen if we update the font of the sample label every time a font variation is selected. And here is a new thing: How can we create a font (a NSFont object) using the data we have so far?

NSFontManager will be our tool again, as it provides a method named font(withFamily:traits:weight:size:) that returns a NSFont object. If you think about it, we have values for all parameters, as traits and weight are parts of the font member data that we keep in the fontFamilyMembers collection. Also, the selected font family is also kept to the selectedFontFamily property. Regarding size, we’ll set a random value, it doesn’t really matter.

In the handleFontTypeSelection(_:) IBAction method we are going to implement all the logic that will allow the creation of a new font object, which in turn we will set to the sample label along with the PostScript name of the font.

@IBAction func handleFontTypeSelection(_ sender: Any) {
&nbsp;&nbsp;&nbsp;&nbsp;let selectedMember = fontFamilyMembers[fontTypesPopup.indexOfSelectedItem]
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;if let postscriptName = selectedMember[0] as? String, let weight = selectedMember[2] as? Int, let traits = selectedMember[3] as? UInt, let fontfamily = selectedFontFamily {
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let font = NSFontManager.shared.font(withFamily: fontfamily,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; traits: NSFontTraitMask(rawValue: traits),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; weight: weight,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size: 19.0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sampleLabel.font = font
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sampleLabel.stringValue = postscriptName
&nbsp;&nbsp;&nbsp;&nbsp;}
}

  1. Open the Objects Library again, and type button.
  2. Drag and drop a push button to view controller’s view below the popups.
  3. Set its constraints: Trailing: 20, Bottom: 20, Width: 120, Height: 21.
  4. Double click on the button to change its title to: Display All
  5. Open the Objects Library one last time, and type label in the search field.
  6. Drag and drop a label object into the view controller, under the popups but above the push button.
  7. Set the following constraints for the label: Top: 20, Leading: 20, Trailing: 20, Height: 80.

Run the app again, and this time you will have both a sample of the selected font, and its PostScript name too!

An Eye To The Details

Our small app is working, but there are a few details left untouched. Let’s go through them.

Regarding the first one, it’s obvious that there is no font sample when the app starts. Moreover, no font members are contained in the fontTypesPopup popup button until we update the selected font family. To get around that, we will go back to one of the first methods created here, the populateFontFamilies(). In it we must make a call to the handleFontFamilySelection(_:) IBAction method and trigger that way the gathering of the font family’s available members:

func populateFontFamilies() {
&nbsp;&nbsp;&nbsp;&nbsp;// ...
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;handleFontFamilySelection(self)
}

 This fixes the missing values on the second popup when the app starts, but it doesn’t fix the missing font sample. To make the sample label show the font sample of the first member found in the fontTypesPopup popup button automatically, we need to update the updateFontTypesPopup() method as shown in the next snippet:

func updateFontTypesPopup() {
&nbsp;&nbsp;&nbsp;&nbsp;// ...
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;fontTypesPopup.selectItem(at: 0)&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;handleFontTypeSelection(self)
}

First, we auto-select the first item in the popup. Then, we call the handleFontTypeSelection(_:) IBAction method to create the font based on the selected member and update the sample label.

Lastly, one more detail that will show us a general technique beyond the demo app specifics…

Updating The Window title

Our app’s window title is saying “Window” (unless you changed that in Interface Builder), but wouldn’t be nice to make it show the selected font family’s name?

Accessing the window programmatically is easy and it’s done through the view property (main view) of the view controller as you will see right next. Go to the handleFontFamilySelection(_:) IBAction method and add the following line:

@IBAction func handleFontFamilySelection(_ sender: Any) {
&nbsp;&nbsp;&nbsp;&nbsp;if let fontFamily = fontFamiliesPopup.titleOfSelectedItem {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// ...
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;view.window?.title = fontFamily
&nbsp;&nbsp;&nbsp;&nbsp;}
}

The window now displays the selected font family!

Completing The App With A New Window Controller

Our small application is working perfectly at this point and all steps presented so far have already shown some important how-to stuff regarding macOS programming. However, the “Display All” push button is not functioning yet, and this is the part that we will focus on here. This will give us the chance to explore and talk about more things that will make this post more complete and valuable.

The purpose of the “Display All” push button is to present a new window where font variations of a selected font family will be displayed all together, formatted based on each font’s PostScript name. That might not sound such a big deal given that we can already see them one by one through the popup buttons we have. By doing that though, we will learn:

  • How to create a new macOS project.
  • What the most important parts of the generated project are.
  • What is a window controller and how to configure its contained window, including size, position, title, and a lot more.
  • How to add graphical controls into a view controller.
  • How to interact with those graphical controls, update their values and react on actions triggered by them.
  • How to create additional window controllers.
  • How to change a window’s appearance so it looks like a utility or auxiliary panel.
  • How to load and present and close a window programmatically.

So, if all that sound interesting to you, just keep reading.

Adding A New Window Controller

Back to Main.storyboard file, let’s add a new window controller along with a view controller to our canvas.

Note: Additional window controllers are not required to exist in the Main.storyboard file. You can create new storyboard files to host them. Here we will have them all into the Main storyboard so we keep things simple.

  • How to create a new macOS project.
  • What the most important parts of the generated project are.
  • What is a window controller and how to configure its contained window, including size, position, title, and a lot more.
  • How to add graphical controls into a view controller.
  • How to interact with those graphical controls, update their values and react on actions triggered by them.
  • How to create additional window controllers.
  • How to change a window’s appearance so it looks like a utility or auxiliary panel.
  • How to load and present and close a window programmatically.

You will notice that along with the window controller, an attached view controller is added as well!

What Kind Of Panel Do You Prefer?

Now, let’s see how we can change the default appearance so we can make our new window look like an auxiliary panel.

At first, click on the new window and then show the Identity Inspector. Look at the Custom Class section, where the window’s class is automatically set to NSWindow.

Click on that field, type: NSPanel and hit the Return key on your keyboard.

And now, switch to the Attributes Inspector. A new section has been added to the top, named Panel! The default value in the Style popup is Regular Panel, which means the normal window appearance. Two more panel types are supported:

  • How to create a new macOS project.
  • What the most important parts of the generated project are.
  • What is a window controller and how to configure its contained window, including size, position, title, and a lot more.
  • How to add graphical controls into a view controller.
  • How to interact with those graphical controls, update their values and react on actions triggered by them.
  • How to create additional window controllers.
  • How to change a window’s appearance so it looks like a utility or auxiliary panel.
  • How to load and present and close a window programmatically.

Both of them are meant to exist as auxiliary windows that contain supplementary options or information to the content shown on the main window.

Change the panel style and go through all options; see how the window’s appearance is being changed accordingly. A HUD panel is similar to a Utility panel, with the obvious graphical difference. It’s darker and translucent. Also, only the close button is available on the window’s bar.

Once you finish examining panel style settings, choose HUD as the style for our new window.

You are encouraged to read the Human Interface Guidelines about panels here.

While still being in the Attributes Inspector, set the “Fonts Display” text (without the quotes) as the window’s title.

One last thing before we move to the next step. Show the Identity inspector and in the Identifier text field under the Identity section type the value: fontsDisplayStoryboardID. You will see in a while why we need that.

The Fonts Display View Controller

Along with the window controller, a new view controller was added too to the project. That brings us to the need to create a new NSViewController subclass that we will connect to that new view controller. Press Cmd + N in your keyboard, and select Cocoa Class under the Source section.

Click Next, and change the Subclass of: field to NSViewController. In the Class field, type FontsDisplayViewController. Get finished with the creation of the new file.

Again to the Main.storyboard file, click on the View Controller object, and set the FontsDisplayViewController value to the Class field in the Identity Inspector.

Next, click on the main view of the view controller, and show the Size Inspector. Set its size to 480×400.

Let’s add two new Cocoa controls now to the view.

  1. Open the Objects Library again, and type button.
  2. Drag and drop a push button to view controller’s view below the popups.
  3. Set its constraints: Trailing: 20, Bottom: 20, Width: 120, Height: 21.
  4. Double click on the button to change its title to: Display All
  5. Open the Objects Library one last time, and type label in the search field.
  6. Drag and drop a label object into the view controller, under the popups but above the push button.
  7. Set the following constraints for the label: Top: 20, Leading: 20, Trailing: 20, Height: 80.

We will use the textview to display all available font members of a font family formatted. The button will be used to close the window.

Note: Adding a button to close the window is not really necessary, as the panel itself provides a close button. However, we are doing that here clearly for learning reasons; to see how we can close a window programmatically.

In the FontsDisplayViewController.swift file now, let’s declare an IBOutlet property for the textview, and an IBAction method for the button:

@IBOutlet var fontsTextView: NSTextView!
&nbsp;
@IBAction func closeWindow(_ sender: Any) {
&nbsp;
}

Finally, in the Main.storyboard file again, click to select the Fonts Display View Controller object and from the Connections Inspector connect the fontsTextView outlet to the textview, and the closeWindow(_:) action to the button.

There is one disturbing thing in the UI we are being creating, and that is the white textview on the dark and translucent HUD window. That’s okay and tolerable in the storyboard, however who would want it when using the app?

So, open the FontsDisplayViewController.swift file and add the following function:

func setupTextView() {
&nbsp;&nbsp;&nbsp;&nbsp;fontsTextView.backgroundColor = NSColor(white: 1.0, alpha: 0.0)
&nbsp;&nbsp;&nbsp;&nbsp;fontsTextView.enclosingScrollView?.backgroundColor = NSColor(white: 1.0, alpha: 0.0)
&nbsp;&nbsp;&nbsp;&nbsp;fontsTextView.isEditable = false
&nbsp;&nbsp;&nbsp;&nbsp;fontsTextView.enclosingScrollView?.autohidesScrollers = true
}
&nbsp;

The above:

  • How to create a new macOS project.
  • What the most important parts of the generated project are.
  • What is a window controller and how to configure its contained window, including size, position, title, and a lot more.
  • How to add graphical controls into a view controller.
  • How to interact with those graphical controls, update their values and react on actions triggered by them.
  • How to create additional window controllers.
  • How to change a window’s appearance so it looks like a utility or auxiliary panel.
  • How to load and present and close a window programmatically.

We will call setupTextView() right before the view gets appeared:

override func viewWillAppear() {
&nbsp;&nbsp;&nbsp;&nbsp;super.viewWillAppear()
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;setupTextView()
}

Loading And Presenting The Window Controller

The UI of the auxiliary panel is ready, so let’s see how it looks like when the application is running. Before we load and present the new window controller, we must declare the following two properties in the FontsDisplayViewController.swift file:

var fontFamily: String?
var fontFamilyMembers = [[Any]]()

We need both of them, as we are going to pass the selected font family name and its members from the ViewController class to FontsDisplayViewController. We’ll see how we’ll make use of them in a while. Just declaring them for now is good enough.

So, let’s proceed to the presentation of the new window controller. Open the ViewController.swift file, and go to the displayAllFonts(_:) IBAction method. Remember that this action method is connected to the “Display All” button in the default window of our app, so any code added here will be executed when that button is clicked.

The idea behind presenting a window controller that has been created graphically in a storyboard file, is to initialize a **NSStoryboard** object and ask it to instantiate that window controller. A NSStoryboard object is being initialized by providing the storyboard name, but in a not-so-much straightforward way. Here it is:

let storyboardName = NSStoryboard.Name(stringLiteral: "Main")
let storyboard = NSStoryboard(name: storyboardName, bundle: nil)

As you can see, the NSStoryboard initializer does not accept a string value as an argument (aka the storyboard name). It expects for a NSStoryboard.Name value instead, where Name is String type alias. Value of bundle can be left nil.

With the storyboard object being initialized now, we can instantiate our window controller. For that purpose we will use the storyboard Identifier we had previously set in Interface Builder:

let storyboardID = NSStoryboard.SceneIdentifier(stringLiteral: "fontsDisplayStoryboardID")
&nbsp;
if let fontsDisplayWindowController = storyboard.instantiateController(withIdentifier: storyboardID) as? NSWindowController {
&nbsp;
}

instantiateController(withIdentifier:) is the method of the NSStoryboard class that instantiates the window controller in the above code. It returns an Any? value, so it is necessary to:

  • How to create a new macOS project.
  • What the most important parts of the generated project are.
  • What is a window controller and how to configure its contained window, including size, position, title, and a lot more.
  • How to add graphical controls into a view controller.
  • How to interact with those graphical controls, update their values and react on actions triggered by them.
  • How to create additional window controllers.
  • How to change a window’s appearance so it looks like a utility or auxiliary panel.
  • How to load and present and close a window programmatically.

Note: Apart from window controllers, it is also possible to instantiate view controllers using the *instantiateController(withIdentifier:)* method, as long as a storyboard Identifier has been set for them in Interface Builder. That’s why that method returns an *Any* value instead of a *NSWindowController* object. It’s our duty to cast to the proper type.

Also, in the above snippet you see that the window controller’s identifier is not given as a plain String value. Instead, a NSStoryboard.SceneIdentifier value must be provided, where SceneIdentifier is a String type alias.

Supposedly at this point the new window controller has been instantiated. That’s not enough though, we must access its content view controller, and pass the selected font family and its members collection to it. NSWindowController has a property named contentViewController which represents the view controller attached to the window controller. We will use it, and after having accessed it we will pass the values we want:

if let fontsDisplayVC = fontsDisplayWindowController.contentViewController as? FontsDisplayViewController {
&nbsp;&nbsp;&nbsp;&nbsp;fontsDisplayVC.fontFamily = selectedFontFamily
&nbsp;&nbsp;&nbsp;&nbsp;fontsDisplayVC.fontFamilyMembers = fontFamilyMembers
}

Finally, we can present the window as follows:

fontsDisplayWindowController.showWindow(nil)

The above are the steps required to instantiate a window controller programmatically, to get its content view controller, and eventually present them all. Right next is the displayAllFonts(_:) method in one piece:

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@IBAction func displayAllFonts(_ sender: Any) {
&nbsp;&nbsp;&nbsp;&nbsp;let storyboardName = NSStoryboard.Name(stringLiteral: "Main")
&nbsp;&nbsp;&nbsp;&nbsp;let storyboard = NSStoryboard(name: storyboardName, bundle: nil)
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;let storyboardID = NSStoryboard.SceneIdentifier(stringLiteral: "fontsDisplayStoryboardID")
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;if let fontsDisplayWindowController = storyboard.instantiateController(withIdentifier: storyboardID) as? NSWindowController {
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if let fontsDisplayVC = fontsDisplayWindowController.contentViewController as? FontsDisplayViewController {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fontsDisplayVC.fontFamily = selectedFontFamily
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fontsDisplayVC.fontFamilyMembers = fontFamilyMembers
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fontsDisplayWindowController.showWindow(nil)
&nbsp;&nbsp;&nbsp;&nbsp;}
}

Now you can run the app and click on the “Display All” button. There will be no content yet, however you will have your first HUD panel!

Displaying Fonts

What we are going to achieve in this part is to display all font variations contained in a selected font family one after another in the textview. More precisely, the font PostScript names. Furthermore, each displayed font variation is going to be formatted according to the font it represents.

We will achieve that by creating an attributed string that will contain all PostScript names separated by the newline character “\n”, and by adding new font attributes for each displayed line. At the end, that attributed string will be assigned to the textview.

Let’s get started by creating a new method in the FontsDisplayViewController class. We’ll name it showFonts(), and the first thing we’ll do is to make sure that the font family name exists.

func showFonts() {
&nbsp;&nbsp;&nbsp;&nbsp;guard let fontFamily = fontFamily else { return }&nbsp;&nbsp;&nbsp;&nbsp;
}
&nbsp;

Remember that fontFamily is supposed to get its value when the “Display All” push button is clicked on the main window of the app.

Next, let’s declare the following two variables:

var fontPostscriptNames = ""
var lengths = [Int]()

fontPostscriptNames is the string that will hold all PostScript names that will be displayed on the textview. lengths is an array that will keep the length of each PostScript name. I’ll explain why we need it later.

Now, let’s gather all PostScript names from the font family members and let’s build the display string. At the same time, we’ll be storing each name’s length:

for member in fontFamilyMembers {
&nbsp;&nbsp;&nbsp;&nbsp;if let postscript = member[0] as? String {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fontPostscriptNames += "\(postscript)\n"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lengths.append(postscript.count)
&nbsp;&nbsp;&nbsp;&nbsp;}
}

Once again, the fontPostscriptNames string is composed by appending each font PostScript name and the newline symbol “\n” to it.

Having the string value we want to display, we are able to create the attributed string that will format later:

let attributedString = NSMutableAttributedString(string: fontPostscriptNames)

Here’s what’s coming next: We will go once again through all font family members, and for each one we will be creating a new font (NSFont) object based on each member’s data.

for (index, member) in fontFamilyMembers.enumerated() {
&nbsp;&nbsp;&nbsp;&nbsp;if let weight = member[2] as? Int, let traits = member[3] as? UInt {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if let font = NSFontManager.shared.font(withFamily: fontFamily, traits: NSFontTraitMask(rawValue: traits), weight: weight, size: 19.0) {
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
}

We will use the font object above to create a new attribute which we will add it to the attributedString we initialized previously.

Now, there is a tricky part coming. Any attribute added to an attributed string must specify the range of text that it will be applied to. That range is a NSRange value, which is composed by two distinct values: location and length. Location indicates the index of the starting character a range starts from, and length shows how many characters the range will spread to.

Given the fact that we want each line of our text to have a different attribute because of the different font, we must calculate the range of the text that each font will be applied to. And here is where the lengths array is becoming handy. Each new range will start where the previous range stopped, and its length will be equal to the respective value in the lengths array. First range will start at zero.

The following code shows how we calculate the starting location for each range and how we create a new range:

var location = 0
if index > 0 {
&nbsp;&nbsp;&nbsp;&nbsp;for i in 0..<index {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;location += lengths[i] + 1
&nbsp;&nbsp;&nbsp;&nbsp;}
}
&nbsp;
let range = NSMakeRange(location, lengths[index])

In case index is zero, meaning this is the first member in the fontFamilyMembers array, the location is set to zero too (start of text). In every other case, location is the sum of all previous range lengths, including the “\n” symbol which counts as additional character in each line (that’s why “+ 1” is added to each length).

Last line shows how a range is created. NSMakeRange() function accepts two arguments, the location and the length of the range.

Finally, we can create a new attribute for each font now:

attributedString.addAttribute(NSAttributedString.Key.font, value: font, range: range)

All the above will happen for each single item found in the fontFamilyMembers array, or in other words, in the for (index, member) in fontFamilyMembers.enumerated() { ... } loop. There’s one more attribute we have to add to the entire text, and after the end of the loop. That is the text color. By default, black color is the text color of the textview. But since we are using a HUD panel which is already dark, we have to give a light color to the text.

Here is how we do that for the entire text. As you will see, specifying the range in that case is a lot easier than what we previously did:

attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: NSColor.white, range: NSMakeRange(0, attributedString.string.count))

Finally, the attributed string is ready with all the attributes set. It’s time to assign it to the textview, or more precisely, to the textStorage property of the textview:

fontsTextView.textStorage?.setAttributedString(attributedString)

Here’s the showFonts() method with its code all together:

func showFonts() {
&nbsp;&nbsp;&nbsp;&nbsp;guard let fontFamily = fontFamily else { return }
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;var fontPostscriptNames = ""
&nbsp;&nbsp;&nbsp;&nbsp;var lengths = [Int]()
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;for member in fontFamilyMembers {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if let postscript = member[0] as? String {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fontPostscriptNames += "\(postscript)\n"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lengths.append(postscript.count)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;let attributedString = NSMutableAttributedString(string: fontPostscriptNames)
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;for (index, member) in fontFamilyMembers.enumerated() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if let weight = member[2] as? Int, let traits = member[3] as? UInt {
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if let font = NSFontManager.shared.font(withFamily: fontFamily, traits: NSFontTraitMask(rawValue: traits), weight: weight, size: 19.0) {
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var location = 0
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if index > 0 {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for i in 0..<index {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;location += lengths[i] + 1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let range = NSMakeRange(location, lengths[index])
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;attributedString.addAttribute(NSAttributedString.Key.font, value: font, range: range)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: NSColor.white, range: NSMakeRange(0, attributedString.string.count))
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;fontsTextView.textStorage?.setAttributedString(attributedString)&nbsp;&nbsp;&nbsp;&nbsp;
}

Do not forget to call it:

override func viewWillAppear() {
&nbsp;&nbsp;&nbsp;&nbsp;// ...
&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;showFonts()
}

We are done! Run the app now, select any font family and click on the “Display All” button. You will get all available font variations in one place:

Closing The Window

There is one last thing to do, and that is to enable the Close button so it’s possible to close the window when clicking on it. Doing so is extremely easy as you can see right next:

@IBAction func closeWindow(_ sender: Any) {
&nbsp;&nbsp;&nbsp;&nbsp;view.window?.close()
}

Summary

We came eventually to the end of the tutorial! Through all previous parts it became quite obvious that creating a macOS application involves a lot of steps and details, and this post highlighted the most important ones given our today roadmap. There are definitely more things to explore and discuss, and in future posts we’ll be focusing on more and new stuff about macOS programming. Here we managed to create a small application with just a few graphical controls on its UI, we implemented code to get the font information we wanted, to make visual updates to controls and to “play” with windows. By going into the making process all these, we had the chance to meet important concepts and to talk about standard techniques and practices. I hope this post will become a guide to your efforts in building your own macOS applications. Don’t forget to visit Apple’s documentation and Human Interface Guidelines if you find yourself stuck, or you just want to make sure that you are playing by the rules. See you soon!

For reference, you can download the full project on GitHub.

Thanks for reading ❤

If you liked this post, share it with all of your programming buddies!

How To Use PostgreSQL with Your Ruby on Rails Application on macOS

How To Use PostgreSQL with Your Ruby on Rails Application on macOS

In this tutorial, you will set up a Ruby on Rails development environment connected to a PostgreSQL database on a local macOS machine. You will install and configure PostgreSQL, and then test your setup by creating a Rails application that uses PostgreSQL as its database server.

In this tutorial, you will set up a Ruby on Rails development environment connected to a PostgreSQL database on a local macOS machine. You will install and configure PostgreSQL, and then test your setup by creating a Rails application that uses PostgreSQL as its database server.

Introduction

When using the Ruby on Rails web framework, your application is set up by default to use SQLite as a database. SQLite is a lightweight, portable, and user-friendly relational database that performs especially well in low-memory environments, and will work well in many cases. However, for highly complex applications that need more reliable data integrity and programmatic extensibility, a PostgreSQL database will be a more robust and flexible choice. In order to configure your Ruby on Rails setup to use PostgreSQL, you will need to perform a few additional steps to get it up and running.

Prerequisites

This tutorial requires the following:

  • One computer or virtual machine with macOS installed, with administrative access to that machine and an internet connection.
  • A Ruby on Rails development environment installed on your macOS machine. To set this up, follow our guide on How To Install Ruby on Rails with rbenv on macOS. This tutorial will use version 2.6.3 of Ruby and 5.2.3 of Rails; for information on the latest versions, check out the official sites for Ruby and Rails.
Step 1 — Installing PostgreSQL

In order to configure Ruby on Rails to create your web application with PostgreSQL as a database, you will first install the database onto your machine. Although there are many ways to install PostgreSQL on macOS, this tutorial will use the package manager Homebrew.

There are multiple Homebrew packages to install different versions of PostgreSQL. To install the latest version, run the following command:

brew install postgresql

If you would like to download a specific version of PostgreSQL, replace postgresql in the previous command with your desired package. You can find the available packages at the Homebrew website.

Next, include the PostgreSQL binary in your PATH variable in order to access the PostgreSQL command line tools, making sure to replace the 10 with the version number you are using:

echo 'export PATH="/usr/local/opt/[email protected]/bin:$PATH"' >> ~/.bash_profile

Then, apply the changes you made to your ~/.bash_profile file to your current shell session:

source ~/.bash_profile

To start the service and enable it to start at login, run the following:

brew services start [email protected]

Check to make sure the installation was successful:

postgres -V

You will get the following output:

Output
postgres (PostgreSQL) 10.9 

Once PostgreSQL is installed, the next step is to create a role that your Rails application will use later to create your database.

Step 2 — Creating a Database Role for Your Application

In PostgreSQL, roles can be used to organize permissions and authorization. When starting PostgreSQL with Homebrew, you will automatically have a superuser role created with your macOS username. In order to keep these superuser privileges separate from the database instance you use for your Rails application, in this step you will create a new role with less access.

To create a new role, run the following command, replacing appname with whatever name you'd like to give the role:

createuser -P -d appname

In this command, you used createuser to create a role named appname. The -d flag gave the role the permission to create new databases.

You also specified the -P flag, which means you will be prompted to enter a password for your new role. Enter your desired password, making sure to record it so that you can use it in a configuration file in a future step.

If you did not use the -P flag and want to set a password for the role after you create it, enter the PostgreSQL console with the following command:

psql postgres

You will receive the following output, along with the prompt for the PostgreSQL console:

Output
psql (10.9)
Type "help" for help.
 
postgres=#

The PostgreSQL console is indicated by the postgres=# prompt. At the PostgreSQL prompt, enter this command to set the password for the new database role, replacing the highlighted name with the one you created:

\password appname

PostgreSQL will prompt you for a password. Enter your desired password at the prompt, then confirm it.

Now, exit the PostgreSQL console by entering this command:

\q

Your usual prompt will now reappear.

In this step, you created a new PostgreSQL role without superuser privileges for your application. Now you are ready to create a new Rails app that uses this role to create a database.

Step 3 — Creating a New Rails Application

With your role configured for PostgreSQL, you can now create a new Rails application that is set up to use PostgreSQL as a database.

First, navigate to your home directory:

cd ~

Create a new Rails application in this directory, replacing appname with whatever you would like to call your app:

rails new appname -d=postgresql

The -d=postgresql option sets PostgreSQL as the database.

Once you've run this command, a new folder named appname will appear in your home directory, containing all the elements of a basic Rails application.

Next, move into the application's directory:

cd appname

Now that you have created a new Rails application and have moved into the root directory for your project, you can configure and create your PostgreSQL database from within your Rails app.

Step 4 — Configuring and Creating Your Database

When creating the development and test databases for your application, Rails will use the PostgreSQL role that you created in Step 2. To make sure that Rails creates these databases, you will alter the database configuration file of your project. You will then create your databases.

One of the configuration changes to make in your Rails application is to add the password for the PostgreSQL role you created in the last step. To keep sensitive information like passwords safe, it is a good idea to store this in an environment variable rather than to write it directly in your configuration file.

To store your password in an environment variable at login, run the following command, replacing APPNAME with the name of your app and PostgreSQL_Role_Password with the password you created in the last step:

echo 'export APPNAME_DATABASE_PASSWORD="PostgreSQL_Role_Password"' >> ~/.bash_profile

This command writes the export command to your ~/.bash_profile file so that the environment variable will be set at login.

To export the variable for your current session, use the source command:

source ~/.bash_profile

Now that you have stored your password in your environment, it's time to alter the configuration file.

Open your application's database configuration file in your preferred text editor. This tutorial will use nano:

nano config/database.yml

Under the default section, find the line that says pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> and add the following highlighted lines, filling in your credentials and the environment variable you created. It should look something like this:

config/database.yml

...
default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see Rails configuration guide
  # http://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: appname
  password: <%= ENV['APPNAME_DATABASE_PASSWORD'] %>
 
development:
  <<: *default
  database: appname_development
...

This will make the Rails application run the database with the correct role and password. Save and exit by pressing CTRL+X, Y, then ENTER.

For more information on configuring databases in Rails, see the Rails documentation.

Now that you have made changes to config/database.yml, create your application's databases by using the rails command:

rails db:create

Once Rails creates the database, you will receive the following output:

Output
Created database 'appname_development' 
Created database 'appname_test' 

As the output suggests, this command created a development and test database in your PostgreSQL server.

You now have a PostgreSQL database connected to your Rails app. To ensure that your application is working, the next step is to test your configuration.

Step 5 — Testing Your Configuration

To test that your application is able to use the PostgreSQL database, try to run your web application so that it will show up in a browser.

First, you'll use the built-in web server for Rails, Puma, to serve your application. This web server comes with Rails automatically and requires no additional setup. To serve your application, run the following command:

rails server --binding=127.0.0.1

--binding binds your application to a specified IP. By default, this flag will bind Rails to 0.0.0.0, but since this means that Rails will listen to all interfaces, it is more secure to use 127.0.0.1 to specify the localhost. By default, the application listens on port 3000.

Once your Rails app is running, your command prompt will disappear, replaced by this output:

Output
=> Booting Puma
=> Rails 5.2.3 application starting in development
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.1 (ruby 2.6.3-p62), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://127.0.0.1:3000
Use Ctrl-C to stop 

To test if your application is running, open up a new terminal window on your server and use the curl command to send a request to 127.0.0.1:3000:

curl http://127.0.0.1:3000

You will receive a lot of output in HTML, ending in something like:

Output
...
        <strong>Rails version:</strong> 5.2.3<br />
        <strong>Ruby version:</strong> 2.6.3 (x86_64-darwin18)
      </p>
    </section>
  </div>
</body>
</html>

You can also access your Rails application in a local web browser by visiting:

http://127.0.0.1:3000

At this URL, you will find a Ruby on Rails welcome page:

This means that your application is properly configured and connected to the PostgreSQL database.

Conclusion

In this tutorial, you created a Ruby on Rails web application that was configured to use PostgreSQL as a database on a local macOS machine.

Installing Python on Windows, macOS, Linux, iOS, and Android

Installing Python on Windows, macOS, Linux, iOS, and Android

To get started working with Python, you’ll need to have access to the Python interpreter. There are several common ways to accomplish this. In this article, you will learn how to install the latest version of Python 3 on Windows, macOS, Linux, iOS, and Android.

To get started working with Python, you’ll need to have access to the Python interpreter. There are several common ways to accomplish this. In this article, you will learn how to install the latest version of Python 3 on Windows, macOS, Linux, iOS, and Android.

Many operating systems, such as **macOS **and Linux, come with Python pre-installed. The version of **Python **that comes with your operating system is called your system Python.

Table of Contents

  • Windows
    Step 1: Download the Python 3 InstallerStep 2: Run the Installer* Windows Subsystem for Linux (WSL)
  • Linux
    UbuntuLinux MintDebianopenSUSECentOSFedoraArch LinuxCompiling Python From Source* macOS / Mac OS X
    Step 1: Install Homebrew (Part 1)Step 2: Install Homebrew (Part 2)Step 3: Install Python* iOS (iPhone / iPad)
  • Android (Phones & Tablets)
  • Conclusion

To get started working with Python 3, you’ll need to have access to the Python interpreter. There are several common ways to accomplish this:

  • Python can be obtained from the Python Software Foundation website at python.org. Typically, that involves downloading the appropriate installer for your operating system and running it on your machine.
  • Some operating systems, notably Linux, provide a package manager that can be run to install Python.
  • On macOS, the best way to install Python 3 involves installing a package manager called Homebrew. You’ll see how to do this in the relevant section in the tutorial.
  • On mobile operating systems like Android and iOS, you can install apps that provide a Python programming environment. This can be a great way to practice your coding skills on the go.

Alternatively, there are several websites that allow you to access a Python interpreter online without installing anything on your computer at all.

Note: There is a chance that Python may have been shipped with your operating system and is already installed. Even if that is the case, it may be that the installed version is outdated, in which case you will want to obtain the latest version anyhow.

In this Python installation guide, you’ll see step by step how to set up a Installing Python 3 distribution on Windows, macOS, Linux, iOS, and Android. So let’s get started!

Installing Python on Windows

It is highly unlikely that your Windows system shipped with Python already installed. Windows systems typically do not. Fortunately, installing does not involve much more than downloading the Python installer from the python.org website and running it. Let’s take a look at how to install Python 3 on Windows:

Step 1: Download the Python 3 Installer

  1. Open a browser window and navigate to the Download page for Windows at python.org.
  2. Underneath the heading at the top that says Python Releases for Windows, click on the link for the Latest Python 3 Release - Python 3.x.x. (As of this writing, the latest is Python 3.6.5.)
  3. Scroll to the bottom and select either Windows x86-64 executable installer for 64-bit or Windows x86 executable installer for 32-bit. (See below.)

Sidebar: 32-bit or 64-bit Python?

For Windows, you can choose either the 32-bit or 64-bit installer. Here’s what the difference between the two comes down to:* If your system has a 32-bit processor, then you should choose the 32-bit installer.

  • On a 64-bit system, either installer will actually work for most purposes. The 32-bit version will generally use less memory, but the 64-bit version performs better for applications with intensive computation.
  • If you’re unsure which version to pick, go with the 64-bit version.

Note: Remember that if you get this choice “wrong” and would like to switch to another version of Python, you can just uninstall Python and then re-install it by downloading another installer from python.org.### Step 2: Run the Installer

Once you have chosen and downloaded an installer, simply run it by double-clicking on the downloaded file. A dialog should appear that looks something like this:

Important: You want to be sure to check the box that says Add Python 3.x to PATH as shown to ensure that the interpreter will be placed in your execution path.

Then just click Install Now.a That should be all there is to it. A few minutes later you should have a working Python 3 installation on your system.

Windows Subsystem for Linux (WSL)

If you are running Windows 10 Creators or Anniversary Update, you actually have another option for installing Python. These versions of Windows 10 include a feature called the Windows Subsystem for Linux, which allows you to run a Linux environment directly in Windows, unmodified and without the overhead of a virtual machine.

Once you have installed the Linux distribution of your choice, you can install Python 3 from a Bash console window, just as you would if you were running that Linux distribution natively. (See below.)

Installing Python on Linux

There is a very good chance your Linux distribution has Python installed already, but it probably won’t be the latest version, and it may be Python 2 instead of Python 3.

To find out what version(s) you have, open a terminal window and try the following commands:

  • python --version
  • python2 --version
  • python3 --version

One or more of these commands should respond with a version, as below:

$ python3 --version
Python 3.6.5

If the version shown is Python 2.x.x or a version of Python 3 that is not the latest (3.6.5 as of this writing), then you will want to install the latest version. The procedure for doing this will depend on the Linux distribution you are running.

Note that it is frequently easier to use a tool called pyenv to manage multiple Python versions on Linux. To learn more about it, see our article here.

Installing Python on Ubuntu

Depending on the version of the Ubuntu distribution you run, the Python install instructions vary. You can determine your local Ubuntu version by running the following command:

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.4 LTS
Release:        16.04
Codename:       xenial

Depending on the version number you see under Release in the console output, follow the instructions below:

  • Ubuntu 17.10, Ubuntu 18.04 (and above) come with Python 3.6 by default. You should be able to invoke it with the command python3.
  • Ubuntu 16.10 and 17.04 do not come with Python 3.6 by default, but it is in the Universe repository. You should be able to install it with the following commands:
$ sudo apt-get update
$ sudo apt-get install python3.6

  • You can then invoke it with the command python3.6.
  • If you are using Ubuntu 14.04 or 16.04, Python 3.6 is not in the Universe repository, and you need to get it from a Personal Package Archive (PPA). For example, to install Python from the “deadsnakes” PPA, do the following:
$ sudo add-apt-repository ppa:deadsnakes/ppa
$ sudo apt-get update
$ sudo apt-get install python3.6

  • As above, invoke with the command python3.6.

Linux Mint

Mint and Ubuntu use the same package management system, which frequently makes life easier. You can follow the instructions above for Ubuntu 14.04. The “deadsnakes” PPA works with Mint.

Debian

We found sources that indicated that the Ubuntu 16.10 method would work for Debian, but we never found a path to get it to work on Debian 9. Instead, we ended up making Python from source as listed below.

One issue with Debian, however, is that it generally does not install the sudo command by default. To install it, you’ll need to do the following before you carry out the Compiling Python From Source instructions below:

$ su
$ apt-get install sudo
$ vi /etc/sudoers

After that, open the /etc/sudoers file using the sudo vim command (or your favorite text editor.) Add the following line of text to the end of the file, replacing your_username with your actual username:

your_username ALL=(ALL) ALL

openSUSE

We found several sites describing how to get zypper to install the latest version of Python, but they seemed problematic or outdated. We did not manage to get any of them to work successfully, so we fell back to building Python from source. To do that, you will need to install the development tools, which can be done in YaST (via the menus) or by using zypper:

$ sudu zypper install -t pattern devel_C_C++

This step took a while and involved the installation of 154 packages, but once it was completed, we were able to build the source as shown in the Compiling Python From Source section above.

CentOS

The IUS Community does a nice job of providing newer versions of software for “Enterprise Linux” distros (i.e. Red Hat Enterprise and CentOS). You can use their work to help you install Python 3.

To install, you should first update your system with the yum package manager:

$ sudo yum update
$ sudo yum install yum-utils

You can then install the CentOS IUS package which will get you up to date with their site:

$ sudo yum install https://centos7.iuscommunity.org/ius-release.rpm

Finally you can then install Python and Pip:

$ sudo yum install python36u
$ sudo yum install python36u-pip

Thanks to Jani Karhunen for his excellent writeup for CentOS 7.

Fedora

Fedora has a roadmap to switch to Python 3 as the default Python published here. It indicates that the current version and the next few versions will all ship with Python 2 as the default, but Python 3 will be installed. If the python3 installed on your version is not 3.6, you can use the following command to install it:

$ sudo dnf install python36

Arch Linux

Arch Linux is fairly aggressive about keeping up with Python releases. It is likely you already have the latest version. If not, you can use this command:

$ packman -S python

Compiling Python From Source

Sometimes your Linux distribution will not have the latest version of Python, or maybe you just want to be able to build the latest, greatest version yourself. Here are the steps you need to take to build Python from source:

Step 1: Download the Source Code

To start, you need to get the Python source code. Python.org makes this fairly easy. If you go to the Downloads page, you will see the latest source for Python 3 at the top. (Make sure you don’t grab Legacy Python, Python 2.)

When you select the version, at the bottom of the page there is a Files section. Select the Gzipped source tarball and download it to your machine. If you prefer a command line method, you can easily use wget to download it to your current directory:

$ wget https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tgz

Step 2: Prepare Your System

There are a few distro-specific steps involved in building Python from scratch. The goal of each step is the same on all distros, but you might need to translate to your distribution if it does not use apt-get:

  1. The first step you should take when doing an operation like this is to update the system packages on your machine before you start. On Debian, this is what that looks like:
$ sudo apt-get update
$ sudo apt-get upgrade

  1. Next, we want to make sure the system has the tools needed to build Python. There are a bunch of them and you might already have some, but that’s fine. I’ve listed them all in one command line, but you can break the list into shorter commands by just repeating the sudo apt-get install -y portion:
# For apt-based systems (like Debian, Ubuntu, and Mint)
$ sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev  libncursesw5-dev xz-utils tk-dev

# For yum-based systems (like CentOS)
$ sudo yum -y groupinstall development
$ sudo yum -y install zlib-devel

Step 3: Build Python

  1. Once you have the prerequisites and the tar file, you can unpack the source into a directory. Note that the following command will create a new directory called Python-3.6.5 under the one you are in:
$ tar xvf Python-3.6.5.tgz
$ cd Python-3.6.5

  1. Now you need to run the ./configure tool to prepare the build:
$ ./configure --enable-optimizations --with-ensurepip=install

  1. Next, you build the Python programs using make. The -j option simply tells make to split the building into parallel steps to speed up the compilation. Even with the parallel builds, this step can take a several minutes:
$ make -j 8

  1. Then, you’ll want to install your new version of Python. You’ll use the altinstall target here in order to not overwrite the system’s version of Python. Since you’re installing Python into /usr/bin, you’ll need to run as root:
$ sudo make altinstall

Warning: Please only use the altinstall target on make. Using the install target will overwrite the python binary. While this seems like it would be cool, there are big portions of the system that rely on the pre-installed version of Python.#### Step 4: Verify Your Python Install

Finally, you can test out your new Python version:

$ python3.6 -V
Python 3.6.5

Installing Python on macOS / Mac OS X

While current versions of macOS (previously known as “Mac OS X”) include a version of Python 2, it is likely out of date by a few months. Also, this tutorial series uses Python 3, so let’s get you upgraded to that.

The best way we found to install Python 3 on macOS is through the Homebrew package manager. This approach is also recommended by community guides like The Hitchhiker’s Guide to Python.

Step 1: Install Homebrew (Part 1)

To get started, you first want to install Homebrew:

  1. Open a browser and navigate to http://brew.sh/. After the page has finished loading, select the Homebrew bootstrap code under “Install Homebrew”. Then hit Cmd+C to copy it to the clipboard. Make sure you’ve captured the text of the complete command because otherwise the installation will fail.
  2. Now you need to open a Terminal.app window, paste the Homebrew bootstrap code, and then hit Enter. This will begin the Homebrew installation.
  3. If you’re doing this on a fresh install of macOS, you may get a pop up alert asking you to install Apple’s “command line developer tools”. You’ll need those to continue with the installation, so please confirm the dialog box by clicking on “Install”.

At this point, you’re likely waiting for the command line developer tools to finish installing, and that’s going to take a few minutes. Time to grab a coffee or tea!

Step 2: Install Homebrew (Part 2)

You can continue installing Homebrew and then Python after the command line developer tools installation is complete:

  1. Confirm the “The software was installed” dialog from the developer tools installer.
  2. Back in the terminal, hit Enter to continue with the Homebrew installation.
  3. Homebrew asks you to enter your password so it can finalize the installation. Enter your user account password and hit Enter to continue.
  4. Depending on your internet connection, Homebrew will take a few minutes to download its required files. Once the installation is complete, you’ll end up back at the command prompt in your terminal window.

Whew! Now that the Homebrew package manager is set up, let’s continue on with installing Python 3 on your system.

Step 3: Install Python

Once Homebrew has finished installing, return to your terminal and run the following command:

$ brew install python3

Note: When you copy this command, be sure you don’t include the ```Many operating systems, such as **macOS **and Linux, come with Python pre-installed. The version of **Python **that comes with your operating system is called your system Python.

Table of Contents

  • Windows
    Step 1: Download the Python 3 InstallerStep 2: Run the Installer* Windows Subsystem for Linux (WSL)
  • Linux
    UbuntuLinux MintDebianopenSUSECentOSFedoraArch LinuxCompiling Python From Source* macOS / Mac OS X
    Step 1: Install Homebrew (Part 1)Step 2: Install Homebrew (Part 2)Step 3: Install Python* iOS (iPhone / iPad)
  • Android (Phones & Tablets)
  • Conclusion

To get started working with Python 3, you’ll need to have access to the Python interpreter. There are several common ways to accomplish this:

  • Python can be obtained from the Python Software Foundation website at python.org. Typically, that involves downloading the appropriate installer for your operating system and running it on your machine.
  • Some operating systems, notably Linux, provide a package manager that can be run to install Python.
  • On macOS, the best way to install Python 3 involves installing a package manager called Homebrew. You’ll see how to do this in the relevant section in the tutorial.
  • On mobile operating systems like Android and iOS, you can install apps that provide a Python programming environment. This can be a great way to practice your coding skills on the go.

Alternatively, there are several websites that allow you to access a Python interpreter online without installing anything on your computer at all.

Note: There is a chance that Python may have been shipped with your operating system and is already installed. Even if that is the case, it may be that the installed version is outdated, in which case you will want to obtain the latest version anyhow.

In this Python installation guide, you’ll see step by step how to set up a Installing Python 3 distribution on Windows, macOS, Linux, iOS, and Android. So let’s get started!

Installing Python on Windows

It is highly unlikely that your Windows system shipped with Python already installed. Windows systems typically do not. Fortunately, installing does not involve much more than downloading the Python installer from the python.org website and running it. Let’s take a look at how to install Python 3 on Windows:

Step 1: Download the Python 3 Installer

  1. Open a browser window and navigate to the Download page for Windows at python.org.
  2. Underneath the heading at the top that says Python Releases for Windows, click on the link for the Latest Python 3 Release - Python 3.x.x. (As of this writing, the latest is Python 3.6.5.)
  3. Scroll to the bottom and select either Windows x86-64 executable installer for 64-bit or Windows x86 executable installer for 32-bit. (See below.)

Sidebar: 32-bit or 64-bit Python?

For Windows, you can choose either the 32-bit or 64-bit installer. Here’s what the difference between the two comes down to:* If your system has a 32-bit processor, then you should choose the 32-bit installer.

  • On a 64-bit system, either installer will actually work for most purposes. The 32-bit version will generally use less memory, but the 64-bit version performs better for applications with intensive computation.
  • If you’re unsure which version to pick, go with the 64-bit version.

Note: Remember that if you get this choice “wrong” and would like to switch to another version of Python, you can just uninstall Python and then re-install it by downloading another installer from python.org.### Step 2: Run the Installer

Once you have chosen and downloaded an installer, simply run it by double-clicking on the downloaded file. A dialog should appear that looks something like this:

Important: You want to be sure to check the box that says Add Python 3.x to PATH as shown to ensure that the interpreter will be placed in your execution path.

Then just click Install Now. That should be all there is to it. A few minutes later you should have a working Python 3 installation on your system.

Windows Subsystem for Linux (WSL)

If you are running Windows 10 Creators or Anniversary Update, you actually have another option for installing Python. These versions of Windows 10 include a feature called the Windows Subsystem for Linux, which allows you to run a Linux environment directly in Windows, unmodified and without the overhead of a virtual machine.

Once you have installed the Linux distribution of your choice, you can install Python 3 from a Bash console window, just as you would if you were running that Linux distribution natively. (See below.)

Installing Python on Linux

There is a very good chance your Linux distribution has Python installed already, but it probably won’t be the latest version, and it may be Python 2 instead of Python 3.

To find out what version(s) you have, open a terminal window and try the following commands:

  • python --version
  • python2 --version
  • python3 --version

One or more of these commands should respond with a version, as below:

$ python3 --version
Python 3.6.5

If the version shown is Python 2.x.x or a version of Python 3 that is not the latest (3.6.5 as of this writing), then you will want to install the latest version. The procedure for doing this will depend on the Linux distribution you are running.

Note that it is frequently easier to use a tool called pyenv to manage multiple Python versions on Linux. To learn more about it, see our article here.

Installing Python on Ubuntu

Depending on the version of the Ubuntu distribution you run, the Python install instructions vary. You can determine your local Ubuntu version by running the following command:

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.4 LTS
Release:        16.04
Codename:       xenial

Depending on the version number you see under Release in the console output, follow the instructions below:

  • Ubuntu 17.10, Ubuntu 18.04 (and above) come with Python 3.6 by default. You should be able to invoke it with the command python3.
  • Ubuntu 16.10 and 17.04 do not come with Python 3.6 by default, but it is in the Universe repository. You should be able to install it with the following commands:
$ sudo apt-get update
$ sudo apt-get install python3.6

  • You can then invoke it with the command python3.6.
  • If you are using Ubuntu 14.04 or 16.04, Python 3.6 is not in the Universe repository, and you need to get it from a Personal Package Archive (PPA). For example, to install Python from the “deadsnakes” PPA, do the following:
$ sudo add-apt-repository ppa:deadsnakes/ppa
$ sudo apt-get update
$ sudo apt-get install python3.6

  • As above, invoke with the command python3.6.

Linux Mint

Mint and Ubuntu use the same package management system, which frequently makes life easier. You can follow the instructions above for Ubuntu 14.04. The “deadsnakes” PPA works with Mint.

Debian

We found sources that indicated that the Ubuntu 16.10 method would work for Debian, but we never found a path to get it to work on Debian 9. Instead, we ended up making Python from source as listed below.

One issue with Debian, however, is that it generally does not install the sudo command by default. To install it, you’ll need to do the following before you carry out the Compiling Python From Source instructions below:

$ su
$ apt-get install sudo
$ vi /etc/sudoers

After that, open the /etc/sudoers file using the sudo vim command (or your favorite text editor.) Add the following line of text to the end of the file, replacing your_username with your actual username:

your_username ALL=(ALL) ALL

openSUSE

We found several sites describing how to get zypper to install the latest version of Python, but they seemed problematic or outdated. We did not manage to get any of them to work successfully, so we fell back to building Python from source. To do that, you will need to install the development tools, which can be done in YaST (via the menus) or by using zypper:

$ sudu zypper install -t pattern devel_C_C++

This step took a while and involved the installation of 154 packages, but once it was completed, we were able to build the source as shown in the Compiling Python From Source section above.

CentOS

The IUS Community does a nice job of providing newer versions of software for “Enterprise Linux” distros (i.e. Red Hat Enterprise and CentOS). You can use their work to help you install Python 3.

To install, you should first update your system with the yum package manager:

$ sudo yum update
$ sudo yum install yum-utils

You can then install the CentOS IUS package which will get you up to date with their site:

$ sudo yum install https://centos7.iuscommunity.org/ius-release.rpm

Finally you can then install Python and Pip:

$ sudo yum install python36u
$ sudo yum install python36u-pip

Thanks to Jani Karhunen for his excellent writeup for CentOS 7.

Fedora

Fedora has a roadmap to switch to Python 3 as the default Python published here. It indicates that the current version and the next few versions will all ship with Python 2 as the default, but Python 3 will be installed. If the python3 installed on your version is not 3.6, you can use the following command to install it:

$ sudo dnf install python36

Arch Linux

Arch Linux is fairly aggressive about keeping up with Python releases. It is likely you already have the latest version. If not, you can use this command:

$ packman -S python

Compiling Python From Source

Sometimes your Linux distribution will not have the latest version of Python, or maybe you just want to be able to build the latest, greatest version yourself. Here are the steps you need to take to build Python from source:

Step 1: Download the Source Code

To start, you need to get the Python source code. Python.org makes this fairly easy. If you go to the Downloads page, you will see the latest source for Python 3 at the top. (Make sure you don’t grab Legacy Python, Python 2.)

When you select the version, at the bottom of the page there is a Files section. Select the Gzipped source tarball and download it to your machine. If you prefer a command line method, you can easily use wget to download it to your current directory:

$ wget https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tgz

Step 2: Prepare Your System

There are a few distro-specific steps involved in building Python from scratch. The goal of each step is the same on all distros, but you might need to translate to your distribution if it does not use apt-get:

  1. The first step you should take when doing an operation like this is to update the system packages on your machine before you start. On Debian, this is what that looks like:
$ sudo apt-get update
$ sudo apt-get upgrade

  1. Next, we want to make sure the system has the tools needed to build Python. There are a bunch of them and you might already have some, but that’s fine. I’ve listed them all in one command line, but you can break the list into shorter commands by just repeating the sudo apt-get install -y portion:
# For apt-based systems (like Debian, Ubuntu, and Mint)
$ sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev  libncursesw5-dev xz-utils tk-dev

# For yum-based systems (like CentOS)
$ sudo yum -y groupinstall development
$ sudo yum -y install zlib-devel

Step 3: Build Python

  1. Once you have the prerequisites and the tar file, you can unpack the source into a directory. Note that the following command will create a new directory called Python-3.6.5 under the one you are in:
$ tar xvf Python-3.6.5.tgz
$ cd Python-3.6.5

  1. Now you need to run the ./configure tool to prepare the build:
$ ./configure --enable-optimizations --with-ensurepip=install

  1. Next, you build the Python programs using make. The -j option simply tells make to split the building into parallel steps to speed up the compilation. Even with the parallel builds, this step can take a several minutes:
$ make -j 8

  1. Then, you’ll want to install your new version of Python. You’ll use the altinstall target here in order to not overwrite the system’s version of Python. Since you’re installing Python into /usr/bin, you’ll need to run as root:
$ sudo make altinstall

Warning: Please only use the altinstall target on make. Using the install target will overwrite the python binary. While this seems like it would be cool, there are big portions of the system that rely on the pre-installed version of Python.#### Step 4: Verify Your Python Install

Finally, you can test out your new Python version:

$ python3.6 -V
Python 3.6.5

Installing Python on macOS / Mac OS X

While current versions of macOS (previously known as “Mac OS X”) include a version of Python 2, it is likely out of date by a few months. Also, this tutorial series uses Python 3, so let’s get you upgraded to that.

The best way we found to install Python 3 on macOS is through the Homebrew package manager. This approach is also recommended by community guides like The Hitchhiker’s Guide to Python.

Step 1: Install Homebrew (Part 1)

To get started, you first want to install Homebrew:

  1. Open a browser and navigate to http://brew.sh/. After the page has finished loading, select the Homebrew bootstrap code under “Install Homebrew”. Then hit Cmd+C to copy it to the clipboard. Make sure you’ve captured the text of the complete command because otherwise the installation will fail.
  2. Now you need to open a Terminal.app window, paste the Homebrew bootstrap code, and then hit Enter. This will begin the Homebrew installation.
  3. If you’re doing this on a fresh install of macOS, you may get a pop up alert asking you to install Apple’s “command line developer tools”. You’ll need those to continue with the installation, so please confirm the dialog box by clicking on “Install”.

At this point, you’re likely waiting for the command line developer tools to finish installing, and that’s going to take a few minutes. Time to grab a coffee or tea!

Step 2: Install Homebrew (Part 2)

You can continue installing Homebrew and then Python after the command line developer tools installation is complete:

  1. Confirm the “The software was installed” dialog from the developer tools installer.
  2. Back in the terminal, hit Enter to continue with the Homebrew installation.
  3. Homebrew asks you to enter your password so it can finalize the installation. Enter your user account password and hit Enter to continue.
  4. Depending on your internet connection, Homebrew will take a few minutes to download its required files. Once the installation is complete, you’ll end up back at the command prompt in your terminal window.

Whew! Now that the Homebrew package manager is set up, let’s continue on with installing Python 3 on your system.

Step 3: Install Python

Once Homebrew has finished installing, return to your terminal and run the following command:

$ brew install python3

Note: When you copy this command, be sure you don’t include the `` character at the beginning. That’s just an indicator that this is a console command.

This will download and install the latest version of Python. After the Homebrew brew install command finishes, Python 3 should be installed on your system.

You can make sure everything went correctly by testing if Python can be accessed from the terminal:

  1. Open the terminal by launching Terminal.app.
  2. Type pip3 and hit Enter.
  3. You should see the help text from Python’s “Pip” package manager. If you get an error message running pip3, go through the Python install steps again to make sure you have a working Python installation.

Assuming everything went well and you saw the output from Pip in your command prompt window…congratulations! You just installed Python on your system, and you’re all set to continue with the next section in this tutorial.

Installing Python on iOS (iPhone / iPad)

The Pythonista app for iOS is a full-fledged Python development environment that you can run on your iPhone or iPad. It’s basically a combination of a Python editor, documentation, and interpreter rolled into one single app.

Pythonista is surprisingly fun to use. It’s a great little tool when you’re stuck without a laptop and want to work on your Python skills on the go. It comes with the complete Python 3 standard library and even includes full documentation you can browse offline.

To install and set up Pythonista you need to download it from the iOS app store.

Installing Python on Android (Phones & Tablets)

If you have an Android tablet or phone and want to practice Python on the go, there are a several options available. The one that we found most reliably supports Python 3.6 is Pydroid 3.

Pydroid 3 features an interpreter you can use for REPL sessions, and it also provides the ability to edit, save, and execute Python code:

You can download and install Pydroid 3 from the Google Play store. There is a free version and also a paid Premium version which supports code prediction and code analysis.

Conclusion

This section provided you with the information you need to gain access to a Python 3 interpreter. You are now ready to head to the next section and begin interacting with Python!