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.

 

Advertisements

Using Swift Package Manager

About Swift Package Manager

The Swift Package Manager is the tool used to build Applications and Libraries. it streamlines the process of managing multiple Modules & Packages. Before we go ahead and learn to use Swift Package Manager we need to get familiar with some basic terminology.

Modules

Modules are used to specify a namespace and used to control access to that particular piece of code. Everything in Swift is organised as a module. An entire app can fit into a module or an app can be made using multiple modules. The fact that we can build modules using other modules means that reusing code becomes a lot easier. So, when we make an iOS App with Xcode and Swift. The entire app is considered a single module.

Targets

Targets are the end product that we want to make. So an app for iOS is a separate target. A library is a target. An app for macOS is a separate target. You can have many targets. Some can be for testing purposes only.

Packages

Packages group the necessary source files together. A package can contain more than one target. Normally one would create a package for a family of products. For example: you want to make a photo editing app that runs on macOS & iOS. You would create one package for it. That package would have 2 targets: an iOS App & a macOS App.

Products

This is a categorisation of your packages. There are 2 types of products. Executables or Libraries. A library contains the module which can be reused elsewhere. Executables are application that run & may make use of other modules.

Dependencies

Dependencies are the modules or the pieces of code that are required to make the different targets within the package. These are normally provided as URLs.

End Products

*NOTE: Before you get started you must be familiar with Setting up Swift on Linux. If you haven’t done that then please go through the updated article: UPDATE: Swift on Linux. This also makes use of Swift Package Manager.

Example

So let us get started with an example. We are going to learn how to create:

  • a library package called ErrorTypes
  • a library package, called MathOperations, that uses the ErrorTypes library package
  • an executable package called Calc that makes use of the MathOperations package.

We will see how to create all three elements. Also I have uploaded the ErrorTypes & MathOperations packages to the http://www.github.com repository to demonstrate the use of dependencies. You can also create your own local git repositories if you wish.

To illustrate the folder hierarchy: I have created a folder called “Developer” in my Ubuntu linux home folder. Within that I have created a folder called “SPMDEMO“. All the paths that I will be using will be with reference to these folders. You should see a structure like this:

/home/admin/Developer/SPMDEMO/ErrorTypes
/home/admin/Developer/SPMDEMO/MathOperations
/home/admin/Developer/SPMDEMO/Calc

You are free to follow this exercise using your own folder locations. Just modify the paths accordingly.

swift package init
swift package init --type executable
swift build

If you need help with the commands run:

swift package --help
swift --help

Creating a Package

  1. First let us start off by creating the ErrorTypes package.
    mkdir ErrorTypes
  2. Navigate to the folder and create the package:
  3. cd ErrorTypes
    swift package init
    

    By default init will create a library package type.

  4. Navigate to the folder containing the source files:
    cd ./Sources/ErrorTypes/
  5. Open the ErrorTypes.swift file and write the following code
    public enum ErrorCodes : Error
    {
         case FileNotFound(String)
         case DivideByZero(String)
         case UnknownError(String)
    }
    
    public struct MathConstants
    {
         static let pi : Float = 3.14159
         static let e  : Float = 2.68791
    }
    

    Feel free to add some code of your own. The above is just an example.

  6. Run the command to build to make sure that there aren’t any issues. You shouldn’t have any as there are no dependencies of any kind. Its a simple straightforward piece of code.
    swift build
  7. If everything is fine check your code into a git repository. This can be local or on the web. Remember that we will need the URL to this repository.
  8. Navigate back to the SPMDEMO folder.
    cd ~/Developer/SPMDEMO/
  9. Create a folder called MathOperations.
    mkdir MathOperations
  10. Navigate to the newly created folder and run the command to create a library package.
    cd MathOperations
    swift package init
    
  11. Navigate to the sources folder:
    cd ./Sources/MathOperations/
  12. Open the MathOperations.swift file and write the following code.
    import ErrorTypes
    
    public struct MathOperations
    {
         public static func add(Number num1 : Int, with num2 : Int) -> Int
         {
              return num1 + num2
         }
    
         public static func mult(Number num1 : Int, with num2 : Int) -> Int
         {
              return num1 * num2
         }
    
         public static func div(Number num1 : Int, by num2 : Int) throws -> Int
         {
              guard num2 > 0
              else
              {
              throw ErrorCodes.DivideByZero("You are dividing by zero. The second argument is incorrect.")
              }
    
              return num1 / num2
         }
    
         public static func sub(_ num1 : Int, from num2 : Int) -> Int
         {
              return num2 - num1
         }
    }
    
  13. Before we build we need to modify the Packages.swift file to indicate there is a dependency.
    Notice that in the MathOperations.swift file we are importing a module called ErrorTypes. We just created it. But just because we created it doesn’t mean it will be added automatically. We need to pull that module into our own

    Also notice that I have provided access specifiers “public” everywhere. This ensures that the code written in one module is accessible in the other.

    Navigate to the MathOperations parent folder.

    cd ~/Developer/SPMDEMO/MathOperations/
  14. Open the Packages.swift file and make the changes as shown below:
    // swift-tools-version:4.0
    // The swift-tools-version declares the minimum version of Swift required to build this package.
    
    import PackageDescription
    
    let package = Package(name: "MathOperations",
         products: [
              // Products define the executables and libraries produced by a package, and make them visible to other packages.
              .library(name: "MathOperations", targets: ["MathOperations"]),
         ],
    
         dependencies: [
              // Dependencies declare other packages that this package depends on.
              .package(url:"https://github.com/AmaranthineTech/ErrorTypes.git", from:"1.0.0"),
         ],
    
         targets: [
              // Targets are the basic building blocks of a package. A target can define a module or a test suite.
              // Targets can depend on other targets in this package, and on products in packages which this package depends on.
              .target(name: "MathOperations", dependencies: ["ErrorTypes"]),
              .testTarget(name: "MathOperationsTests", dependencies:   ["MathOperations"]),]
    )
    
  15. Once these changes are made save the file and run the command
    swift build

    If you typed everything correctly then you should see the source code for the ErrorTypes module being pulled in and the build being successful.Here are some common mistakes:
    – Forgetting to write the import ErrorTypes statement
    – Error in the URL
    – The from tag not matching the tag in the repository
    – Access specifiers are incorrect or missing
    – Not mentioning the dependencies in the target

  16. Just like with the ErrorTypes module create a git repository for the MathOperations module.
  17. Now let us make the Calc executable that will use the MathOperations library. First navigate back to the SPMDEMO folder and create a folder called Calc.
    cd ~/Developer/SPMDEMO/
    mkdir Calc
    
  18. This time we are going to create an executable package. Run the command:
    swift package init --type executable

    This also creates a similar folder structure as in the case of the library.

  19. Navigate to the folder containing the main.swift file.
    cd ./Sources/Calc/
  20. Modify the main.swift file as shown below:
    import MathOperations
    
    //testing addition
    var result : Int = MathOperations.add(Number: 33, with: 29)
    print("Result of adding 33 with 29 is: \(result)")
    
    //testing multiplication
    result = MathOperations.mult(Number: 33, with: 29)
    print("Result of multiplying 33 with 29 is: \(result)")
    
    //testing division
    do
    {
         result = try MathOperations.div(Number: 33, by: 0)
         print("Result of dividing 33 by 29 is: \(result)")
    }
    catch let error
    {
         print("ERROR: \(error)")
    }
    
    //testing subtraction
    result = MathOperations.sub(3, from: 29)print("Result of subtracting 3 from 29 is: \(result)")
    
  21. Navigate back to the main Calc folder.
    cd ~/Developer/SPMDEMO/Calc/
  22. Modify the Packages.swift file as shown below:
    // swift-tools-version:4.0
    // The swift-tools-version declares the minimum version of Swift required to build this package.
    
    import PackageDescription
    
    let package = Package(name: "Calc",
    dependencies: [
         // Dependencies declare other packages that this package depends on.
         .package(url: "https://github.com/AmaranthineTech/MathOperations.git", from: "1.0.1"),
    ],
    targets: [
         // Targets are the basic building blocks of a package. A target can define a module or a test suite.
         // Targets can depend on other targets in this package, and on products in packages which this package depends on.
         .target(name: "Calc", dependencies: ["MathOperations"]),
    ]
    )
    
  23. Save the file and run the build command:
    swift build
  24. Like before you should see both the MathOperationsErrorType module being pulled in. We are ready to run the executable. Navigate to the debug folder which contains the executable. Make sure you are in the main Calc folder when you run this command.
    cd ./build/debug/
  25. You should see an executable file called Calc. Run it.
    ./Calc
  26. If everything went okay then you should see the output on the console.

As you can see it is pretty straightforward to develop Applications written in Swift on Linux.

Adding System Modules

In the previous example we saw how to import our own custom made modules. However, there are some modules provided by the system which offers functionality we may wish to use. For example if we wanted to use the random number generator in our application we would need to use the random() method. This is in the glib module.

  1. Quickly create a package called SystemLibs. This is an executable.
  2. Write the following code in the main.swift.
    #if os(Linux)
    import Glibc
    #else
    import Darwin.C
    #endif
    extension Int
    {
         func toString() -> String
         {
              return "\(self)"
         }
    }
    
    var luckyNumber : Int = Int(random())
    
    var luckyNumberStr : String = luckyNumber.toString()
    
    print("The lucky number is \(luckyNumberStr)")
    
  3. Build the code and run the executable.

Adding system modules is direct and simple. The glibc module contains aspects of the standard library. The condition check is to make sure that we are importing the correct module based on the system that we are developing the application on.

Handling Sub-dependencies

As we saw in the earlier example, sub dependencies are handled automatically. So when our Calc application marked the MathOperations module as a dependency it was pulled during the build. However, the MathOperations module itself marked ErrorTypes module as a dependency. We did not have to modify the Packages.swift file belonging to Calc to indicate that ErrorTypes module also needs to be pulled. This was handled automatically by Swift Package Manager.

Conclusion

In this article we have seen:

  • How to create a library package
  • How to create a library package that depends on another library package
  • How to create an executable that depends on a library package
  • How to import the system Glibc module into our executables.

The Swift Package Manager simplifies many aspects of the development process for us. Many of the things we have discussed also work on macOS. Going forward reusing code and planning for the same should be done keeping Swift Package Manager in mind.

UPDATE: Swift on Linux

This article is an UPDATE for Writing Swift Programs on Linux

This article uses Command Line Interface(CLI) to write Swift Programs. If you are new to CLI then you should read the following articles: Terminal Commands for OS X – BasicTerminal Commands for OS X – Part 2.

This article has been written using Ubuntu version 16.04 LTS

For the best part the process is still the same.

  1. Download the Swift tools for Linux from: Swift Download Page
  2. Untar the downloaded files
  3. Copy them to a folder of your choice. I have created a folder called “Developer” in my home folder. So I copied the untarred contents there. This is important because we will be needing the location later.
  4. Switch to Terminal on your Ubuntu System.
  5. First we will install clang. Run the command
    sudo apt-get install clang
  6. Next we will make sure we set the PATH to the path where we copied the Swift tools. For example if the Untarred swift folder is called “swift-4.0-DEVELOPMENT-SNAPSHOT-2017-12-04-a-ubuntu16.04/usr/bin:”${PATH}” and it is in the Developer folder I created earlier then the command would be:
    export PATH=/home/admin/Developer/swift-4.0-DEVELOPMENT-SNAPSHOT-2017-12-04-a-ubuntu16.04/

    The folder name will vary from system to system. The path above is just an example.

  7. Let us check to make sure that everything installed okay. We can do this with 2 commands:
    which swift

    This should show you the path to the folder.
    or

    swift --version

    This should print out the swift version.

  8. Next let us test the REPL. Run the command:
    swift

    This will result in a prompt that looks like:

    Welcome to Swift version 4.0.3-dev (2dedb62a0b, Clang ab7472e733, Swift 64ab6903b2). Type :help for assistance.
     1>
    
  9. Type some of the commands mentioned below:
    12 * 8
    let hello = "Welcome to Swift in Linux"
    print(hello)
    
  10. Now that we know that the REPL is working well, let us move on to the next stage. Let us quit from the REPL:
    :q

Creating Single File Projects

  1. Next let us use Swift Package Manager to create a single file project. I will be creating the project in the Developer folder. So I will navigate to it:cd ~/Developer/
  2. Create a folder of your choice, lets call it Hello World:
    HelloWorld
  3. Enter the folder:
    cd HelloWorld
  4. Create a manifest file for the Package with the command:
    swift package init

    This will create some content for you. The structure should look as shown below.Screen Shot 2018-03-27 at 10.24.02 AM

  5. If we run the command to build it will simply create a module for us. To do that type and run:
    swift build
  6. But we would like to create an executable application. In the sources folder create a file called main.swift. You can use the command:
    touch main.swift

    to quickly create a new swift file.

  7. Open the main.swift file. Write the following code in there:
    let object : HelloWorld = HelloWorld()
    print(object.text)
    print("End of program...!")
    
  8. To create the executable we will first build our code:
    swift build
  9. Now we will run the executable, assuming that you are still in the HelloWorld folder within the sources folder navigate to a hidden build folder. To do that first we will navigate to our main HelloWorld package folder.
    cd ../..
  10. To view all the folders including the hidden folders run the list command:
    ls -la
  11. Navigate to the hidden folder and the debug folder inside it to locate the executable:
    cd .build/debug/
  12. To run the executable:
    ./HelloWorld
  13. If you want to build and directly run & avoid doing steps 9-13 repeatedly the command is:
    swift run

Next we will see how to create multi file projects

Create Multi File Projects

    1. In the previous project go back to the HelloWorld folder within the Sources folder. Create a file called converter.swift:
      touch converter.swift
    2. Write the following code in that file:
      //note the code below is for demonstrating multi file projects & may not necessarily be accurate or correct
      
      //note the code below is for demonstrating multi file projects & may not necessarily be accurate or correct
      func centigrade_to_fahrenheit(temperatureInCentigrade : Float) -> Float
      {
           return ((temperatureInCentigrade*9.0/5.0)+32.0)
      }
      
      func string_to_float(input : String) -> Float
      {
           var number : Float = 0.0;
           var result : Float = 0.0
           var decimalFound : Bool = false
           var numberOfDigitsAfterDecimal : UInt8 = 0
      
           for charac in input
           {
                switch charac
                {
                     case "0":
                          number = 0.0;
                          result = (result * 10.0) + number;
                     case "1":
                          number = 1.0;
                          result = (result * 10.0) + number;
                     case "2":
                          number = 2.0;
                          result = (result * 10.0) + number;
                     case "3":
                          number = 3.0;
                          result = (result * 10.0) + number;
                     case "4":
                          number = 4.0;
                          result = (result * 10.0) + number;
                     case "5":
                          number = 5.0;
                          result = (result * 10.0) + number;
                     case "6":
                          number = 6.0;
                          result = (result * 10.0) + number;
                     case "7":
                          number = 7.0;
                          result = (result * 10.0) + number;
                     case "8":
                          number = 8.0;
                          result = (result * 10.0) + number;
                     case "9":
                          number = 9.0;
                          result = (result * 10.0) + number;
                     default:
                          decimalFound = true
                          break
                }
                if decimalFound
                {
                     numberOfDigitsAfterDecimal += 1
                }
           }
      
           for _ in 0..<numberOfDigitsAfterDecimal-1
           {
                result = result / 10.0
           }
           return result
      }

 

  1. Write the following code in the main.swift file:
    let object : HelloWorld = HelloWorld()
    if CommandLine.arguments.count != 2
    {
            print("USAGE: centigradeToFahrenheit 33.4")
            print("You are missing an argument")
    }
    else
    {
            let temperatureInCentigrade = string_to_float(input: CommandLine.arguments[1]) 
    
            print("\(temperatureInCentigrade) is equal to \(centigrade_to_fahrenheit(temperatureInCentigrade: temperatureInCentigrade))")
    }
    print(object.text)
    print("End....!")
    
  2. Build and run the code. To run it while passing arguments in:
    ./HelloWorld 33.4

So that is how you can build single file & multi file Swift applications on Linux.

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.

Programming Style Guide: Documentation

Now we will shift our attention to that part of programming which is often ignored. Documentation.

Documentation is a key part of programming. In fact, some might go as far as saying that Documentation is the most important aspect of Programming. Let us understand what we mean by documentation by looking at some key points. Later we will look at different ways of documenting our code.

We document our code so that:

  1. Anyone who is reading our code can understand what we are trying to achieve.
  2. Anyone who wishes to make changes to our code knows where to make the changes.
  3. Anyone who issuing our code can easily find out its capabilities and limitations.
  4. Other programmers can figure out how to use our code.
  5. Developers can find out when and where changes were made to a code. This is useful to understand the evolution of our code.
  6. We can easily recollect what, why, when, where & how something was done by us. This is necessary if we are revisiting code that we have written a long time back.
  7. We can add warnings and disclaimers

There may be some other reasons why we may want to document our code, but the list above summaries the most common reasons. This can easily be seen from a simple example.

func fahr_to_cent(Centigrade temp : Float) -&amp;gt; Float
{
return (32 + (temp * 1.8))
}

It is clear to use what the function does simply from its name. However, there is a lot more information that we can provide. Let us modify the implementation a little bit to make it more informative and readable.

/**
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) -&amp;gt; Float
{
     return ((temp * 9.0 / 5.0) + 32.0)
}

The code above looks a lot better now. We made the function name better, but more importantly we have added documentation that better describes the function. This includes range of permitted values, version number, important notes. The comments haven’t been written randomly. They have been formatted in a way that will make them appear in quick help. So now if we have to use the function we know what to watch out for.

Now that we know why we need to document our code let us look at some of the ways this can be done.

Comments

The most common form of documentation is by using comments. Most programming languages support comments. Comments are text which is ignored by the compiler. As such they are not used to build the actual software. The sole reason why they exist is because there has to be some mechanism to write notes.

Single Line Comments

// This is a comment

A single line comment as the name says is a piece of text that can fit in one line.

Good when a short description is required. Normally this is placed before or after a variable as most variables would need a short description.

You can have multiple lines using the Single comment mechanism too.

// This is a comment
// This is a comment on the next line

Multi Line Comments

There is a better way to implement multi line comments. We can enclose the text in a /* */ range.

/* This is a comment
   This is a comment on the next line
   Useful when we have to write really large pieces of comments&amp;amp;amp;lt;span 				data-mce-type="bookmark" 				id="mce_SELREST_start" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			&amp;amp;amp;gt;&amp;amp;amp;lt;/span&amp;amp;amp;gt;
*/

Use Case

Here are some examples of when comments can or should be used.

/*
        File Name.   : main.cpp
        Date Created : 13th February 2017
        Created By   : Arun Patwardhan
        Project Name : String Parser
        File Contents:
                - Command Line Option selector
                - Different entry points for the remaining code
        Contact      : arun@amaranthine.co.in
*/

This is a classic example of a multi line comment. This comment provides useful information about the name of the file, when it was created, who created it, contact information, the code that is found in this file.

/*
    Exception Possibilities while Reading/Writing from/to Database
    write_error : This is thrown when there is duplicate data that is being
                  written into the database.
    db_empty.   : This is thrown when you attempt to read from an empty data
                  base.
                  Use the func is_empty() method.
    invalid_data: This is thrown when the data to be written is not valid.
    data_missing: This is thrown when insufficient data is passed. If the write
                  operation requires mandatory data an exception is thrown
                  instead of writing default values.
*/
enum DBExceptions : Error
{
    case write_error(String)
    case db_empty(String)
    case invalid_data(String)
    case data_missing(String)
}

This example shows the necessary documentation while declaring a new type. In short its purpose and situations when different values might be used.

Here is an example of code for functions.

@interface Converter : NSObject
/*!
    @brief This is a temperature conversion function

    @discussion This functions takes floating point values and does a floating point conversion to make sure that we get a precise conversion.

    @param temperature This is the value in centigrade that is passed in. Note, negative values can also be passed in. Values whose results exceed the range supported by float will produce un predictable results.

    @return float Returns a floating point value
*/
-(float) convert_to_fahrenheit_from_centigrade:(float) temperature;
@end

The comment gives information about different aspects of the function. Including the rage of values supported. Note that it also uses special markup to allow for the code description to show up in the Help menu bar or when you option click the method.

Comments

This is how the comments with markup look like. They appear in the ⌥ click menu as well as the help menu on the right hand side.

Read Me Files

Another thing one can do along with comments is to create Read Me files. Read Me files are plain text files that are bundled as a part of the project. Unlike comments which give information about a specific piece of code or an entire file, Read Me files give information about the entire project as a whole. Since they are text files we actually treat them as text.

Here is some typical information that is found in a Read Me file:


Project Name : String Parser
Project Request/Ticket Code: 13788
Orignal Project Author : Arun Patwardhan
Contact Details :
– arun@amaranthine.co.in
http://www.amaranthine.in

Platforms on which Application Can Run
– macOS 10.10 or later
– Windows 7 or later
– Linux (Ubuntu 14 or later)

Compiler Supported – g++

Building the Application

make

Testing

strParser -f Test1 -o myOutput1
strParser -f Test2 -o myOutput2

Files
– makefile
This is the file used to build the Application.

– main.cpp
This is the entry point file. The selection of execution path on the basis of command line options is done here.

– Parser.h
This file contains the declaration for the Parser class as well as its internal structure.

– Parser.cpp
This file contains the implementation of the Parser class

– DataStructure.h
This file contains the declaration of the internal structure of the data structure.

– DataStructure.cpp
This file contains the implementation of the internal structure of the data structure.

– Validator.h
This file contains the declaration of the internal structure of the data structure.

– Validator.cpp
This file contains the implementation of the internal structure of the data structure.

– Test1
Runs a basic set of strings as input.

– Output1
Expected output after running Test1. Compare your results with the results of this file.

Libraries Required – Standard Template Library


The above is just a sample Read Me file. In real world implementations these can get a lot bigger with references to links and future developments. Some of the other things that can be mentioned are:

  • Future additions
  • Bugs fixed (potentially with the bug fix request ticket)
  • Limitations
  • Tools that are required to make this code
  • Additional tools that need to be installed
  • Project Status

Naming Conventions

Documentation becomes a lot easier if we follow good naming conventions. Variables, functions, types, files… which are well named in itself become self explanatory and at the very least reduce the amount of documentation required.

Additional Tools Documentation in C++, Objective-C

Doxygen

HeaderDocretired You may come across some projects that use this.

Additional References for Documentation for Swift

Here is an article on Markups for Swift.

 

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.

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