Guide


ON: BY: Christopher Hannah

Snapchat has just released a new feature, and it’s one that can be taken in a few different ways. It’s Snap Map, and basically it’s a way to share and view peoples locations.

To activate Snap Map, just pinch to zoom out, and you can view any of your friends that are currently sharing their location with you.

In their short video showing the new feature (Now unavailable), it seems as it’s being advertised as a way to see where your friends are, so you can go hang out with them.

But at the same time, it’s very easy to accidentally share your location with more people than you want. This becomes a much bigger problem with a service such as Snapchat, as the majority of users are very young.

Fortunately, there is a setting in Snapchat where you can limit who can view your location. I would suggest turning this feature off completely, but it’s not a problem if it’s managed properly.

So here is how to fine-tune your privacy preferences in Snapchat:

1st Method - From Settings

  1. When viewing your profile in Snapchat, press the settings icon in the top-right hand corner.
  2. Scroll down to the section labelled “WHO CAN…”.
  3. Tap on “See My Location”.
  4. You can then choose any location sharing options from here.

2nd Method - From Snap Map

  1. When viewing the map using Snap Map, press the settings icon in the top-right hand corner.
  2. You get moved straight to the location settings, where you can choose any sharing options.

Location Sharing Options

When sharing your location in Snapchat, there are three different options to choose from (of course there’s also the option to not share it at all, by never enabling the feature).

  • Ghost Mode (Location is hidden)
  • My Friends
  • Select Friends…

So you can either hide it completely, share your location with all of your friends, or just to a selected group. In some cases, “My Friends” is a completely fine option, but that only makes sense if you only add close friends. But if you like to add other people you don’t know very well, or you just want to completely sure who you’re sharing your location with, the latter “Select Friends” option is much better suited.

Extra Tips

  • When using “My Friends”, any friends added will automatically be allowed to view your profile.
  • When using “Select Friends…”, people you allow to see your location won’t be notified, they will simply be able to see you on their map.
  • Your location is only received while you are using the Snapchat app, and apparently not in the background.
  • Any location data is deleted after a few hours.
  • To clear your last locations, toggle Ghost Mode on and off. This will clear your past data, but keep your sharing settings the same.
  • The last tip - Just be careful who you’re giving your location to.
ON: BY: Christopher Hannah

This article is part of a collection of articles about Swift Basics, where I try to explain different parts of Swift development in a more understandable way.


In most iOS applications, you will probably need to use a UITableView at some point. In this short guide, you will find out how to create a UITableView, and populate it with your own data.

UITableView

As Apple say in [the documentation][uitableviewdoc], “A table view displays a list of items in a single column.”.

Basically, it’s a list of cells, that you can take complete control over.

With a UITableView object, there are two ways in which you can control them. They are the UITableViewDelegate, and the UITableViewDataSource. The delegate is what manages the interactions on the table cells, such as selecting and reordering. The UITableViewDataSource is as you may of guessed, what controls the data that populates the table, and also configures the cells in the Table View.

However in this guide, we will just be focussing on the DataSource, as this is all we need to populate a TableView with data.

Styles

There are various ways in which you can customise the style of the TableView manually, but there are two main styles that you can choose from in the InterfaceBuilder, “Grouped” or “Plain”. There aren’t many differences, but in the “Plain” style, each cell fills the Table, and the relevant header/footer float above the cells. However in the “Grouped” style, the sections are visually separated into groups, with the addition of a background colour.

Creating the Project

We’ll start with a new Xcode project. So create a new iOS project, and select the “Single View Application” template. Then you can give it a name, for this example I’m using “TableViewExample”.


Just make sure the Language is Swift, and the other options aren’t needed for this example.

This will create all the necessary files, such as “AppDelegate.swift”, “ViewController.swift”, and “Main.storyboard”.

Putting a UITableView on the Screen

Click on the “Main.storyboard” file, and from the object library on the right, drag a Table View onto the view (There should only be the one).


Then to make sure it works on all iOS devices and screen sizes, we’ll set up the layout. Just drag the corners of the TableView so that it fills the view, but keeps the top status bar visible, it should automatically align.

Select the Table View, and then open up the “Add New Constraints” view from the bottom right corner. It is the icon with a square, which has a vertical line either side.

Once you constraint view appears, select the four lines around the square at the top, while making sure each value is 0. This will simply make it fit to the edges on any screen size.

Configuring the UITableView

Now we need to configure the Table View so that we can manage it later on. So select the Table View, and then click to show the “Attributes Inspector” from the right sidebar.

The only values you need to change are:

  • Content - Dynamic Prototypes
  • Prototype Cells - 1
  • Style - Grouped

All we are doing with these settings, is making the cells in the table dynamic, so that we can update them with live data later on. Then we set the style to grouped, so we can see each section better visually.

UITableViewCell

As we also want to populate the cells with some data later on, we will make use of the dynamic prototyping in Interface Builder, to design the cells.

Firstly we will set a “Reuse Identifier” for the cell, this is so that we can reuse the same cell prototype when loading the TableView. To do this, just select the cell (it may be easier to do this in the Document Outline to the left”, and while still showing the “Attributes Inspector”, set the Reuse Identifier to “PlainCell”.

Linking the UITableView to the ViewController

We will manage the Table View from the initial View Controller, so the next step is to set it as the DataSource of the Table. You can do this programatically, but for this example we will do it using Interface Builder.

To do this, select the Table View, and then choose the “Connections Inspector” in the right sidebar.

From there, just click and drag from the open circle to the right of “delegate” and “dataSource” to the View Controller icon at the top of the view.

Then in the “ViewController.swift” file, we will need to set the class to be the DataSource.

Just replace the current class definition:

``` class ViewController: UIViewController { ```

To the following:

``` class ViewController: UIViewController, UITableViewDataSource { ```

It will show some errors right now, but that is just because we haven’t implemented the required functions yet.

Populating the Table View

We have the Table View set up in Interface Builder, and it’s linked to the View Controller, so now it’s time to populate it with real data.

At the top of the View Controller class, just below the code you’ve just written, copy the below code:

``` let sections = ["Fruit", "Vegetables"] let fruit = ["Apple", "Orange", "Mango"] let vegetables = ["Carrot", "Broccoli", "Cucumber"] ```

This is just three arrays that will be used for the section headings, and the content of each of them.

UITableViewDataSource

To fill the table with data, we need to write four functions to do the following:

  • Set the headings for each section.
  • Set the total number of sections.
  • Set the total number of rows in each section.
  • Configure the individual cells with the relevant data.

Section Headings

We already defined the section headings before, so all we need to do here is to return the string for the associated section, which the function receives as an Int.

``` func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { return sections[section] } ```

Number of Sections

This is quite a simple method, and it just tells the TableView how many sections there are. We already have the section headings in an Array, so we can just return the count value of this.

``` func numberOfSections(in tableView: UITableView) -> Int { return sections.count } ```

Number of Rows

Very similar to the method above, but this time we have slightly more complexity in how we return the value of the number of rows. As this method is for every section, we first need to check which section it is for, and then return the count value of the relevant array.

``` func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { switch section { case 0: // Fruit Section return fruit.count case 1: // Vegetable Section return vegetables.count default: return 0 } } ```

Configure the Cell

The last part of populating the Table View, is to load the data into the cell.

We do this by first creating a UITableViewCell object, by making use of the dequeueReusableCell(withIdentifier:) function. This uses the Reuse Identifier we set earlier, to dynamically reuse one of the cells that have already been created. Then depending on the section that the cell is in, we set the text of the text label of the cell, to the value from the relevant array. After this, the cell is returned, and it is displayed.

``` func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // Create an object of the dynamic cell "PlainCell" let cell = tableView.dequeueReusableCell(withIdentifier: "PlainCell", for: indexPath)
// Depending on the section, fill the textLabel with the relevant text
switch indexPath.section {
case 0:
    // Fruit Section
    cell.textLabel?.text = fruit[indexPath.row]
    break
case 1:
    // Vegetable Section
    cell.textLabel?.text = vegetables[indexPath.row]
    break
default:
    break
}

// Return the configured cell
return cell

}

</div>

### Results
If you run this project now, it should look like this:

![](/content/images/2017/03/Simulator-Screen-Shot-10-Mar-2017--00-07-23.png)


### Final Code
Here is the final code for the View Controller that we created:

<div class="language-swift">

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

let sections = ["Fruit", "Vegetables"]
let fruit = ["Apple", "Orange", "Mango"]
let vegetables = ["Carrot", "Broccoli", "Cucumber"]

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}

// MARK: UITableViewDataSource

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section]
}

func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {
case 0:
// Fruit Section
return fruit.count
case 1:
// Vegetable Section
return vegetables.count
default:
return 0
}
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Create an object of the dynamic cell "PlainCell"
let cell = tableView.dequeueReusableCell(withIdentifier: "PlainCell", for: indexPath)

// Depending on the section, fill the textLabel with the relevant text
switch indexPath.section {
case 0:
    // Fruit Section
    cell.textLabel?.text = fruit[indexPath.row]
    break
case 1:
    // Vegetable Section
    cell.textLabel?.text = vegetables[indexPath.row]
    break
default:
    break
}

// Return the configured cell
return cell

}

}

</div>

You can also find the [full project on GitHub][gh], however as this project will be used continuously in this series, you can find [the relevant release for this guide here][rel].

---

**Congratulations!** You’ve now developed an app that makes use of a UITableView, along with a UITableViewDataSource to dynamically populate data, and also to configure the UITableViewCell.

As this is an ongoing series of articles, you can expect more guides on how to take this project even further.


[gh]: https://github.com/chrishannah/TableViewExample/
[rel]: https://github.com/chrishannah/TableViewExample/releases/tag/0.1
[uitableviewdoc]: https://developer.apple.com/reference/uikit/uitableview
ON: BY: Christopher Hannah

This article is part of a collection of articles about Swift Basics, where I try to explain different parts of Swift development in a more understandable way.


While doing some development in Swift, using Dates and DateFormatters, I found the task of going through every format option quite boring. So this is a quick "cheatsheet", that anyone can use to identify what style of Date/Time they want to display, and also the code to get it.

Of course, you first need to create a Date object, which used in this way will generate the current date/time. Then you will also need a DateFormatter object, which handles the formatting, and is used to output the result into a usable String.

let date = Date()
let dateFormatter = DateFormatter()

Date

Full Date

Output: Wednesday, March 8, 2017

Code:

let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .full
let stringOutput = dateFormatter.string(from: date)

Long Date

Output: March 8, 2017

Code:

let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
let stringOutput = dateFormatter.string(from: date)

Medium Date

Output: Mar 8, 2017

Code:

let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
let stringOutput = dateFormatter.string(from: date)

Short Date

Output: 3/8/17

Code:

let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short
let stringOutput = dateFormatter.string(from: date)

Time

Full Time

Output: 1:26:32 PM Greenwich Mean Time

Code:

let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.timeStyle = .full
let stringOutput = dateFormatter.string(from: date)

Long Time

Output: 1:26:32 PM GMT

Code:

let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.timeStyle = .long
let stringOutput = dateFormatter.string(from: date)

Medium Time

Output: 1:26:32 PM

Code:

let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.timeStyle = .medium
let stringOutput = dateFormatter.string(from: date)

Short Time

Output: 1:26 PM

Code:

let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.timeStyle = .short
let stringOutput = dateFormatter.string(from: date)

Date and Time

You can of course, use the dateFormat and timeFormat together to output the date and time in the same string.

Here is an example:

Output: March 8, 2017 at 1:37 PM

Code:

let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .short
let stringOutput = dateFormatter.string(from: date)

Download

I've made a Swift Playground containing all of the formats for date and time, which you can use yourself by copying the code from GitHub.

ON: BY: Christopher Hannah

Developers are always talking about whether to use Git from the command line, or via a GUI such as GitHub Desktop. Well, if you’re using Xcode, then there’s a much simpler method that’s already built-in! It’s called Xcode Source Control[1].

I’m just about to upload one of my projects to GitHub, so I thought I’d share the process. Especially as I’ve recently found it so much easier to use, because it’s right there in Xcode!

Step 1

The first step is to let Xcode create a Git repository on your Mac. It should be checked by default.

Step 2

Then you will need to create a new repository on GitHub. Give it a name, description, and make it Public/Private. But make sure you don’t select “Initialize this repository with a README”.


Then select “Create Repository”.

Step 3

Then you’ll be redirected to a page where you’ll be asked to set up your repository. You only need one thing from this page, and it’s the URL in the Quick Setup section.

In my case, this is https://github.com/chrishannah/CH-Work-Item.git.

Step 4

Now it’s time to add this into Xcode.

Simply select Source Control from the menu bar, your project name, and then select the “Configure project” option.

Once you’ve done that, the next step is to select the “Remotes” tab, then select the + button in the bottom-left corner, and select “Add Remote”.

Here you will need to give it a name, and an address. The address is the URL previously found on the GitHub set up page. Then press “Add Remote”.

Step 5

The repository has now been created on GitHub, and added to Xcode, the next step is to initialise the repository.

Again, from the menu bar, select Source Control, and then Commit.

A window will appear with all the changes to the repository, since this hasn’t been initialised yet, it will show all of your projects files.

Simply add a commit message, select “Push to remote”, which should automatically select your GitHub repository, and press “Commit X Files and Push”.


If you haven’t connected your GitHub to Xcode before, you will be prompted for a username and password, these are your GitHub details.

That’s It!

Once you’ve completed all of the previous steps, your project should now be on GitHub, and if you go back to the repository on GitHub, it should now be populated.

If you haven’t already (like me above), it’s probably best to add a README file.

Managing Your Repository

From here it’s really easy to manage your repository in Xcode. It’s all found in the Source Control menu.

From there you can commit new files, push them to GitHub, pull any new changes, and anything else you’d expect from a Git client.


I hope that this guide proved useful, and provided a bit of piece of mind for you knowing that your project is now essentially backed up.

If you want to see the other tutorials I have here, then there is a Guide section.

You can find me on GitHub as chrishannah.


  1. For more information, there is a session from WWDC 2013, “Understanding Source Control in Xcode” that explains this in more detail ↩︎

ON: BY: Christopher Hannah

If you're an Apple Music subscriber, or you just have a super large iTunes library, then downloading all of your music to a device can be a giant pain.

With the iPhone storage sizes getting bigger, having your entire collection downloaded is even more of a possibility. I for example have a 128GB iPhone 7 Plus, so I easily have enough space for my entire library.

The only problem is that on iOS, there isn't a "download all" button. However there's a really simple solution if you have a Mac available.

Step 1 - In the sidebar, right click and choose Create Smart Playlist.

Create Smart Playlist

Step 2 - Change the rules to "Artist is not (blank)" like the image below.

Smart Playlist Rules

Step 3 - Open the Playlist in the Music app on your iOS device.

Step 4 - Tap on the "..." button in the top right, and press Download.

iOS Download Button

That's it!

All of your music library should then start to download.

Another bonus that this gives you, is that because it's a Smart Playlist, it will continue to update as you add music to your library. As the rule simply is that it matches any item where the Artist name isn't blank, which should be all of them!

ON: BY: Christopher Hannah

I've seen a few people have issues regarding opening applications that they have downloaded from the internet, that they get the error below, about it being from an unidentified developer.

Unidentified Developer Warning

This is due to the latest security settings in macOS, and these are accessible in the Security & Privacy pane in System Preferences.

Security & Privacy Pane

There are two options to choose from:

  • App Store
  • App Store and identified developers

Of course the top option means you can only open applications distributed from the Mac App Store. But the other one means it allows all apps from the Mac App Store, and also any developers that have signed their application with Apple's "Developer ID" certificate. This allows developers to distribute their apps outside of the store, but also maintain the same security features, and trust level as the former option.

You can read more about Developer ID on the Apple Developer website.

There is also a temporary solution, which lets you override the security settings on a case by case basis. Just press "Open Anyway" at the bottom of the preferences pane, and it will then open like normal!

Edit (14th January 2017):

My friend Cesare let me know that you can also unlock a third option, this let's you choose "Anywhere" in the preferences, and will let you download and open any application without restriction.

To unlock it, just open Terminal (Applications/Utilities/Terminal) and enter the following line exactly:

sudo spctl --master-disable

If you want to return it back to normal, just enter the following:

sudo spctl --master-enable
ON: BY: Christopher Hannah

With the MacBook Pro's new Touch Bar, you can now create your own favicon that will appear there when a user sets it as a bookmark. The same file is also use to create an alpha mask when adding your website as a Pinned Tab.

It's a small bit of code, that you add to your <HEAD> section, just by your other favicons.

Just specify that it is a "mask-icon", add the location for the file (has to be SVG), and then specify a colour to be used. The colour is the background on the Touch Bar icon, and it's also the colour used in the Pinned Tab mask.

Code:

<link 
	rel="mask-icon" 
	href="safari-pinned-tab.svg" 
	color="#dc7604"
>

As an example, you can see the new touch bar icon I made for Radical Thinker.

Radical Thinker Touch Bar Icon

If you haven't already, you can also set an icon for when a user adds your website to their home screen on iOS. This is done similarly, but doesn't have to be an SVG.

Code:

<link 
	rel="apple-touch-icon" 
	sizes="180x180" 
	href="apple-touch-icon.png"
>