Migrating to Swift from Objective-C

This article explores some of the advantages and challenges faced by developers while migrating to Swift from Objective-C.

1. Do we want to migrate?

Before you start the migration process remove the old adage:

If it isn’t broken, don’t fix it!

Start by identifying the reasons why you wish to migrate. Here are some possible reasons why.

  • The code is old and not updated for a very long time. You now wish to add new features.
  • The frameworks/libraries you are using in your project have upgraded to modern Swift and no longer support your old Objective-C syntax. *You may still want to just update to modern Objective-C, but this would be a good time to jump onto swift.
  • You see potential for improvement in code size/speed/performance by using new Swift features not available in Objective-C. For example: Generic Programming.
  • The developers who developed the app in Objective-C have left and the new employees are proficient at Swift. *Again not a strong reason, but a valid reason if there is no other alternative. Asking people to sit down and learn Objective-C may not be practical, especially if they don’t have a background in C Programming.
  • The app is due for a performance, stability, & bug fix update. This is a good time to consider migration to Swift.

Factors to keep in mind before considering migration.

  • The cost of migration. This is the cost of keeping a certain number of developers occupied in migrating the code. The cost is in terms of time as well as money.
  • Potential risks. Any change to the code increases the risk of bugs. The chances of introducing limits on backward compatibility also increase.
  • Benefits gained. An assessment needs to be done as to whether there are any benefits of migrating to Swift. The Return on Investment needs to be figured out.
  • Compatibility with 3rd Party or in house libraries that you might use.

After having thought through all this you are ready for the next step: “Prepare to Migrate”

2. Preparing to Migrate

This is where you actually begin to work on the migration of the App.

  1. As a first step perform a full code review of the app.
  2. The next step is a major decision. Should you rebuild your entire app from scratch or do a piece by piece migration. We will explore the advantages a little later in the article.
  3. Look for Swift versions of 3rd frameworks/libraries you use. This is not strictly required, however, this is a good time to check for new APIs.
  4. Identify parts of the project to migrate. This is to be done if it is a piecemeal migration. This marks you as ready for the next step: “Starting the Migration”.

3. Starting the Migration

Once you have everything in place you are ready to begin.

Migrations happen class by class. Select an Objective-C class to migrate and start working on converting it to Swift.

If you have any pure C functions then you can either choose to make them work with Swift or rewrite them in Swift.

While migrating pay special attention to your code. Here are some conversions that you can make.

  • See if you can make it simpler by using Generic Programming instead of usingVoid *
  • Replace the use of NSError * with exceptions.
  • Use extensions to give types new capabilities.
  • Consider creating your own Data structures. You may use Swift Arrays, Dictionaries if you wish. But this might be a good time to improve performance by building your own data structures.
  • Embrace closures and protocols a lot more.
  • Make extensive use of the @available attribute to describe your changes and mark availability
  • Start incorporating Swift Markup to make the comments from your Objective-C code more readable.
  • Enums pulled in from Objective-C can be made more powerful in Swift by adding methods which work with enums as a part of the enum itself.
  • Use property observers to make code more reactive. In some situations this might be easier than setting observers.

Migration Steps

Here are some general steps you can follow. The steps below are for both a full app conversion or a piece meal conversion.

Note: The steps mentioned below are sample steps and not necessarily the only way to achieve this.
  1. If its a full app conversion then create a new project. Else duplicate the existing project.
  2. Start by looking for the frameworks you need and importing them in the necessary Swift files.
  3. Identify class(es) that you have in your Objective-C project. Start by creating empty versions of those in your Swift project. It is very likely that you may not need all the classes as you might be optimising or reworking your App’s architecture. Also it is possible that you may need new classes.
  4. Next identify data structures used in the class. Either convert them to their swift equivalents or explore other options.
  5. Migrate the functions directly associated with the data structures.
  6. Migrate the variables used in the Objective-C class.
  7. Lastly migrate the remaining functions to Swift.
  8. Do this till you have converted all the classes that you wish to convert.

One point left to talk about is testing. Thoroughly test you app after each step you complete. If you are using XCTests, migrate a single Unit test at a time. Corresponding to the changes that you have made above.

5. Things to watch out for

There are many things to keep in mind while migrating your code.

  • In a mixed language project (Swift and Objective-C) Swift only features won’t be supported. So Generic Programming cannot be implemented.
  • Blind copying of the code from Objective-C to Swift may not result in the best output. Try to examine each line for potential optimisation opportunities.
  • Watch out for OS version compatibility. You may have to choose your Swift version accordingly.

6. Full Conversion versus Part by Part Conversion

Full Conversion

PROS:

  • The advantage of building the app from scratch is that your overall development time is less as different parts of the app can be refactored at development time.
  • You also have the advantage of adopting new development approaches or architectures such as Model View View Model (MVVM) or Test Driven Development (TDD).
  • You are in a better position to take advantage of all the Swift features as there won’t be any challenges with compatibility.
  • The advantages of Swift viz: Speed, Safety, and compact code are more easily achieved
  • If you want to support older versions of iOS then having a pure Swift and pure Objective-C version helps.

CONS:

  • Of course this means that your development time is large.
  • There is a potential for writing duplicate code in Swift especially if it is being reused in Objective-C projects. You may end up with 2 code bases for the same feature.

Part Conversion

PROS:

  • The advantage of migrating parts of your app is that you can split the migration over a larger period and use your resources on other projects.
  • In terms of cost this is less expensive and more resource friendly
  • The potential for duplicate code is reduced

CONS:

  • But on the flip side every time you take a new part to migrate you will have to make changes to the Swift code written earlier. This increases the development time and may affect the quality of the app in the long run.
  • You cannot take advantages of all the Swift features.
  • There is a chance that once the migration is complete the App may have to undergo an overhaul to take advantage of the Swift features & improve on Speed, Safety & Size.

This article just talks about some of the advantages and challenges with Migration to Swift. There are multiple approaches available and you will have to pick and choose the approach based on your needs or situation. I had written an article some time back about choosing between Swift & Objective-C, you can have a look at that too. Here is an article, for your reference, written by Apple on Migrating to Swift. Good luck & Happy Programming! Do feel free to share your experience migrating to Swift.

 

Advertisements

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.

 

Automation on the Mac

Automating tasks on the Mac is very useful for a wide variety of reasons. In this article we are going to look at the different technologies available for automating tasks.

TOOLS

Automator

The simplest way of achieving automation. Automator which is a built in application allows you to create task workflows by simply dragging in a set of predefined routines into a specified sequence. Let us explore how it works by creating a watermarking print plugin

Let us look at how we can create a print plugin that automatically adds a watermark to the pdf file.

  1. First get hold of an image that you will use as a watermark.
  2. Open Automator.
  3. Click on “New Document”
  4. Choose Print Plugin as the type of task to createScreen Shot 2018-03-21 at 11.58.26 AM
  5. From the left hand side drag the “Watermark PDF Documents” option. You will be able to locate this from the PDF library on the extreme right.1
  6. Add the image that will be used as a watermark. Customise the settings to your desired level. You may have to use trial and error till you get the desired output.
  7. Similarly drag the Move finder Items to the right. You will be able to locate this from the Files & Folders library.2
  8. Save the task as WatermarkCreator.
  9. Open a text file.
  10. Select File > Print
  11. Click on the PDF drop down in the print dialog.3.4
  12. Select the newly created task.
    3
  13. You have now successfully setup your own watermark creator.

Shell Scripting

For those coming from a Linux/Unix background this might be a familiar option. Very often users need to run a series of terminal commands repeatedly. While it is not difficult to do this, wouldn’t it be nice if we could write all the commands in a single file? Shell Scripts help users do just that.

To create a shell script:

  1. Open TextEdit
  2. Write the following code in there (We will write code to create a series of files and folders in our home folder for a user called admin):
    #! /bin/sh
    cd /Users/admin/
    if [ -d "/Users/admin/Applications/" ]; then
        echo "Applications Folder Exists"
    else
        mkdir Applications
    fi
    if [ -d "/Users/admin/Sites/" ]; then
        echo "Sites Folder Exists"
    else
        mkdir Sites
    fi
    if [ -d "/Users/admin/Developer/" ]; then
        echo "Developer Folder Exists"
    else
        mkdir Developer
    fi
    cd Developer
    if [ -d "/Users/admin/Developer/iOSProjects/" ]; then
        echo "iOSProjects Folder Exists"
    else
        mkdir iOSProjects
    fi
    if [ -d "/Users/admin/Developer/macOSProjects/" ]; then
        echo "macOSProjects Folder Exists"
    else
        mkdir macOSProjects
    fi
    
  3. Save the file with the name FolderCreator on the Desktop.
  4. Open the Terminal Application
  5. Let us make the script executable. To do that, run the commands:
    cd ~/Desktop
    chmod 777 FolderCreator
    
  6. Now run the command:
    ./FolderCreator

You have now easily created your own shell script. For more information about terminal commands you can read the following articles: Terminal Commands for OS X – BasicTerminal Commands for OS X – Part 2Terminal Commands – Part 3, & Configuring/Troubleshooting OS X Using Command Line

AppleScript

AppleScript is Apple’s proprietary scripting technology. It comes bundled as a part of macOS. To create AppleScript tasks we need to use the built in AppleScript editor.

Here is an example of a small AppleScript

tell application “Finder” to set the view for all Finder Windows as column view
tell application “Finder” to close every Finder Window
tell application “Safari”
open location “<a href="http://www.arunpatwardhan.com">http://www.arunpatwardhan.com</a>
open location “<a href="http://www.amaranthine.in/feedback">http://www.amaranthine.in/feedback</a>
open location “<a href="http://www.amaranthine.in/gallery">http://www.amaranthine.in/gallery</a>
end tell

Copy that block of commands in your AppleScript editor and see what comes up.

There are many more things that can be done with AppleScript. You can have popup windows asking users for commands, turn off the computer. Change the settings for different parts of the OS and for different applications. All this with commands written in a single file. All the user has to do is double click the file.

For more information about AppleScript visit Apple’s Developer site.

Launch Agents, Launch Daemons

NOTE: Scheduling Launch Agents/Launch Daemons improperly may leave your computer in an unusable state. Always test this on a computer that does not contain important data. If you are unsure, please consult someone with knowledge of the same before proceeding ahead.

Launch Agents/Launch Daemons allow you to schedule tasks which are to be performed at intervals. You can also use them to ensure that tasks are kept running and that the user does not have the possibility to quit them. To setup a launch daemon:

  1. First create a Plist file that looks like the one below. I have created a script called echoer and placed it in the /Users/admin/Applications folder where admin is the user.Screen Shot 2018-03-22 at 10.34.18 AM
  2. Place the file in the ~/Library/LaunchAgents folder. Name it in.amaranthine.demod.plist
  3. Run the command in terminal to load the Launch Agent.
    launchctl load ~/Library/LaunchAgent/in.amaranthine.demod.plist

That’s it you have just setup a simple launch agent which will ensure that your script runs every 6 seconds.

For more information or to create detailed Launch Agents/Launch Daemons visit:Creating Launch Agents & Launch Daemons

Login Items

An easy way to automatically load, Applications/Files/Folder, as soon as well login is to use Login Items. This is very easy to do.

  1. Open System Preferences > Users & Groups
  2. Switch to the Login Items tab.IMG_1560
  3. Click on the ‘+’ sign at the bottom to add new Applications. Let’s add Maps so that it launches as soon as we login. You should see it appear in the list.IMG_1561

That’s it. You have setup login items. You can repeat this process for as many applications as you wish.

Others

PHP, Perl, Python, Javascript, Swift allow you to create custom automated tasks and routines. These require knowledge of programming.

Choosing the right approach

Which one to choose depends on a lot of factors but we can break it down to 2:

  • You are a technically qualified person and understand things like programming, scripting and command line
  • You are an end user working either at home or in office.

End User

If you are an End user then you should really stick to Automator and Login Items. These are the ones that are the easiest to implement and least likely to cause any issues. You could venture and explore other options if you have a good understanding of them. Or you can ask the IT or Tech Support teams to help you with scripting and other technologies.

Tech Support or IT Person

Any of the tools mentioned above can be used by you. Make sure that you have a good command over the tools and are able to troubleshoot issues arising out of their usage.

Note: The programs/applications/tools and languages mentioned in this article may not cover all the available options. Also, anyone who uses or implements the items mentioned in the article does so at their own risk. The author does not take responsibility for any loss or damage that may arise from the use of the programs/applications/tools and languages mentioned above.

 

Screen and Audio recording on macOS & iOS

In this article we are going to look at how we can use the built in Application: QuickTime to record a screen or a movie. In fact, the videos that you are about to see in the article below were created using QuickTime.

A good reason to record the activity on the screen would be to create a visual step by step guide which can be distributed to employees in the organisation. For example, you can create a video to show employees how they can sign into their company’s email account and access it from their iPhone or Mac.

Recording your Mac’s screen

Follow the steps given below to record your Mac’s screen:

  1. Open QuickTime Player
  2. Click on File > New Screen RecordingScreen Shot 2018-01-24 at 4.46.22 PM
  3. You should see the window popping up.
  4. From the drop down next to the Record button select the audio input & whether mouse clicks should be shown.Screen Shot 2018-01-24 at 4.47.29 PM
  5. Click on the Record Button. You should see a dialog asking you whether you want to record a small area or a full screen.Screen Shot 2018-01-24 at 4.47.52 PM
  6. The recording starts once the stop button in the menu bar becomes dark.
  7. Click on the stop button to stop the recording.
    Screen Shot 2018-01-24 at 4.57.49 PM
  8. Save the file that was created.

Recording your iPhone/iPad Screen

(Mirroring your iPhone Screen on the Projector)

The process of recording the iPhone/iPad screen is quite similar to recording your computer’s screen. The key thing to remember is to connect your iPhone/iPad to the Mac with the lightning cable.

Follow the steps given below to record your iPhone/iPad screen:

  1. Open QuickTime Player
  2. Click on File > New Movie Recording
  3. You should see the window popping up.
  4. From the drop down next to the Record button select the audio input & whether mouse clicks should be shown. The difference now is the fact that you get an extra option to choose the source.

Recording a Movie

Follow the steps given below to record a Movie on your Mac:

  1. Open QuickTime Player
  2. Click on File > New Movie RecordingScreen Shot 2018-01-29 at 4.11.38 PM
  3. You should see the window popping up.
  4. From the drop down next to the Record button select the audio input. You can also select your camera source from here.
    Screen Shot 2018-01-29 at 4.21.41 PM
  5. Click record to start recording & click on the stop button to stop recording.

Recording Audio

Follow the steps given below to record an Audio on your Mac:

  1. Open QuickTime Player
  2. Click on File > New Audio RecordingScreen Shot 2018-01-29 at 4.11.38 PM copy
  3. You should see the window popping up.
  4. From the drop down next to the Record button select the audio input.
  5. Click record to start recording and stop to stop recording.

Here is a quick video on how to perform the different tasks that we have seen above.

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.

Adding formatted text to Swift in Xcode

Formatting in Playgrounds and Xcode projects is achieved using Markups in comments. The following article describes some of the things that you can do. Note that there are many more ways of acheiving some of the effects shown here.

The idea behind markups is to make your code more readable whether you are using Playgrounds or Xcode.

If you can only see the commented code in playgrounds and not the rendered markup then click on Editor > Show Rendered Markup to view the rendering. You can use this option to toggle back and forth.

Formatting in Playgrounds

Plain Text

There are different kinds of text you can place in a Playground. Let us look at the code below to see what all is achieved.

//: # Documentation
//: ## Contents
//: * Text Description
//: * Documentation for Functions
//: * Documentation for Types
//: * Formatting Text
//:  - Code
//:  - Italics
//:  - Bold
//: * Inserting Items
//: * Links
//: * Assets
//: * Callouts

The comments here are in the format //:.

Rendered Output

This is how the rendered output looks.

Line 1 shows how to render a Title Text. This is achieved using the # before the text.
Line 2 shows how to get a lower sized text by using ## instead of #. We can achieve more levels if we wish.

For multi line text with bullets use the *, +, – symbols. This is seen on lines 7-13.

It is also possible to create numbered lists too. Simply type the numbered list & it renders accordingly.

//: * Inserting Items
//: 1. Links
//: 2. Assets
//: 3. Callouts

This renders as:

Screen Shot 2017-11-08 at 11.25.27 AM

Playground Pages

It is possible to have multiple pages in Playgrounds. This way we can create a more readable experience that makes the code structured, compartmentalised and easier to understand.

To do that open a playground and then simply add a playground by clicking File > New > Playground Page.

To move from one page to the next simply write the comment.

//: [Next Topic](@next)

This will automatically place a link to jump to the next page.

Similarly you can add a link to move to the previous page.

//: [Previous](@previous)

Code block

We can even show a code block in the text. It is formatted in a different manner to tell the user that it is a code block.

//: ### Code block
/*:
Loop to print characters
````
for char in "Arun Patwardhan"
{
    print(char)
}
*/

This is how it appears:

Screen Shot 2017-11-08 at 11.30.45 AM

Function Help

There is also some formatting that can be done for functions, types and other pieces of code written in a playground. This also appears on the quick help of the sidebar.

We will look at how to create formatted markup for playgrounds.

/*:
## This function takes temperature in Centigrade and converts it to Fahrenheit.
- important: This function does not do data validation
*/
/*:
- Note: "Please refer to Quick Help for more information."
*/
/*:
- Callout(Custom Callout): This is how you create a custom callout ` - Callout(Custom Callout):`
*/
/*:
- Example: `convert_to_fahrenheit_from(Centigrade: 32.0)`
*/

This renders as:

Formatted Markup for Functions

Formatted Markup for Functions.

We will look at formatting the comments to appear in Quick Help in the Formatting for Xcode section.

Inserting Links

The last bit is related to inserting links. We have already seen how to insert links for moving between Playground pages.

Redirecting to URL

/*:
For more articles on Programming, see [Programming articles @ arunpatwardhan.com](https://arunpatwardhan.com/category/programming/)
*/

This renders as:

Screen Shot 2017-11-09 at 11.14.24 AM

Formatting for Xcode

Function Help

As we saw in the earlier section we can create a lot of documentation for Functions. The approach is similar to the one we used in Playgrounds. We will be using callouts to provide information. We will use some callouts for Playgrounds, however, there are many more callouts available for Xcode Symbol Documentation as compared to Playground. The main difference here is the fact that the comments begin with /** instead of /*:.

“The code shown below will work in both, regular Xcode projects as well as Playgrounds.”

/**
This function takes temperature in Centigrade and converts it to Fahrenheit.
- important: This function does not do data validation
- parameter temp: This is the temperature in Centigrade. It can be a negative value too.
- returns: This is the temperature in Fahrenheit.
- requires: `temp > -273.0 && temp < 1000.0` - Note: The requirement mentioned is not enforced. - Since: iOS 11 - author: Arun Patwardhan - copyright: Copyright (c) Amaranthine 2015 - version: 1.0 */
func convert_to_fahrenheit_from(Centigrade temp : Float) -> Float
{
    return ((temp * 9.0 / 5.0) + 32.0)
}

This renders as:

Formatted Markup for Playgrounds as well as Quick Help

Formatted Markup for Playgrounds as well as Quick Help

Note that the quick help appears in the Right hand side sidebar. That too only after you select the function.

As we can see this makes the function a lot more readable. The real advantage of Quick Help comes in the fact that the documentation is now easily accessible no matter which file we are in within the project. The also helps the developer put in the right kind of information, required for proper usage of the function, in the help section.

Note that the rendered markup for Playgrounds will only appear in Playgrounds. 

Inserting Links

Just like in the previous section where we introduced links we can add links to the symbol documentation.

/**
   For more articles on Programming [Programming articles @ arunpatwardhan.com (https://arunpatwardhan.com/category/programming/)
*/
func recursiveFunction(count : inout Int)
{
   while 0 <= count
   {
      count -= 1
      recursiveFunction(count: &count)
   }
}

This renders in Quick Help as:

Screen Shot 2017-11-09 at 11.26.53 AM

Callouts supported by Playgrounds

  • Custom Callout
  • Example

Callouts supported by Symbol Documentation

  • Attention
  • Author
  • Authors
  • Bug
  • Complexity
  • Copyright
  • Date
  • Invariant
  • Precondition
  • Postcondition
  • Remark
  • Requires
  • See Also
  • Since
  • Version
  • Warning

Callouts supported by both Playgrounds & Symbol Documentation

  • Experiment
  • Important
  • Note

Programming Style Guide: Code Refactoring

One of the key attributes towards code that is readable and easy on the eyes is code that is split into appropriately sized pieces. Code refactoring is does exactly that. It is very easy to write a program as one big piece of code. Of course, any program that grows becomes increasingly complicated and highly inefficient. If not controlled, it will soon reach a point where it is highly unreadable, extremely difficult to maintain & filled with bugs. Not to mention that it is inefficient too.

Refactoring code and breaking it down into smaller reusable chunks is the key. The objective is:

  1. To make code easier to read
  2. To make reusable components so that we can save on duplication of code. This will reduce the code count and make sure that any changes to the reused code are available everywhere.
  3. To lend a structure to the application. Tasks now have their own space.
  4. Build scalable and maintainable code.
  5. Build bug free code.

Let us look at an example.

Screen Shot 2017-10-16 at 11.26.26 AM

Bad Code

This code is clearly written poorly. Its difficult to read. There aren’t good whitespaces. No consistency. Even the naming conventions are poor.

The fix would be :

  • Break it down into different functions
  • Separate tasks into their own files
  • Name the different elements of the code properly.

This is how the code looks now. It has been broken down into different files.

main.cpp

#include <iostream>
#include "MathOperations.hpp"
#include "Choices.hpp"

int main(int argc, const char * argv[])
{
     float number1           = 0.0;
     float number2           = 0.0;
     Choices selectedOption  = CLEAR;
     float answer            = 0;
     float integralAnswer    = 0;

     while(EXIT != selectedOption)
     {
          //Welcome message
          std::cout<<"Welcome to Calculator Program"<<std::endl;
          std::cout<<"Choose between the following options"<<std::endl;
          std::cout<<"1. Add\n2. Subtract\n3. Multiply\n4. Divide\n5. Remainder\n6. Percentage"<<std::endl;

          //User choice
          std::cout<<"Choice: ";                               std::cin>>selectedOption;

          //Chance to enter first number
          std::cout<<"Number 1: ";                               std::cin>>number1;

          //Chance to enter second number
          std::cout<<"Number 2: ";                               std::cin>>number2;

          switch (selectedOption)
          {
               case ADDITION:
                    answer = addition(number1, number2);
                    std::cout<<"The addition of "<<number1<<" & "<<number2<<" = "<<answer<<std::endl;
                    break;
               case SUBTRACTION:
                    answer = subtraction(number1, number2);
                    std::cout<<"The subtraction of "<<number1<<" & "<<number2<<" = "<<answer<<std::endl;
                    break;
               case MULTIPLICATION:
                    answer = multiplication(number1, number2);
                    std::cout<<"The multiplication of "<<number1<<" & "<<number2<<" = "<<answer<<std::endl;
                    break;
               case DIVISION:
                    answer = division(number1, number2);
                    std::cout<<"The division of "<<number1<<" & "<<number2<<" = "<<answer<<std::endl;
                    break;
               case REMAINDER:
                    integralAnswer = remainder((int)number1, (int)number2);
                    std::cout<<"The remainder of "<<number1<<" divided by "<<number2<<" = "<<integralAnswer<<std::endl;
                    break;
               case PERCENTAGE:
                    answer = percentage(number1, number2);
                    std::cout<<"The percentage of "<<number1<<" out of "<<number2<<" = "<<answer<<span 				data-mce-type="bookmark" 				id="mce_SELREST_start" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			></span><std::endl;
                    break;
               default:
                    break;
          }
     }
     return 0;
}

Choices.hpp

#ifndef Choices_hpp
#define Choices_hpp

#include <stdio.h>
#include <iostream>

enum Choices : unsigned short int { ADDITION = 1, SUBTRACTION, MULTIPLICATION, DIVISION, REMAINDER, PERCENTAGE, CLEAR, EXIT};

typedef enum Choices Choices;

std::istream& operator >>(std::istream &is, Choices& enumVar);

#endif

Choices.cpp

#include "Choices.hpp"

std::istream& operator >>(std::istream &is, Choices& enumVar)
{
    unsigned short int intVal;
    is>>intVal;
    switch (intVal) {
        case 1:
            enumVar = ADDITION;
            break;
        case 2:
            enumVar = SUBTRACTION;
            break;
        case 3:
            enumVar = MULTIPLICATION;
            break;
        case 4:
            enumVar = DIVISION;
            break;
        case 5:
            enumVar = REMAINDER;
            break;
        case 6:
            enumVar = PERCENTAGE;
            break;
        default:
            enumVar = EXIT;
            break;
    }
    return is;
}

MathOperations.hpp

#ifndef MathOperations_hpp
#define MathOperations_hpp

#include <stdio.h>

//Addition
float addition(float number1, float number2);

//Subtraction
float subtraction(float number1, float number2);

//Multiplication
float multiplication(   float number1, float number2);

//Division
float division(float number1, float number2);

//Remainder
int remainder(int number1, int number2);

//Percentage
float percentage(float number1, float number2);

#endif

MathOperations.cpp

#include "MathOperations.hpp"

//Addition
float addition(float number1, float number2)
{
    return number1 + number2;
}

//Subtraction
float subtraction(float number1, float number2)
{
    return number1 - number2;
}

//Multiplication
float multiplication(   float number1, float number2)
{
    return number2 * number1;
}

//Division
float division(float number1, float number2)
{
    if (number2 > 0) {
        return number1 / number2;
    }
    return 0.0;
}

//Remainder
int remainder(int number1, int number2)
{
    return number1 % number2;
}

//Percentage
float percentage(float number1, float number2)
{
    if (number2 > 0) {
        return (number1 / number2) * 100.0;
    }
    return 0.0;
}

Let us look at how this looks for Swift.
main.swift

import Foundation

var number1 : Float             = 0.0
var number2 : Float             = 0.0
var selectedOption : Choices    = Choices.CLEAR
var answer : Float              = 0.0
var integralAnswer : Int        = 0

func readNumbers(One firstNumber : inout Float, Two secondNumber : inout Float)
{
     //Chance to enter first number
     print("Number 1: \n")
     firstNumber = Choices.inputNumbers()

     //Chance to enter second number
     print("Number 2: \n")
     secondNumber = Choices.inputNumbers()
}

while(Choices.EXIT != selectedOption)
{
     //Welcome message
     print("Welcome to Calculator Program")
     print("Choose between the following options")
     print("1. Add\n2. Subtract\n3. Multiply\n4. Divide\n5. Remainder\n6. Percentage")

     //User choice
     print("Choice: \n")
     selectedOption = Choices.inputChoices()
     switch (selectedOption)
     {
          case Choices.ADDITION:
               readNumbers(One: &number1, Two: &number2)
               answer = addition_of(_value: number1, with_value: number2)
               print("The addition of \(number1) & \(number2) = \(answer)")
               break
          case Choices.SUBTRACTION:
               readNumbers(One: &number1, Two: &number2)
               answer = subtraction_of(_value: number1, from_value: number2)
               print("The subtraction of \(number1) & \(number2) = \(answer)")
               break
          case Choices.MULTIPLICATION:
               readNumbers(One: &number1, Two: &number2)
               answer = multiplication_of(_value: number1, with_value: number2)
               print("The multiplication of \(number1) & \(number2) = \(answer)")
               break
          case Choices.DIVISION:
               readNumbers(One: &number1, Two: &number2)
               answer = division_of(_value: number1, by_value: number2)
               print("The division of \(number1) & \(number2) = \(answer)")
               break
          case Choices.REMAINDER:
               readNumbers(One: &number1, Two: &number2)
               integralAnswer = remainder_of(_value: Int(exactly:number1)!, <span 				data-mce-type="bookmark" 				id="mce_SELREST_start" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			></span>divided_by_value: Int(exactly: number2)!)
               print("The remainder of \(number1) divided by \(number2) = \(integralAnswer)")
               break
          case Choices.PERCENTAGE:
               readNumbers(One: &number1, Two: &number2)
               answer = percentage_of(_value: number1, with_respect_to_value: number2)
               print("The percentage of \(number1) out of \(number2) = \(answer)")
               break
          default:
               selectedOption = .EXIT
               break
     }
}

Choices.swift

import Foundation

enum Choices { case ADDITION, SUBTRACTION, MULTIPLICATION, DIVISION, REMAINDER, PERCENTAGE, CLEAR, EXIT}

//CLI Reading Capability
extension Choices
{
    static func inputChoices() -> Choices
    {
        let ip : String? = readLine()
        let choice : String = String(ip!)

        switch choice {
        case "1":
            return .ADDITION
        case "2":
            return .SUBTRACTION
        case "3":
            return .MULTIPLICATION
        case "4":
            return .DIVISION
        case "5":
            return .REMAINDER
        case "6":
            return .PERCENTAGE
        default:
            return .EXIT
        }
    }

    static func inputNumbers() -> Float
    {
        let ip : String? = readLine()

        let numberFormatter = NumberFormatter()
        let number = numberFormatter.number(from: ip!)

        let num : Float? = number?.floatValue
        return num!
    }
}

MathOperations.swift

import Foundation

//Addition
func addition_of(_value number1 : Float, with_value number2 : Float) -> Float
{
    return number1 + number2;
}

//Subtraction
func subtraction_of(_value number2 : Float, from_value number1 : Float) -> Float
{
    return number1 - number2;
}

//Multiplication
func multiplication_of(_value number1 : Float, with_value number2 : Float) -> Float
{
    return number2 * number1;
}

//Division
func division_of(_value number1 : Float, by_value number2 : Float) -> Float
{
    if (number2 > 0) {
        return number1 / number2;
    }
    return 0.0;
}

//Remainder
func remainder_of(_value number1 : Int, divided_by_value number2 : Int) -> Int
{
    return number1 % number2;
}

//Percentage
func percentage_of(_value number1 : Float, with_respect_to_value number2 : Float) -> Float
{
    if (number2 > 0) {
        return (number1 / number2) * 100.0;
    }
    return 0.0;
}

Discussion on Swift Extensions

As we can see that most of the code in Swift is very similar to C++. Most of the differences are basic syntactic differences. However, there is 1 feature of Swift that greatly aids code refactoring that I would like to talk about, Extensions.

Extensions allow us to add new functionality to the existing type. As the name says the type is extended. This allows us to add changes to a type in a consistent & clearly demarcated way. Developers can now neatly separate newly added components. This greatly helps in understanding the evolution of types.

“This is often referred to as versioning.”

Extensions can be used in the following ways to implement code refactoring:

  • Different sections of a type reside in their own extensions
  • Changes made to a type are made by keeping them in their own extensions
  • Step by step build up of code is done by representing each step as an independent extension. This gives clarity on how a certain end result was achieved.

Conclusion

As we can see from the sample code above (for both C++ & Swift) the program is much more readable. Code is carefully compartmentalised. Its a lot easier to read. It is a lot easier to scale too.

The reader may point out that the amount of code to achieve the same result is significantly higher, that however is a small price to pay in the long run. The biggest advantage is the scalability & the ease with which it can be done. Simply breaking code down into separate files & functions makes a huge difference. Here are some other benefits:

  • Individual files can be modified. This means one can now have a team working on different parts of the code.
  • Code is less cluttered. Changes are now spread across files & are easier to track.

We will now see how we can further improve this code in upcoming articles.

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.

macOS & iOS IT Tool List

This list is based on questions that I have been asked by various IT admins.

It is more of a collection of tools (mainly software, but a few hardware tools too) that Enterprise IT Teams might find useful while supporting/managing Macs & iPhones in the enterprise. Some of the tools are free, while others are paid. Also, it is not necessary that all the tools will be required. Of course, some tools are not meant for troubleshooting but provide a service themselves.

The below list is not an endorsement or recommendation of any of the products mentioned. These are just some of the products I have come across. You may have to do your own research to see which tool fits your organisation’s needs. The author is not responsible for any damages or loss of data that might occur from usage of these tools.

*This list is not a complete list but an ongoing project. Feel free to share your comments on tools that you may have used & I will add them to this list.

DEPLOYMENT

DeployStudio

Munki

macOS Server – NetInstall Service. To be used along with System image Utility

PACKAGE MANAGEMENT

Iceberg

pkgbuild

REMOTE MANAGEMENT

RealVNC

TeamViewer

Apple Remote Desktop

LogMeIn

BACKUPS

macOS Server – Time Machine Service

Retrospect

Carbon Copy Cloner

Chronosync

Crash Plan

DEVICE MANAGEMENT

Centrify

JAMF Casper Suite

AirWatch

Mobile Iron

macOS Server – Profile Manager Service

Apple Configurator 2

Heat LANRev

Cisco Meraki

filewave

Absolute Software

BoxTone

Maas 360 – IBM

Tangoe

Lightspeed Systems

VIRTUALIZATION

Parallels Desktop

VMWare Fusion

Oracle VirtualBox

DISK MANAGEMENT

Tuxera

Disk Drill

APPLE APPLICATIONS FOR THIRD PARTY OS

iTunes

iCloud Control Panel

Move to iOS from Android

Migration Assistant

AUTOMATION

Workflow for iOS

Automator – Built in app for creating Workflows.

AppleScript

Command Line Script

NETWORK TROUBLESHOOTING

iNetTools

Network Diagnostics

Network Ping

Wireshark

DISPLAY

Air Squirrel

SYSTEM TROUBLESHOOTING

Install Disk – I will be talking about how to create a multi-OS install disk in a later article.

SOFTWARE MANAGEMENT

macOS Server – Caching Service

Reposado

AutoPKG

Munki

HARDWARE

Thunderbolt 1,2,3 Cables
Thunderbolt 1,2
USB-C Cable

FireWire 400/800 Cables

Portable disk with macOS installed on it. Not the same as install disk. Its an external bootable hard drive with the OS installed on it. You can plug this into any Mac & boot from the external HDD.

VGA to MiniDisplay adapter

HDMI to HDMI Cable

Thunderbolt Ethernet Bridge

USB Ethernet Bridge

Adapters for the different ports supported by Macs & iPhones

Lightning Cables