Creating iOS Apps without Storyboard – Part 2

Autolayout Programmatically

This article continues from the previous article. Earlier we saw how we can make iOS Apps without using the storyboard file. In this article we will explore how to implement Autolayout programmatically. We will continue from the previous article.

The code that I will be showing in the article will not be covering all the possible cases. The point of this article is to give you an idea on how to implement the different Autolayout solutions. Feel free to play around with the code to cover all the cases & situations.

Programmatic Constraints

We have 3 options when it comes to applying constraints programmatically:

  1. StackViews
  2. Layout Anchors
  3. NSLayoutConstraints class
  4. Visual Format Language (VFL)

Handling Size Classes in code

Handling Size classes in code is fairly easy. It is a simple question of overriding the correct function. We will look at this in greater detail when we cover the topic later in the article.

TopicPage
Implementing UIStackViews2
Implementing Layout Anchors3
NSLayoutConstraints class4
Implementing Visual Format Language5
Size Classes6
Summary & Video7

This article has been written using Xcode 10.3.

Advertisements

Creating iOS Apps without Storyboard – Part 1

What are “nibless” apps?

Apps which are designed without the help of Storyboard are called as “Nibless” apps. Normally we design an app with the help of a Storyboard file. Earlier they were called Xib files or Nib files. Hence the term “Nibless”.

Why should we create Apps without storyboard?

There are a number of reasons.

  1. It makes for a better experience when implementing along with version control.
  2. Allows us to create UI elements dynamically.
  3. Makes reusable UI Components easier to distribute and reuse.

How can we create Apps without Storyboard?

There are a couple of things that need to be done. Firstly the Main.storyboard file needs to be removed and the project settings need to be updated to reflect this change.. We are doing this since we won’t be using the storyboard file.
Everything will now have to be started up by us manually. Many of these tasks were taken care of by storyboard, but since that was removed we will have to do it. This means we have to manually create the window, create the view controller set it as a the root view controller.
We also have to manually create each and every component on our own. That is the very thing we were trying to achieve.

This example is implemented on Xcode 10.3 on macOS 10.14.5. We are not implementing auto layout in this article. We will look at implementing that programmatically in the next article.

  1. Let us start with an empty project. Open Xcode.
  2. Select File > New > Project
  3. Give it any name. Select the language as Swift & leave the checkboxes unchecked.
  4. Once the project loads select the Main.storyboard file and delete it.
  5. Switch to the Project settings file.
  6. Remove the entry for the main interface.
  7. It is a good idea to leave the LaunchScreen.storyboard file. The reason for this is to give the launch process a reference of the screen size it needs to produce. Else it will default down to the 0,0,320,480 which is the old iPhone size.
  8. Switch to the AppDelegate.swift file.
  9. Add the following property below the UI Window declaration.
      
    let mainScreenController : ViewController = ViewController() 
    
  10. Add the code to create the window and set root view controller in the didFinishLaunchingWithOptions method
       
    //1. Create the UIWindow object   
    self.window = UIWindow(frame: UIScreen.main.bounds)   
    
    //2. Set the root view controller   
    self.window?.rootViewController = self.mainScreenController   
    
    //3. Make the window key and visible  
    self.window?.makeKeyAndVisible()  
    
  11. Switch to the ViewController.swift file.
  12. Declare the following variables
      
    //UI Variables  
    var labelDemo   : UILabel?  
    var imageDemo   : UIImageView?  
    var buttonDemo  : UIButton = UIButton(type: UIButton.ButtonType.roundedRect) 
    var dataField   : UITextField?
    
  13. Implement the function to create labels. The process of creating a view programmatically is fairly straightforward. Barring a few variations depending on the view component nothing is drastically different.
      
    func createLabel() 
    {      
         //1. Specify the dimensions      
         let labelRect : CGRect   = CGRect(x: 100.0, y: 50.0, width: self.view.frame.size.width - 130.0, height: 60.0)     
    
         //2. Create the view object      
         labelDemo                = UILabel(frame: labelRect)      
    
         //3. Customise the view attributes      
         labelDemo?.text          = "This is my first Programmatic App."                
         labelDemo?.textColor     = UIColor.yellow      
         labelDemo?.textAlignment = NSTextAlignment.left  
         labelDemo?.numberOfLines = 0      
         labelDemo?.font          = UIFont.boldSystemFont(ofSize: 20.0)      
    
         //4. Add the view to the subview      
         self.view.addSubview(labelDemo!) 
    } 
    
    Let us examine the steps one by one.
     
    //1. Specify the dimensions 
    let labelRect : CGRect = CGRect(x: 100.0, y: 50.0, width: self.view.frame.size.width - 130.0, height: 60.0)
    
    This will define the dimensions of the view. As we are not implementing auto layout we will need to do this manually.
     
    //2. Create the view object
    labelDemo = UILabel(frame: labelRect) 
    
    Now that we have the dimensions we can go ahead and instantiate an instance of the label object using those dimensions. These 2 parts are the same as dragging a label from the object library onto the storyboard and placing it onto the storyboard per our requirements.
    //3. Customise the view attributes 
    labelDemo?.text          = "This is my first Programmatic App."     
    labelDemo?.textColor     = UIColor.yellow 
    labelDemo?.textAlignment = NSTextAlignment.center      
    labelDemo?.numberOfLines = 0 
    labelDemo?.font          = UIFont.boldSystemFont(ofSize: 20.0)
    
    This part is the same as changing the attributes in the attributes inspector. This is where we customise the label.
     
    //4. Add the view to the subview 
    self.view.addSubview(labelDemo!) 
    
    This last part also forms one part of dragging the label on to the storyboard. When we drag a view on to the storyboard it is placed within the main view that belongs to the ViewController. This statement completes the above process.
  14. Repeat the above steps for showing an image.
    func createImage()
    {
         //1. Specify the dimensions
         let imageRect  : CGRect  = CGRect(x: 30.0, y: 50.0, width: 60.0, height: 60.0)
    
         //2. Create the image model
         let imageModel : UIImage = UIImage(named: "logo.png")!
    
         //3. Create the view object
         imageDemo                = UIImageView(frame: imageRect)
    
         //4. Customise the view attributes
         imageDemo?.image         = imageModel
         imageDemo?.contentMode   = UIView.ContentMode.scaleAspectFit
    
         //5. Add the view to the subview
         self.view.addSubview(imageDemo!)
    }
    
    The code above is almost similar to the one created for labels except for the fact that we had to explicitly create a model object for the view. Images being different from strings, require this process to be done explicitly.
  15. Similarly let us implement the code for creating buttons
    func createButton()
    {
         //1. Specify the dimensions
         let buttonRect : CGRect = CGRect(x: 30.0, y: 220.0, width: 100.0, height: 50.0)
    
         //2. Provide the frame to the button
         buttonDemo.frame = buttonRect
    
         //3. Customise the view attributes
         buttonDemo.setTitle("Click Me", for: UIControl.State.normal)
         buttonDemo.addTarget(self, action: #selector(ViewController.clickMeTapped), for: UIControl.Event.touchDown)
    
         //4. Add the view to the subview
         self.view.addSubview(buttonDemo)
    }
    
    @objc func clickMeTapped(
    {
         print("Click me tapped!")
    }
    
    Again just minor variations here. Mainly the step to add a target function to be invoked when the button is tapped. We also need to write the target function itself.
  16. We will also implement the code to create a text field.
    func createTextField()
    {
        //1. Provide dimensions for the view
        let tfRect : CGRect             = CGRect(x: 30.0, y: 140.0, width: self.view.frame.size.width - 60.0, height: 50.0)
            
        //2. Create the view object
        dataField                       = UITextField(frame: tfRect)
            
        //3. Customise the attributes of the view
        dataField?.placeholder          = "Enter Name"
        dataField?.borderStyle          = UITextField.BorderStyle.roundedRect
        dataField?.keyboardType         = UIKeyboardType.namePhonePad
        dataField?.keyboardAppearance   = UIKeyboardAppearance.dark
        dataField?.returnKeyType        = UIReturnKeyType.go
            
        //4. Add the view to the subview
        self.view.addSubview(dataField!)
    }
    
  17. Next we need to call all these functions. I have implemented a single creator function for that.
    func createUIElements()
    {
         self.createLabel()
         self.createImage()
         self.createButton()
         self.createTextField()
    }
    
  18. Lastly we will call this function in the viewDidLoad method. Add the following lines to the viewDidLoad method.
    self.view.backgroundColor = UIColor.lightGray
    self.createUIElements()
    
    I have also added code to change the background colour so that we can see the background clearly.
  19. Run the project. Everything should appear normally.

Are there any benefits of creating apps without storyboard?

The points mentioned in the “why should we make programmatic apps?” section are some of the advantages. Beyond that there aren’t too many.
If you are looking at a team based project development then this approach is good.
There is no difference in terms of memory or performance when it comes down to apps design with or without storyboard.

Are there any drawbacks?

As can be seen from the example above, there are a couple of drawbacks

  1. The main drawback is that you can’t get a quick preview of how your app looks. You have to run the simulation every time you wish to see the end result.
  2. There is a lot more coding involved. Which can be daunting to those who are overly accustomed to designing with the help of storyboards

Note

A small point. I have left the LaunchScreen.storyboard file. I did not delete it. The reason I did that was to allow the app to allow the system to determine the dimensions on the device. If we do delete the file then the UIScreen.main.bounds return (0.0, 0.0, 320.0, 480.0) which are the old iPhone screen size settings.
While you can go ahead and make changes programmatically it is a lot easier to just leave the LaunchScreen.storyboard file there.

Carrying on from the previous point. It actually is okay if you leave the Main.storyboard file as is too. In which case you will have to skip steps 5,6,8,9,10. The code is still running programmatically but you do not have to create the main ViewController manually.

Download the Source Code

You can download the Xcode Project from this link.

iPhone Screen Recording – Part 2

This is an addendum to the earlier topic on Screen and Audio recording on macOS & iOS.

In the earlier article we had discussed how to share the iPhone screen on the project or how to record iPhone screen activities. In this article we are going to see how to use the built in feature of iOS 11 to do the same.

  1. First we must add the button to do this to control centre. Open Settings > Control Centre> Customise Controls .IMG_0134
  2. Tap on the ‘+’ button next to Screen Recording to add Screen Recording to the control centre. Close the Settings App.IMG_0135
  3. Swipe up from the bottom of the screen to bring the control centre options.
  4. Tap on the Screen record button. Tap the microphone audio button to record audio if you wish.IMG_0136
  5. Tap the “Start Recording” button to start recording. To stop simply tap on the “Stop Recording” button.IMG_0138IMG_0140
  6. The video is saved in the camera roll.

Third Party Applications

This feature is used to provide screen sharing capability via apps such as TeamViewer.

 

Buyers Guide for macOS & iOS in the Enterprise

This article is more of a productivity article aimed at getting first time users up and running quickly on their Mac, iPhones or iPads. Anyone looking to buy one of these products or Tech Support teams that help employees with their computers would find this article helpful. The thoughts shared here are personal, readers are welcome to share their own thoughts and experiences.

The article is not a comprehensive guide. Its aim is to give potential users some idea as to how the devices can be used in their work environment. Specifically from an Application perspective.

Macintosh

macFamily


Which one to buy?

This depends on how the device is going to be used. Here are 3 general classifications:

Basic Usage

Basic usage would mean simple day to day tasks. These are the tasks that would qualify for:

  • Checking emails
  • Browsing the web
  • Social Media
  • Listening to Music
  • Watching Movies
  • Composing letters
  • Preparing Presentations & running presentations
  • Note taking

In such a case you may want to consider buying a MacBook or a MacBook Air. If portability is not required then a Mac Mini would also do.

At entry level configurations these devices would do the job very well.

Intermediate Usage

If the tasks being performed are a little more demanding then you may want to consider higher configuration devices. Again in most cases the  MacBook or a MacBook Air would do. If portability is not required then a Mac Mini would also do. In all these cases consider one with slightly higher configuration.

For situations where the compute power is important you may even consider the MacBook Pro. For example, if there are programmers who need to work with a high configuration Mac and they need portability, then you can consider the MacBook Pro.

Pro Usage

This indicates that the tasks being performed are very compute intensive. These are some of the job profiles which may demand compute intensive resources:

  • Programmers
  • Video Editors
  • Audio Editors
  • Post Production Teams
  • Marketing & Creative Teams
  • Scientific Research

For such situations the higher end desktops & MacBook Pros would be required. So the iMac or the highest configuration Mac Mini, or the 15″ MacBook Pro would be best suited for such environments.

In some situations even more powerful computers would be required. The iMac Pro & Mac Pro should then be considered.


Built In Applications that might be useful

Productivity Tools

There are 3 applications which are a part of the suite called iWork that are very useful in organisations.

  • PAGES: Built in word processing application. You can easily created documents, letters, reports and even have them exported in Microsoft Office compatible format.
  • KEYNOTE: Built in presentation applications. Enables you to create powerful presentations from scratch. Like Pages it is possible to create presentations that are compatible with PowerPoint.
  • NUMBERS: Built in spreadsheet application. Enables you to quickly create spreadsheets and export them to Excel if needed.

The other advantage is the fact that these applications are also accessible from the cloud. Tight integration with iCloud means that you can make changes to documents from your Mac, iPhone, iPad, or iCloud.com.

Creative Tools

There are 2 applications which are available for creative purpose. These might be handy for people working in the creative departments.

  • IMOVIE: Quick create movies using videos, audios and photos that you have.
  • GARAGEBAND: A simple Music creation application that comes with a library of different instruments.

Popular Third Party Applications

These are just some of the applications.

Office Suite

Productivity

Cloud

Creative

Security

Communication

Data Backup

Virtualisation (Running Windows or Windows Applications on the Mac)


Some tasks that can be done with built in Applications

  • Scanning Documents using Preview
  • Signing Documents using Preview
  • Record Screen Activity using QuickTime
  • Record a quick movie using QuickTime
  • Automate Tasks & create workflows using Automator
  • Encrypt Data using FileVault
  • Show your iPhone/iPad screen on a projector using QuickTime on Mac
  • Backup data using Time Machine

iPhone/iPad

iosFamily


Which one to buy?

The decision on whether to buy the iPhone &/or the iPad depends a lot on what you intend to use it for. As such the major differences between the 2 devices are:

  • iPads tend to have larger screens
  • iPhone has cellular communication capability
  • iPhones are more portable as compared to iPads
  • iPads are better suited for long duration usage
  • iPads tend to be higher powered devices

While it appears that iPads are better than iPhones, that is not necessarily the case. iPhones being smaller and more compact have many advantages too.

Ideally speaking having both, an iPhone and an iPad, is the best thing to do.

To make a decision use the task list below to help find out if you need an iPhone or an iPad or both.

Note, even though I mention that the tasks can be performed easily on an iPhone, many of the tasks can also be done very easily on the iPad. The point is to illustrate ease of use in situations where you have to perform tasks with a single hand or when you are on the move.

Tasks easily performed on an iPhone

  • Making calls
  • Messaging
  • Scheduling activities such as: Reminders, Appointments, Events
  • Taking Photos & Videos
  • Emails
  • Banking Transactions
  • Finding Transit Directions
  • Finding a Taxi
  • Making E-Payments

Tasks easily performed on the iPad

  • Writing letters & blogs
  • Creating Presentations
  • Working with spreadsheets
  • Creating posters, flyers
  • Working with business applications
  • Content creation

If you do a mixture of tasks from both the lists then getting both an iPhone as well as an iPad is a good idea.

A thing to keep in mind is that the Pro version of the iPad also has a nice keyboard accessory as well as the  Pencil available. These 2 products make the whole experience so much better.

Screen size consideration

iPhone and iPad screen sizes vary quite a bit. Here are some tips on the tasks which can be best performed on specific screen sizes.

Creative Work

Generally speaking, creative tasks require a large screensize. So for an iPhone the smallest screen you should have is 4.7″. Similarly for the iPad the smallest screen you should have is the  9.7″.

Documents, letters, spreadsheets

These tasks are better performed on the iPads as such you can go for any screen size in them. Of the lot, its a lot easier to create documents and letters on the phone than spreadsheets. Again, for phones one should the larger the screen size the better.

Presentations

Like documents and spreadsheets presentations are a lot easier to create on the iPad. They can also be created from the phones. The larger the phone the better.

Messaging & Communication

This is one aspect where the screen size is not so much of an issue. In fact, some users may find the smaller screen size a lot better. Typically, the iPhone is a much better device than the iPad for this.

Productivity & General Tasks

This includes calling taxis, ordering food, taking notes, control keynote presentations, setting up appointments and reminders. These tasks are also best performed on iPhones. They can be done well with the iPad too.


Built In Applications that might be useful

Productivity Tools

There are 3 applications which are a part of the suite called iWork that are very useful in organisations.

  • PAGES: Built in word processing application. You can easily created documents, letters, reports and even have them exported in Microsoft Office compatible format.
  • KEYNOTE: Built in presentation applications. Enables you to create powerful presentations from scratch. Like Pages it is possible to create presentations that are compatible with PowerPoint.
  • NUMBERS: Built in spreadsheet application. Enables you to quickly create spreadsheets and export them to Excel if needed.

The other advantage is the fact that these applications are also accessible from the cloud. Tight integration with iCloud means that you can make changes to documents from your Mac, iPhone, iPad, or iCloud.com.

Creative Tools

There are 2 applications which are available for creative purpose. These might be handy for people working in the creative departments.

  • IMOVIE: Quick create movies using videos, audios and photos that you have.
  • GARAGEBAND: A simple Music creation application that comes with a library of different instruments.

Other Apps

  • Notes
  • Voice Memos
  • Files

Popular Third Party Applications

Office Suite

Productivity

Cloud

Creative

Security

Communication


Some tasks that can be done with built in Applications

  • Scanning Documents using Notes
  • Recording Voice Memos
  • Control HomeKit devices
  • Edit PDFs through iBooks
  • Create PDF documents through pages & then edit the PDFs either through iBooks or markup utilities
  • Record and Edit videos using the camera & iMovie

Useful iPad Accessories

 TV

There are a few things that can be done with the  TV. It can be used to mirror both macOS & iOS Devices. In which case apps such as Reflector are not really required.

It is very easy to setup and use. This can make projecting both the iPad screen as well as the iOS Screen very easy & it allows you to move across the room as you are not physically wired to the projector.

Final Word

As we can see there are a wide variety of apps available both for macOS & iOS. These include built in apps as well as Third party apps. The community of developers creating these apps is strong and growing. There are many more apps which can be used for a wide variety of purposes.

This article should give the user a fair idea as to the capabilities of devices such as iPads, MacBooks and the rest of the line up. The good thing is that for enterprise environments its easily possible to create apps that are tailored to the needs of that organisation and this makes the devices much more attractive.

Programming Style Guide – The Need for programming standards

Programming Style Guide refers to the conventions followed while writing programs. This guide is going to be a series of blogs highlighting different programming standards. The series will try to cover as many standards as possible, focus will be on common and popular standards.

But why the need for programming standards? Standards help software developers design software in such a way that it is easy to read, understand, maintain & expand. It provides a consistent experience & also speeds up the way in which software development is done.

A program written with the best standards kept in mind is self explanatory, easy to read, can be built on, & is a stable piece of software

This specific article will act as a Content list for all the articles written as a part of this series. The examples are from the Swift & C++ programming languages.

  1. Naming Conventions
  2. Code Refactoring
  3. Programming Style Guide: Documentation
  4. Programming Style Guide: Command Query Separation

 

 

Programming Style Guide: Naming Conventions

Today we are going to look at Naming conventions you can follow while writing code.

Naming conventions lay down the basic rules for naming different elements in your code. The objectives are simple:

  • Make the element easy to read
  • Should be self explanatory
  • Should contain information in a compact and concise manner.

Ideally a well named variable or function should not need a comment to explain what it is for.

With the above objectives in mind let us look at some of the naming conventions that can be followed. The examples are from the Swift & C++ programming languages.

Naming Conventions

Camel Case Names

In camel case naming convention the entire name of the element is constructed by forming a sentence joined into a single word. So for example if we have a variable for keeping track of the price of oil in US dollars then the variable name might be priceOfOilUSD.

Here are some examples of naming conventions with the camel case.

SWIFT

var priceOfOil : Float = 23.49

C++

float priceOfOil = 3.45;
class PersonInfo
{

};

Underscore Separated Names

In the underscore separated naming convention the entire name of the element is constructed by forming a sentence joined together with the help of underscores in-between them. So if we take the example of the variable keeping track of the price of oil in US dollars the the variable name might be price_of_oil_usd.

Swift

var price_of_oil : Float = 45.71

C++

float price_of_oil = 99.87;

void print_value_of_pi()
{
     //print something
}

Names with type information

A naming convention that is quite popular is the one that mixes the previous 2 naming conventions, with the underscore used to separate the type description in the prefix. So if we take the example of the variable keeping track of the price of oil in US dollars then the variable name might be f_priceOfOil or float_priceOfOil. Either of the design styles work. The prefix is popularly abbreviated and you can create your own rules for abbreviating the type description.

This style is often referred to as the Hungarian notation. The additional information that is provided as a part of the prefix can be:

  • Whether the variable is a pointer
  • Whether the variable is an object
  • The scope of the variable
  • Type size
  • Whether the data can vary or is a constant

Swift

var f_priceOfOil : Float = 0.0

C++

float f_priceOfOil = 22.3;
int *ptr_memmoryBuffer = NULL; //ptr indicates variable is a pointer

Naming Rules

There are some rules that are typically followed while designing names for variables and  functions. Like the conventions themselves the rules are not binding but they are very useful an give the added punch that naming conventions provide.

  1. Variable names always start in lower case.
  2. Type names always start in upper case.
  3. The naming conventions is consistently applied through all the projects
  4. Names should be kept as small as possible without sacrificing on the description

Naming Strategies

As far as strategies are concerned there are multiple approaches that one can follow. Here are some potential strategies.

  • Follow one naming convention for variables and another convention for functions.
  • Let constants be all upper case
  • Prefix types with your companies initials.

Summary

The above illustrate just some of the naming conventions that can be followed. By no means are they comprehensive or complete. Also it is not necessarily true that everyone follows the above naming conventions. You may find that many software development firms have their own unique naming convention. This article should give you an an idea about naming conventions. Feel free to share some naming conventions that you have come across.

When to use Swift & when to use Objective-C?

Over the past few years I have received a number of questions with regards to Swift & Objective-C. Specifically related to the future of the 2. I will try to address those questions in the form of an FAQ.

Should I learn Swift or Objective-C?

This is a question that I get from developers new to iOS/macOS App Development. Ideally speaking, you should learn Swift. As that is going to become the main language for App development on Apple’s ecosystem. However, the reality is a little different. There are a large number of applications that are written in Objective-C. You are likely to encounter them at your workplace. You may also have to maintain, upgrade & improve those apps. In such a case, it makes sense to learn Objective-C too.

Can I mix Swift & Objective-C in the same project?

Yes! But remember that you should check for feature compatibility between the 2 languages. Adding Swift code to an Objective-C project may not be very beneficial as only those features that are compatible with Objective-C can be written in Swift.

Going the other way round is not a problem. You can read more about that here:Mixing Swift & Objective-C

Will Objective-C be deprecated in the future?

That is an interesting question. There is no formal announcement from Apple stating the Objective-C is going to be deprecated. However, one can expect more attention to be paid to Swift. That is where most of the newest techniques, tools & technologies are going to be available. Objective-C will keep running as it is as of now.

Can I mix Swift with other Programming Languages?

Swift can easily be mixed with Objective-C. If you wish to incorporate C++ or C code in your Swift Project then wrapping them in Objective-C code allows you to achieve this.

Apart from that Swift does support working with C code code. You can read about that here:Interacting with C APIs.

Swift does not provide interoperability support for any other languages as of now.

Which version of Swift should I use?

It is recommended that you use the latest available version of Swift. However, the actual version that you work on depends on many other factors like: compatibility with OS Versions, support & business related choices.

Why shouldn’t we just convert all our Objective-C code to Swift and keep things simple?

A very tempting proposition. However, practical realities prevent us from doing this. The process of converting from Objective-C to Swift is time consuming. Apart from having to convert the syntax, the code also needs to be optimised taking into account the new features that are available. This will mean extensive testing and quality assurance. Most companies will not invest their resources into this endeavour.

A better approach is to migrate to Swift gradually. Here are some ways to do this:

  1. If its a brand new product/app that you are creating, start it in Swift.
  2. Any new reusable code components that are being created should be done in Swift (they should be Objective-C compatible if you intend to use this code in Objective-C projects).
  3. If any part of a product is going to undergo heavy change, either due to a bug fix or a new feature. This is a good time to convert it into Swift.

A good example is how Apple is approaching the process of migrating to Swift. They are doing it component by component.

I have been developing apps in Objective-C for some time. I am able to create any reasonably complicated app now. If Objective-C hasn’t been deprecated then should I start making apps in Swift?

This is a choice that you have to make. It is recommended that new apps (at the very least) be made in Swift as that is the language that will undergo the maximum amount of changes & improvements in the future.

What do you suggest as a trainer?

Another question that I get very often. It depends on the situation. I would say learn both Swift & Objective-C. You can skip learning Objective-C if you are confident that you will not have to work with any projects written in that language.

If I am starting on a brand new project I would use Swift. But if its an Objective-C project I would stick to Objective-C.

Can Swift development only be done on macOS?

No! Swift development can also be done on Linux. However, iOS/macOS/tvOS/watchOS App Development can only be done on macOS through Xcode.

How should I migrate to Swift?

There are different approaches that one can use. It all depends on the situation and needs of your organisation. Here are some things that you can do:

  • Start development of brand new apps (from scratch) in Swift.
  • If you are creating a brand new library which will be used for future projects then go ahead with Swift.
  • If a major component of an existing app is going to be changed significantly then you can go ahead with Swift.

You can do all or some of the above. There may be other strategies too. You should also factor in the cost of migration from one language to another.

 

Collection Type, Sequence Type & Indexable Type

This is for Swift Version 2.2 & earlier. I will be adding the snippet of code for the changes the Swift 3.x have introduced.

What are the Collection Type & Sequence Type Protocols?

The Collection Type, Sequence Type & Generator Type Protocols define rules that govern how different data structures or collections of data can be used, interacted with and operated within the Swift programming language. The CollectionType is a special case of the SequenceType.

Why do we need such Protocols?

Lets take the example of the Swift For-Loop.

var arrOfStrings : [String] = [String]()

arrOfStrings.append("Jill")
arrOfStrings.append("Jack")
arrOfStrings.append("John")
arrOfStrings.append("Jane")

for name in arrOfString
{
     print("The name is \(name)")
}

Now, if we have created our own data type. We would not be able to use the above for-loop as it would not conform to the … type protocols. The for-loop is expecting a data structure that acts and behaves in a way that is governed by the … protocols.

Just like the for-loop example above there are many other features within the Swift Programming Language that expect data structures to act and behave in a particular way. By designing our data structures to conform to these protocols we can make the easily compatible with the existing code and language features out there.

How do we use these protocols for our own data structures?

First we need to decide what kind of collection are we making. For the sake of this example I will create a Custom Stack.

class CustomStack<Element>
{
    var data : [Element] = [Element]()

    func push(Element newElement : Element)
    {
        data.append(newElement)
    }

    func pop() -> Element
    {
        return data.removeLast()
    }
}

The above code is very simple for the purpose of this exercise. Its a stack. Which is internally really an Array. It has functions to push data and pop data. We are now going to convert this type to a collection to conform to the CollectionType protocol.

Implementing the Indexable Protocol methods

As a first step we are going to make our CustomStack conform to the Indexable Protocol.

extension CustomStack : Indexable
{
    //INDEXABLE PROTOCOLS
    typealias Index = Int

    var startIndex : Int
    {
        return 0
    }

    var endIndex: Int
    {
        return (data.count - 1)
    }

    subscript (position : Int) -> Element
    {
        return data[position]
    }
}

The above change makes the data structure conform to the Indexable protocol. This is a requirement for it to be of type CollectionType. In order to conform to the Indexable protocol we need to implement a few computed properties. Let us look at the changes

typealias Index = Int

This line informs the system that the Indexing type for my data structure is an Int.

var startIndex : Int
{
    return 0
}

var endIndex: Int
{
    return (data.count - 1)
}

The next 2 are computed properties. Each provides the implementation of the startIndex  and endIndex properties. Note that the type for both is Int as we have declared the Index type earlier as Int.

subscript (position : Int) -> Element
{
    return data[position]
}

The last implementation is of subscript. This provides the implementation to access an Element from the Stack using the Subscript operator.

Implementing the Sequence Type Protocol

Next we will implement the Sequence Type Protocol methods.

extension CustomStack : SequenceType
{
    typealias Generator = AnyGenerator<Element>
    
    func generate() -> Generator
    {
        var index = 0
        
        return AnyGenerator(body: {() -> Element? in
            if index < self.data.count
            {
                let res =  self.data[index]
                index += 1
                return res
            }
            return nil
        })
    }
}

Let us examine this code line by line.

typealias Generator = AnyGenerator<Element>

Objects of type Generator allow us to navigate through our collection. Quite like how iterators  work in C++. This line specifies the type to be AnyGenerator for Elements.

func generate() -> Generator

Next we start the implementation of the generate function. This is required as part of the SequenceType protocol.

var index = 0

This index variable is used to track the element that is currently being accessed.

return AnyGenerator(body: {() -> Element? in
            if index < self.data.count
            {
                let res =  self.data[index]
                index += 1
                return res
            }
            return nil
        })

The return statement is the main statement. Here we are creating an object of type AnyGenerator. As an argument to the constructor call we are passing in a closure that will be used to iterate through the sequence. Note that the closure captures the index variable and holds a reference to its value even though we have left the original function.

Implementing the Collection Type Protocol

Next we will implement the Collection Type Protocol methods. We don’t really need to implement a lot in order to conform to the CollectionType protocol. In fact, if we just conform to the CollectionType protocol and use the implementations of the previous 2 extensions we should be just fine. However, for the sake of demonstration we are implementing the subscript functionality within the CollectionType.

extension CustomStack : CollectionType
{
    typealias SubSequence = CustomStack<Element>
    
    subscript (bounds: Range<CustomStack.Index>) -> CustomStack.SubSequence
    {
        let newStack : CustomStack<Element> = CustomStack<Element>()
        
        for i in bounds.startIndex...bounds.endIndex
        {
            newStack.push(Element: data[i])
        }
        return newStack
    }
}

Let us look at the code line by line.

typealias SubSequence = CustomStack<Element>

Again, as before this line indicates that the SubSequence type is actually a CustomStack.

subscript (bounds: Range<CustomStack.Index>) -> CustomStack.SubSequence

Here we start the implementation of the subscript functionality.

let newStack : CustomStack<Element> = CustomStack<Element>()
        
for i in bounds.startIndex...bounds.endIndex
{
     newStack.push(Element: data[i])
}
return newStack

The rest of the code is the implementation of the subscript range behaviour. One can have different implementations to achieve the same result.

CollectionType Video

Conclusion

As we can see, by designing our data structure to conform to a particular set of protocols. We have made it possible for our data structure to take advantages of the different features, functionalities and even API’s available within the Swift Language and the Frameworks used as a part of iOS, macOS, watchOS & tvOS development.