Logomark
Top-notch video tutorials for developers.

Thousands of developers use NSScreencast to stay on top of iOS development.

Video Training for iOS Developers

The iOS landscape is large and changes often. With short, bite-sized videos released on a steady schedule, NSScreencast helps keep you continually up to date.

  • Quality content We stress the details. Each screencast is carefully produced in HD quality.
  • Team Plans Get access for your whole team. NSScreencast makes for great lunch & learns.
  • Any Device Stream on the web, or use one of our apps for  tv, iPhone, and iPad.
Keep up with iOS Development

NSScreencast has been releasing a new screencasts regularly for more than 6 years. With short videos you can learn a lot over time without a huge time commitment.

NSScreencast offers the largest collection of iOS development screencasts on the internet. With the range of videos that NSScreencast offers, there is something for people of every skill level.

Bite-sized screencasts on iOS and Mac development.

lock
#428
The Keychain is the best place to store sensitive data such as API keys, auth tokens, and login credentials. On device the data is stored encrypted. Once unlocked, you can retrieve the values you saved, keeping the sensitive data secured by the user's passcode, Face ID, or Touch ID. Using the keychain is not very straightforward, however. It has a low-level C-adapted API and is a little cumbersome to work with. In this episode we will look at how to add, query, and remove items from the keychain, then look at a popular open-source library for making storing values in the keychain much easier to implement.
lock
#427
Property wrappers are turning out to be super useful! In this video we'll look at an open-source library called ValidatedPropertyKit, which gives you property wrappers for validating user input. With it you can check for ranges, non-empty strings, regular expressions, or extend it with your own.
lock
#426
Last time we saw the manual approach to parsing XML. While ultra flexible, parsing XML that is extremely tedious. In this episode we will examine a different approach using Codable and a 3rd party library that adds support for XML. We'll see how XML's flexibility adds some increased complexity with how to parse documents, how to control whether properties are encoded/decoded as elements or attributes and how to deal with nested arrays.
lock
#425
Sometimes legacy APIs that we have to deal with only support XML, and while Swift has first class support for JSON with Codable, XML parsing is still done with Foundation's XMLParser. This is a powerful yet difficult to use class that is modeled as a streaming XML parser. This means you have to write some code that keeps track of the values and state of where we are in the XML document in order to parse it. In this episode we will cover how to parse an XML document using multiple objects, parsers, and a delegate stack.
lock
#424
When working with Codable models, everything is great until you deviate even slightly from the normal behavior. Doing so requires you to drop down to a more manual approach where you have to define your own CodingKeys enum and encode/decode methods. In this episode we will look at a 3rd party set of property wrappers that give you some handy Codable functionality for free.
lock
#423
Swift 5.1 introduced a powerful new feature to the language: Property Wrappers. In this video we will take a look at how to write property wrappers and how to use them to simplify code in our apps.
lock
#422
In the last episode we had a bit of an issue... I was trying to store an enum value in UserDefaults, thinking it would automatically use the backing rawValue to store and load the value. Unfortunately this doesn't work. In this episode we fix this issue and extend our solution to also accommodate other data types by leveraging Codable and a custom protocol.
lock
#421
UserDefaults is quite a handy class for storing user user preferences and lightweight data. However the data is keyed by strings and there's no enforcement of any schema or validation of the data you put in it. In this episode we will look at a technique for making strongly typed access to data in UserDefaults so that we can avoid mistakes when typing the key name or the type of data intended to be written to that key.
lock
#420
Now that Swift Package Manager has started to see some adoption and we have some integration inside of Xcode, I think it's time to take a deeper look at how to use it both as a consumer and as a library author. In this episode we'll create a DiceKit library using SwiftPM, then use it in a command line utility.
lock
#419
To wrap up this series, we add a new model to track and persist the progress of playing episodes. We also restore the player and playback position when coming back from a cold launch.
lock
#418
In this episode we create the UI for our playlist screen, showing episodes from each of the subscribed podcasts. On this screen we combine NSFetchedResultsController with UITableViewDiffableDatasource so that our playlist screen can react to changes to the underlying data and reload as necessary. We do this using the automaticallyMergesChangesFromParent on our NSManagedObjectContext.
Shape
#417
Before Swift 5 we used to write our own Result type to contain a value or an error (but never both). A lot of 3rd party libraries brought along their own as well. Then Swift 5 came and brought us Result. Not only is it slightly different than the ones we might be familiar with, Swift's Result type also has some useful functionality up its sleeve.
lock
#416
In this episode we update all of the episodes in the background when the application is launched. We leverage Operations to do this work and set the qualityOfService to prefer foreground work that the user is actively requesting.
lock
#415
One of the features of iOS 13 that has not gotten much attention is the new diffable datasources for UITableView and UICollectionView. Using UITableViewDiffableDataSource or UICollectionViewDiffableDataSource along with NSDiffableDataSourceSnapshot you can create safe, animatable changes between two states without having to keep track of which records were added, moved, or deleted. It's seriously great!
lock
#414
We finish off our operation to import all the episodes given a podcast id and save into the core data store. We also implement a FeedImporter class that listens for new subscriptions in order to kick off the import when a user subscribes.
lock
#413
Our current SubscriptionStore is too tied to the main core data context. In this episode we'll split this behavior on to a new type that will manage persistence for us, as well as implement a solution to solve the problem of core data being initialized asynchronously. We want to delay our app's UI until we have a context we can use.
lock
#412
In preparation for us to have a playlist of episodes ready to play in the app, we need to save the episodes to our Core Data store. In this episode we create the Episode model and associated class.
lock
#411
We refactor out some common logic to show a My Podcasts screen with all of the subscribed podcasts. We fetch the subscriptions using Core Data and listen for changes to subscriptions using our new Typed Notification system.
lock
#410
Sending notifications in your apps is a great way to signal events without having tight coupling between the interested parties. However, in practice this means creating notifications using string names, and passing data as an untyped dictionary means there is opportunity for misspellings and misunderstandings in what data will be passed for which notifications. This can lead to bugs and crashes. In this episode we'll look at creating a more Swift-friendly type-safe wrapper around notifications.
lock
#409
The new default shell in macOS Catalina is zsh. If you're like me and have been using Bash for years, this is probably a good time to make the switch. In this episode I will go over installing zsh, adding a little configuration as well as some of the features it has over bash. I'll also install oh-my-zsh and customize my prompt using Powerline fonts. Finally I'll import some well-used Bash aliases and functions that I've used for years.
lock
#408
We take our player bar and install it into a custom tab bar. To do this we have to create a custom tab bar controller and tab bar subclass and mix it with just a little bit of questionable UIKit hackery to get it to layout how we want. We'll talk about the tradeoffs for different approaches as well as see some useful debugging tips when a button isn't responding to taps.
lock
#407
We have a player but there's currently no way to bring it back up after dismissing it. In this episode we'll design a persistent player bar that will control the player and will be allowed to live outside its view controller.
Shape
#406
Sometimes we need to create variants of our icons. This can be done by using template images and using a UIImageView with a tintColor change, however sometimes this isn't feasible. We can use our icons along with a mask to create new images of whatever color we want. In this episode we'll use UIGraphicsImageRenderer to quickly draw a new dimmed image for a highlighted button state.
lock
#405
In this episode we implement one of the core functions of a podcast player: playing audio! Using AVPlayer we load up the track and observe its progress so we can update the UI to reflect time progressed, time remaining, as well as allowing the user to scrub to a position in the track.