Apple recently added machine learning features in a framework called Core ML. The idea is that you can take machine learning models and plug them into any Xcode project to instantly add machine learning capabilities to your apps. While this is exciting since this makes adding artificial intelligence (AI) to any app quick and easy, it’s not without its drawbacks.
First, let’s talk about the drawback of machine learning in general. In the book “Weapons of Math Destruction,” author Cathy O’Neil explains the inherent limitations of machine learning. Someone must first create an algorithm and then that algorithm is only as good as the data that it trains on. Feed the algorithms he wrong or misleading data and it can’t help but reach incorrect conclusions.
For example, Microsoft once created an AI chat bot that could learn from comments people submitted. So people started submitting racist comments so the AI chat bot would repeat nonsense about the Holocaust never happening and blaming Jews, blacks, and Mexicans for the problems in the world. That example simply shows if you train a machine learning model with bad data, you get back bad results.
Second, machine learning only works when the machine learning model can learn and improve its decisions. Without feedback, the machine learning model has no idea whether it’s coming up with the right conclusions or not. Those twin problems are what Cathy O’Neil highlights in “Weapons of Math Destruction.”
One example she gives is how many school districts are using computer algorithms to determine the “best” teachers. To do this, the programmers who created the algorithm can’t take into account all possible factors so they choose the ones they think (rightly or wrongly) that matter most in evaluating a teacher.
This caused the algorithm to rate one teacher as a 6 (on a scale of 1 to 100) one year, and then rate that same teacher a 96 the following year. How can a teacher go from a dismal 6 rating to an excellent 96 rating in one year? It’s because the first year, the teacher taught advanced students so their test scores were high to begin with, and remained high by the end of the year so they showed no improvement. the algorithm incorrectly assumed that no improvement in test scores meant that the teacher wasn’t any good.
The following year, that same teacher taught ordinary students and their test scores went up, so the algorithm assumed that the teacher did a good job. By not taking all factors into account and even worse, not accepting any feedback for modifying the machine learning model, this algorithm for evaluating teachers generates false and misleading results. yet because a computer generates these results in a seemingly objective way, people wrongly assume the computer must be correct when it’s not.
Even worse, the results of these skewered answers affects the lives of people, often in negative ways. Trying to argue that a computer algorithm is wrong is often a pointless and fruitless effort, and that’s the problem with machine learning.
Now in the world of Xcode, Core ML seems to have several faults. First, it’s not easy to create a machine learning model. That’s why Apple offers several machine learning models on their website. Second, there are plenty of machine learning models available that aren’t stored in the Core ML format, so Apple offers a bunch of tools for converting these machine learning models into Core ML files.
Unfortunately, installing and using these tools is clumsy and error-prone, making the process difficult for all but hardened developers. Apple will likely fix this process, but right now, it’s a huge pain in the neck. Still if you can get it to work, you can theoretically convert most machine learning models into Core ML files so you can add them to any Xcode project. That means you can add AI capabilities to macOS, iOS, watchOS, or tvOS apps.
Perhaps the greatest limitation of machine learning models is that once you have them stored on Core ML format, can you modify these models to make them more intelligent so they actually learn over time with new data?
If you can modify a machine learning model over time, then how do you do it and how do you keep it from making mistakes such as what happened with Microsoft’s chat bot that learned to swear and offer racist comments?
If you can’t modify a machine learning model over time, then it’s inherently limited. If you try several of the machine learning models that Apple provides, you’ll find that they’re only average in recognizing images in pictures.
So machine learning has a great future in making apps smarter. The problem is that machine learning is still limited and difficult. That will only get better over time and machine learning models will get smarter over time as well.
Until then, machine learning is the future so you better know how to add machine learning models to your Xcode projects. Just don’t expect miracles just yet, and keep in mind that “Weapons of Math Destruction” highlights the danger of relying too much on algorithms that we don’t fully understand and can’t modify.
Machine learning has its place, and it’s firmly in assisting humans, not substituting actual thought for machine learning results.
Posted in Algorithms, Programming, Xcode
When you’re working with numbers, you may want to convert the number to a string. The simplest way to convert a number to a string is to use the String data type to convert a number to a string like this:
A fancier way to convert a number to a string is to use the NumberFormatter class. At the simplest level, the NumberFormatter class just duplicates the String data type conversion like this:
In the above code, the first line creates an object (myNumber) from the NumberFormatter class.
The second line converts a number (24) to a string and then stores that number into a constant named costString (“24”).
The NumberFormatter class can also convert a string into a number such as turning “9.4” into 9.4 like this:
In this example, the line converts the string “9.4” into a number (9.4) and stores it into the newStuff variable.
Of course, you could just use the Double data type to convert a string into a number like this:
The first line creates a string variable that contains “4.2” as its value. The second line then uses the Double data type to convert the string from “4.2” to 4.2 as a Double value.
Up until this point, the NumberFormatter class simply duplicates the String and Double keywords to convert a number to a string or a string to a number. What makes the NumberFormatter class unique is that it offers the ability to spell out a number:
The first line defines an object called myNumber based on the NumberFormatter class. Then the second line defines the numberStyle property as .spellOut, which means it converts a number into actual words.
The third line above creates a string from the number 742.409 but spells this out as the string “seven hundred forty-two point four zero nine”, which it stores into the variable x.
The NumberFormatter class is just one of those oddball classes that you may find useful once in a while, so experiment with the NumberFormatter in a Swift playground and see how it works for yourself.
Posted in Algorithms
Safety is crucial in most modern programming languages because programs that allow the wrong types of data will likely fail or crash the program completely. That’s why real-time avionics programs that control jet airliners rely on safe programming languages like Ada.
Swift emphasizes safety as well, and one feature that Swift offers is called the guard statement. The basic structure of the guard statement looks like this:
The guard statement looks to make sure a condition is true. If the condition is false, then exit out of a function without running any code.
By placing a guard statement at the beginning of a function, you can check to make sure all data is valid before running any code. A simple example of a guard statement might look like this, which you can paste and run in a Swift playground:
This code checks to see if a number (stored in the myNumber variable), passed into a function, is an odd or even number. If it’s even, then the guard statement lets any code following run. If the number is odd, then the guard statement runs and the return command stops any further code from running in that function.
When you pass the number 4 into the testGuard function, the guard statement lets it run the testGuard code, which prints “Even number”. When you pass the number 5 into the testGuard function, the guard statement catches it, prints “Odd number”, and then exits out of the function.
By placing a guard statement at the beginning of each function, you can make sure that function only receives valid data. By using the guard statement, you can make your code more reliably.
Posted in Algorithms
When you create a macOS project that uses storyboards, each window is called a view, which has a border. Two ways to modify the border of a view is to change its width and change its color.
To change the view’s border width, you need to use the borderWidth property like this:
One way to make it easy to change the width of a border is to use a slider. Then create an IBOutlet for that slider along with an IBAction method like this:
To change the view’s border color, you need to use the borderColor property like this:
The simplest way to change the border color is through a color well. Just create an IBOutlet and an IBAction method for that color well, in addition to overriding the changeColor function like this:
If you have a slider and a color well on your view, users can drag the slider back and forth to modify the border width and click on the color well to choose a different color for that border. You can download a sample program that shows how this works:
BorderSetting sample program.
Posted in Algorithms, User Interface
Most of the time if you want text to appear on your user interface, you just type it directly into your user interface, such as editing a text field or label. You can also create and edit text using the Attributes Inspector pane as well, but if you need to display large amounts of text, it’s often easier to create and edit that text in a separate file.
Once you create a separate text file (not stored in a word processor format like the Microsoft Word .docx file format), you can then drag and drop that text file into the Project navigator pane.
When you drag and drop a file in the Project navigator pane, a window will appear to display options for adding a file. Make sure the “Copy items if needed” check box is selected.
To retrieve a file, you must specify the filename and extension. If you stored text in a file called “Xcode.txt,” then the filename would be “Xcode” and the extension would be “txt”.
If the text file exists, then you can store the contents of that file in a variable name. If the file can’t load or the file you specify isn’t found, then you need to handle this possible error so your program doesn’t crash. You can do all this with the following code:
The above code would store the contents of the “Xcode.txt” file in the “contents” variable. Just remember that if your file were called “Data.asc” then the above code would replace “Xcode” with “Data” and “txt” with “asc”.
To see how this works in a simple macOS program, download and run the following sample program that displays a text view in a window and a push button. By clicking on the push button, you can load the contents of the Xcode.txt file:
Posted in Algorithms
An array typically contains items of the same data type such as strings or integers. To declare an array to hold a specific data type, you just need to state the data type inside square brackets like this:
Then you can just add items to the array using the append command like this:
You can also define an array just by stuffing it with data right away like this:
Once you fill an array with data, you can sort it using the sorted() method like this:
This would create a sorted array that contains [“bear”, “duck”, “tiger”]. In the above code, the array appears sorted but the original beasts array is actually still unsorted. If you want to save the sorted results, you must store them in a new variable like this:
In this code, newArray is defined as an array of String data types. Then the sorted() data gets stored in the newArray variable.
Of course, you could just declare a new variable and store the sorted results in that new variable in one line. In the above example, sameArray is defined and given a value of sorted array data all in one line.
Typically an array doesn’t contain just one data type like a String or Int, but a structure that contains multiple fields such as the following:
This code creates an array of structures called Contacts where each Contact contains a first, last, and phone field that can hold a String data type. To create a structure, you need to define a variable and data for each field in that structure like this:
This creates three variables (employee, prospect, and salesContact) that each contain a first, last, and phone string data. To add these structures to an array, you can just use the append command like this:
This creates an array that holds three structures. The first structure in the array is the name “Fred Zimmerman,” the second structure is “Susan Acker” and the third structure is “Bill Miller.”
Now to sort this array, you must specify the field to sort on. If we wanted to sort by the “last” field, you would use the sorted command like this:
The above code would create sortedContacts array where the first structure is the name “Susan Acker,” the second structure is “Bill Miller” and the third structure is “Fred Zimmerman.”
The entire code for defining a structure, creating variables to store data in structures, creating an array of structures, and then sorting that array of structures would look like this in a Swift playground:
With an array of structures, you can sort on individual fields.
Posted in Algorithms
The TouchBar replaces the largely useless row of function keys on some of the MacBook Pro laptops. Since Apple recently updated their iWork office suite to take advantage of the TouchBar, it’s likely that the TouchBar will eventually find its way to other Macintosh models including on an external keyboard for the iMac, mac mini, and Mac Pro.
Since the TouchBar will likely be another user interface accessory, it’s important to know how to write macOS programs that offer a TouchBar. If you’re writing macOS programs and don’t have a TouchBar, you can simply use the TouchBar Simulator.
To use the TouchBar Simulator, open Xcode and choose Window > Show Touch Bar (or press Shift+Command+5). If you run any macOS program that supports the TouchBar, you’ll be able to see how those programs offer shortcuts on the simulated TouchBar.
To add TouchBar support to your macOS programs, click on your Main.storyboard file to display your user interface, then open the Object Library window. In the search field, type touchbar and the Object Library will display all the touch bar items you can add, including NSTouchBar, which is the touch bar itself.
Drag the NSTouchBar from the object Library over the Window Controller in your storyboard. The TouchBar will appear directly beneath this Window Controller.
Now you can drag other TouchBar items from the Object Library window on to the TouchBar such as NSTouchBar Slider or NSTouchBar Button. For this example, drag NSTouchBar Color Picker on to the TouchBar.
Now the TouchBar needs its own class file, so choose File > New > File. Click macOS and then click the Cocoa Class icon. Then click the Next button. A new window appears, asking for your class name and subclass.
The name can be anything you want, such as TouchClass. What’s far more important is that the Subclass is NSWindowController.
Click the Next button and then click the Create button. This adds the TouchClass.swift file to the Navigator pane, Now the next step is to link this TouchClass.swift file to the TouchBar.
Click on Main.storyboard and click on the blue icon that appears in the top, middle of the Window Controller where you added the TouchBar. Choose View > Utilities > Show Identity Inspector. Click in the Class popup menu and choose TouchClass (or whatever name you chose for your class file).
Once you’ve connected the TouchBar to a class file, choose View > Assistant Editor > Show Assistant Editor. You want the assistant editor to display the TouchClass.swift file, but you may need to manually choose this TouchClass.swift file to make it appear in the assistant editor.
When opening the TouchClass.swift file, you may see an error message. Just let Xcode correct this error and it will likely add a @available line such as the following:
Now with the TouchBar displaying a color picker, control-drag from the TouchBar color picker to the top of the TouchClass.swift file.
When a popup menu appears, choose the following:
- Connection: Outlet
- Name: colorIcon
- Type: NSColorPickerTouchBar
This creates an IBOutlet to the color picker on the TouchBar with code that looks like this:
Modify the windowDidLoad functions follows:
When a popup menu appears, choose the following:
- Connection: Action
- Name: colorPicked
- Type: NSColorPickerTouchBar
This creates an IBAction method. Now edit this IBAction method with one line of code like this:
Choose Product > Run and you should see your program’s user interface, but probably not any sign of the simulated TouchBar. To display the TouchBar, go back into Xcode and choose Window > Show Touch Bar (or press Shift+Command+5).
Go back to your TouchBar program and you should now see the simulated TouchBar visible. Click on the color picker on the TouchBar to display a range of colors. Each time you click on a color, the background of the window should display that color.
Posted in Algorithms, User Interface
If you’re creating a macOS program, you may want to display a dialog box on the screen to alert the user of something, such as an error message of some kind. The simplest way to create a dialog is to use the NSAlert class like this:
If you create a push button on a window and store the above code in an IBAction method for This code creates a simple dialog that looks like this:
The messageText property defines the bold text and the informativeText property defines the text that appears underneath.
As an alternative to displaying a modal dialog, you can also display a sheet instead by using this code:
This creates a sheet like this:
A simple dialog that displays a message is fine. When the user wants to dismiss the dialog, he or she can just click the OK button. However in many cases, you may want to add up to three buttons on a dialog with custom text. To do that, you need to use the addButton method like this:
To determine which button the user clicked, you need to use a switch statement. If you created a modal dialog using the runModal() method, your switch statement might look like this:
So if you placed a push button on a window, and created an IBAction method to display a dialog by clicking this push button, your entire code might look like this:
To determine which button the user clicked if you created a sheet, your switch statement would look slightly differently:
If you created a push button on a window with an IBAction method to open a sheet, your entire IBAction method code might look like this:
By using the NSAlert class, you an easily create and display dialogs as modal dialog boxes or as a sheet. You an also customize the number of buttons (up to three) and retrieve which button the user clicked on.
Posted in Algorithms, macOS, User Interface
If you need to run one type of animation after another in macOS, Swift provides a simple way to do this where the code looks like this:
By itself, this runAnimationGroup code does nothing. What you need to do is put your animation code within the first set of curly brackets and when that first animation completes, then you can run a second set of animation if you wish.
Suppose you want to rotate an item such as a label and when it’s done rotating, flip it back to its original position. First, create a label and an IBOutlet such as:
Once you have an IBOutlet to represent a label on the user interface, you can rotate it using this code:
Thea love code takes five seconds to rotate a label (lblMessage) 45 degrees. When it’s completed, it changes the label’s rotation back to 0 again.
While this simple example shows how to rotate an item, the more important lesson is to see how the runAnimationGroup lets you combine two different types of animations where the second animation runs after the first animation completes. Any time you need to run two different types of animation back to back, use the runAnimationGroup structure.
Posted in Algorithms, macOS
If you want to make an item on the user interface appear to fade away and reappear again, you can use something called the animator() method. Essentially all you have to do is create an IBOutlet for a user interface item (such as a button or label) and then apply the animator() method along with defining the alphaValue property to 0 (completely invisible) or 1 (completely visible).
Of course, if you assign a user interface item’s alphaValue property to 0, it will suddenly disappear, so that’s why you need to create a delay effect using the following code:
This simply tells code to delay the animator() action by three seconds (or whatever number you assign to the duration property.
Create a simply macOS project using storyboards and place a label and a push button anywhere on the view. Create IBOutlet for the label like this:
Now create an IBAction method for the push button (call it AnimateMe) and fill it with Swift code such as:
This code simply checks what the alphaValue of the label might be. If its value is 1 (completely visible), then it slowly fades the label away in three seconds and sets its alphaValue property to 0. This creates a gradual fade out visual effect.
If the label’s alphaValue property is already 0, then the above Swift code takes three seconds to slowly set the alphaValue to 1, which creates a fade in visual effect.
Obviously there’s more to animation using the animator() method but this can get you started in seeing how simple it can be to create animation in a macOS program.
Posted in Algorithms, macOS, User Interface