Tag Archives: Apple

Escape from Escape

Escape key
Ye Olde Escape Key

During my college days computers were run from teletype machines. These teletypes had a typewriter keyboard layout extended with unfamiliar keys like Control (Ctrl) and Escape (Esc).  You could press Ctrl-G and make the teletype ring its bell — ding! You could press Esc when you mistakenly wrote a BASIC program with an infinite loop and make the program terminate. When I got an Apple ][+ in the early 1980s, Ctrl and Esc keys were present, though there was no Caps Lock key — all letters were capitalized on the Apple ][. I had to buy a separate Videoterm card to get lower case letters and perform the “Shift key mod” inside the case to get the Shift keys to work. Ah, the good old days!

ASR-33 Teletype keyboard layout
ASR-33 Teletype keyboard layout (by Daniele Giacomini [CC BY-SA 2.5 (http://creativecommons.org/licenses/by-sa/2.5)], via Wikimedia Commons)
When the IBM PC came out its keyboard combined the IBM typewriter keyboard with the new computer keys, adding to Control and Escape the Alt key and a set of Function keys. The Alt key originated in the Meta key from MIT keyboards, and is still called the Meta key in Emacs documentation — so delightfully retro! Apple renamed the Alt key the Option key, and, with the Macintosh, added the Apple key that later became the Command key. Windows certainly couldn’t have an Apple key, so named their equivalent key the Windows key.

Apple ][ keyboard from http://www.hp9845.net/9845/history/comparison/
Apart from the Control key, which is combined with other keys to generate non-printing ASCII characters, like Bell (ASCII 7), and the Escape key (ASCII 27), these other keys originally manipulated the high order bit of a character code.  They could get away with this as ASCII only uses 7 bits of an 8 bit byte. However with internationalized keyboards and Unicode, character sets now not only require all 8 bits of a byte, but often more than one byte for each character. So modern keyboards send scancodes with each keypress and it is up to the computer operating system to make sense out of them.

I have to admit I don’t use the Function keys (F1 – F12) much anymore since my WordPerfect and Lotus 1-2-3 days long ago. I use the Escape key mostly to get out of full screen mode when I am watching a YouTube video. But many developers use the vi or Vim editor to create their source code and depend on the Escape key. I am more an Emacs man myself, but sometimes use Vim for simple editing tasks. Vim is a modal editor, meaning there are separate text entry and editing modes. The Escape key is used to change modes. If you use Vim, you are constantly hitting the Escape key. Given the importance and long history of the Escape key (it was created in 1960), a developer who relies on Vim might be forgiven for thinking that the venerable key would be sticking around a bit longer.

IBM PC keyboard
BM PC keyboard (credit http://www.vintage-computer.com/ibm_pc.shtml)

So if I were Apple and designing the next generation MacBook Pro (MBP), eliminating the Escape key would not be high on my list of priorities. But this was what they did, turning the Escape key into an evanescent luminosity on the new Touchbar interface. This is depressing. Up to this point, the MBP has been a great developer machine. I have a “late 2013″ 15” screen MBP. It is a fast, sturdy laptop. Since Mac OS X macOS is a user interface veneer over BSD Unix, all the Unix development tools are there, as opposed to Windows devices, where installing a Unix environment is a pain. It is impossible to develop for macOS or iOS without an Apple machine. With my MBP I can develop for both Android and Apple. It is even possible to develop Windows software on a Mac, though I haven’t tried this. Because of these advantages, lots of developers use a MBP.

It seems Apple has turned its back on developers. Fortunately my current machine is working well and I don’t have any need to buy a new one yet. Ideally by the time I need a new machine the next iteration of the 15″ MBP will offer a standard keyboard and fix some of the other problems the new versions seem to be having.  Apple should focus on features that developers and other professional computer users want in a computer:  more memory than 16 GB, return of the Magsafe power cable, and at least one full-sized USB port so that old USB devices can be used without a dongle. They can continue to sell a Touchbar, USB-C only version of the 15″ MBP for people who like that sort of thing. The 13″ MBP is available with and without a Touchbar, why not do the same thing with the 15″ version?  Perhaps the death of the Escape key isn’t the end of the world, but it does seem to symbolize a lack of interest on Apple’s part in its developers.  But if developers switch to non-Apple machines, those developers will no longer be able to develop Apple apps.  In the long run this will hurt Apple’s major money-maker, the iPhone.

Porting an iOS Project to the Mac

I just finished porting my electronic calipers mobile iOS app, EP Calipers, to the Mac. In doing so I decided to bite the bullet and change the programming language from the original Objective C (ObjC) to Apple’s new language, Swift. Here are some observations.

The Swift programming language

I’m comfortable now with Swift. Swift is an elegant language with a modern syntax. ObjC is a very weird looking language in comparison. You get used to ObjC, but, after writing Swift for a while, your old ObjC code looks awkward. Comparing the two languages is a little like comparing algebraic notation to reverse polish notation (i.e. like comparing (1 + 3) to (1 3 +)). I’ll just give a few examples of the differences. The chapter “A Swift Tour” in Apple’s The Swift Programming Language is good resource for getting up to speed in Swift quickly.

Here’s how an object variable is declared and initialized in ObjC:

Widget *widget = [[Widget alloc] init];

Note that in ObjC objects are declared as pointers, and both the memory allocation for the object and initialization are explicitly stated. ObjC uses messaging in the style of SmallTalk. The brackets enclose these messages. So in the commonly used object construction idiom shown, the Widget class is sent the allocation message, and then the init message. A pointer to a widget results.

The same declaration in Swift:

var widget = Widget()

With Swift the syntax is much cleaner. The keyword var indicates variable initiation. Pointer syntax is not used. The type of the variable doesn’t have to be given if it can be inferred from the initiation. Swift is not a duck-typed language, like, for example, Ruby. It is strongly statically typed. It’s just that if the compiler can figure out the typing, there’s no need for you to do the typing (Sorry for the puns — couldn’t resist). Note that the constructor is just the class name followed by parentheses. If there are parameters for the constructor, they are indicated with parameter names within the parentheses. Finally, note that no semicolon is needed at the end of the line.

Swift has a lot of other niceties. Simple data types like integer, float and double are full-fledged objects in Swift (Int, Float, Double). Unlike ObjC, where only pointers can be nil, all classes in Swift, even classes like Int, can potentially be equal to nil, if the variable is defined as an Optional with the following syntax:

var count: Int? // count can be equal to nil

In order to use an Optional variable, you need to “unwrap” it, either forcibly with an exclamation point:

let y = count! + 1 // will give runtime error if count == nil

or, more safely:

if let tmp = count { // no runtime error if count == nil
     y = tmp + 1
 }

In that statement, the if statement evaluates to false if count is nil. This if statement also demonstrates more of Swift’s nice features. There are no parentheses around the conditional part of the if statement, and the options following the if statement must be enclosed in braces, even if they are only a single line long. This is the kind of syntax rule that would have prevented the Apple’s gotoFail bug and one wonders if that very bug may have led to incorporation of this rule into Swift.

Because Swift has to coexist with the ObjC API, there are conventions for using ObjC classes in Swift. Some ObjC classes, like NSString, have been converted to Swift classes (String class). Most retain their ObjC names (e.g. NSView) but their constructors and methods are changed to Swift syntax. Many methods are converted to properties. For example:

ObjC

NSView *view = [[NSView alloc] initWithFrame:rect];
 [view setEnabled:true];

Swift

let view = NSView(frame: rect)
 view.enabled = true

Properties are declared as variables inside the class. You can add setters and getters for computed properties. When properties are assigned Swift calls the getting and setting code automatically.

There are other improvements in Swift compared to ObjC, too numerous to mention. For example, no header files: wonderful! Swift is easy to learn, easy to write, and lets you do everything that you could do in ObjC, in a quicker and more legible fashion. Well named language, in my opinion.

Mac Cocoa

The other hurdle I had in porting my app was translating the app’s API. Apple iOS is not the same as Apple Cocoa. Many of the foundational classes, like NSString (just String in Swift) are the same, but the user interface in iOS uses the Cocoa Touch API (UIKit), whereas Cocoa uses a different API. The iOS classes are prefixed with UI (e.g. UIView), whereas the Cocoa classes use the NS prefix (NSView).

The naming and functionality of the classes between to two systems is very similar. Of course Cocoa has to deal with mouse and touchpad events, whereas iOS needs to interpret touches as well as deal with devices that rotate. Nevertheless much of the iOS code could be ported to Cocoa just by switching from the UI classes to their NS equivalents (of course while also switching from ObjC to Swift syntax). As expected, the most difficult part of porting was in the area of user input — converting touch gestures to mouse clicks and mouse movement. It is also important to realize that the origin point of the iOS graphics system is at the upper left corner of the screen, whereas the origin in Mac windows is at the lower left corner of the screen. This fact necessitated reversing the sign of y coordinates in the graphical parts of the app.

Although there’s no doubt the UI is different between the two platforms, there does seem to be some unnecessary duplication of classes. Why is there a NSColor class in Cocoa and a UIColor class in iOS, for example? Perhaps if Apple named the classes the same and just imported different libraries for the two platforms, the same code could compile on the two different platforms. Apple has elected to support different software libraries for computers and mobile devices. Microsoft is going in the other direction, using the same OS for both types of devices. I think Apple could get pretty close to having the same code run on both types of devices, at least on the source code (not the binary) level, with a little more effort put into their APIs. I suspect that at some point in the future the two operating systems will come together, despite Tim Cook’s denials.

IKImageView

I used IKImageView, an Apple-supplied utility class, for the image display in my app. In my app, a transparent view (a subclass of NSView) on which the calipers are drawn is overlaid on top of an ECG image (in a IKImageView). It is necessary for the overlying calipers view to know the zoomfactor of the image of the ECG so that the calibration can be adjusted to match the ECG image. In addition in the iOS version of the app I had to worry about device rotation and adjusting the views afterwards to match the new size of the image. On a Mac, there is no device rotation, but I wanted the user to be able to rotate the image if needed, since sometimes ECG images are upside down or tilted. It’s also nice to have a function to fit the image completely in the app window. But because of the way IKImageView works, it was impossible to implement rotation and zoom to fit window functionality and still have the calipers be drawn correctly to scale. With image rotation, IKImageView resizes the image, but reports no change in image size or image zoom. The same problem occurs with the IKImageView zoomToFit method. I’m not sure what is going on behind the scenes, as IKImageView is an opaque class, but this resizing without a change in the zoom factor would break my app. So zoomToFit was out. I was able to allow image rotation, but only when the calipers are not calibrated. This make sense anyway, since in most circumstances, rotating an image will mess up the calibration (unless you rotate by 360°, which seems like an edge case). Other than these problems with image sizing, the IKImageView class was a good fit for my app. It provides a number of useful if sketchily documented methods for manipulating images that are better than those provided by the standard NSImageView class.

Saving and printing

As mentioned, my app includes two superimposed views, and I had trouble figuring out how to save the resulting composite image. IKImageView can give you the full image, but then it would be necessary to redraw the calipers proportionally to the full image, instead of to the part of the image contained in the app window. I came close to implementing this functionality, but eventually decided it wasn’t worth the effort. Similarly printing is not easy in an NSView based app (as opposed to a document based app), since the First Responder can end up being either view or the enclosing view of the window controller. I wished there was a Cocoa method to save the contents of a view and its subviews. Well there is, sort of: the screencapture system call. It’s not perfect; screencapture includes the window border decoration. But it was the easiest solution to saving the composite image in the app window. The user then has the ability to further edit the image with external programs, or print it via the Preview app.

Sandboxing

Mac apps need to be “sandboxed,” meaning if the app needs access to user files, or the network, or the printer, or other capabilities you have to specifically request these permissions, or, as Apple terms it, entitlements. Since the app needed access to open user image files, I just added that specific permission.

Submission to the App Store

Submitting a Mac app to the App Store is similar to submission of an iOS app — meaning if you are not doing it every day, it can be confusing. The first problem I had was the bundle ID of my app was the same as the bundle ID of the iOS version of the app. Bundle IDs need to be unique across both the Mac and iOS versions of your apps. Then there was the usual Apple app signing process which involves certificates, provisioning profiles, identifies, teams, etc., etc. I did encounter one puzzling glitch which involved a dialog appearing asking to use a key from my keychain, and the dialog then not working when clicking the correct button. I had to manually go into the keychain program to allow access to this key. So, in summary it was the usually overly complicated Apple App Store submission process, but in the end it worked.

And so…

Because the Apple API is so similar between Cocoa and iOS, porting my app to the Mac was easier, even with the language change from ObjC to Swift, than porting between different mobile platforms. I have ported apps between iOS and Android, and it is a tougher process. As for Swift, I’m happy to say goodbye to ObjC. Don’t let the door hit you on your way out!

Is Apple Really Serious About Protecting Privacy?

I had thought the answer to the question of the title was “yes,” given Tim Cook’s stance on strong encryption. But if a recent experience at my local Apple Store is any guide, the theoretical views of the Apple CEO on privacy have not trickled down to daily practice at the Apple Stores.

My wife’s Macbook Air developed an intermittent display glitch, so we brought it in to the Apple Store. On the initial visit the Genius Bar guy opened up the computer and reseated a video cable. This appeared to work for about a week and then the problem returned. So we brought it back.

At this point the person behind the bar recommended sending the machine off to a repair facility, with an expected 5 day turn-around time and a fairly reasonable price to fix it. This seemed like a good deal, since we were planning to travel in a couple weeks and my wife wanted her computer back before then. So the Genius Bar woman took the computer into the back room and told us to wait until she came back with some paperwork to sign.

After about 10 minutes she came back and said everything was ready. She passed her iPad over to us. The form she wanted us to fill out asked for the user name and password needed to log in to the computer.

I immediately felt uncomfortable. Reading the fine print on the form, it stated that supplying the user log in information was mandatory. We asked if that was so and it was confirmed. It seemed our only alternative was not to get the computer fixed. So, although worried that I was making a big mistake, I wrote in the password, which appeared in the textbox in plain text.

After walking out of the store I felt like I had just participated in a hacker’s social experiment demonstrating how easy it is to get someone to give their password to a complete stranger. My wife uses LastPass, but I know with some websites she has had the browser remember and automatically fill in passwords. Like most of us, she often reuses passwords and doesn’t use two-factor authentification. But even if all her other passwords were secure, there is still a lot of private information on her computer that we wouldn’t want anyone seeing.

So after we got home she and I spent a few hours changing passwords on our bank accounts and other important sites. It made us feel a little better, but not much.

The emailed receipt from Apple clearly stated that they were not responsible for any data loss or data breach from the computer repair. Great! Everything on the computer is backed up, so I wouldn’t care if they wiped the hard drive. I just don’t want anyone snooping around our data.

I don’t think Apple needed to do this. If they really needed access to the user account to fix the computer (which I doubt since they could tell if the screen was working just by turning the computer on without logging in), it would have taken just a few minutes in the store to activate the Guest User account or create a new user account specifically for them to use. Unfortunately I didn’t think of that until after the fact. But maybe this advice could help someone else in a similar situation.

Perhaps I am being paranoid.  I know people who work at a large computer repair facility. There are very strict rules to discourage copying of data from users’ computers. Or perhaps I’m just being naïve.  Much of my private data now lives in “the cloud,” A.K.A. a bunch of computers in unknown locations belonging to unknown people with unknown trustworthiness. So I know that digital security is a bit of a pipe-dream. Despite what we do to secure our data, the forces that want to steal it (crooks, governments, and businesses — in other words, crooks) will probably win out.

Nevertheless, I think that if Apple wants to portray itself as a paragon of privacy virtue, it had better clean up its act in the Apple Store first.

Reading About Steve Jobs

The iconic Jobs and Wozniak Apple II photo
Wozniak, Jobs, and the Apple II

I am interested in the history of computer technology and over the last couple months have read a lot about Steve Jobs. To be specific I read Walter Isaacson’s Steve Jobs, Brent Schlender’s Becoming Steve Jobs, and a book published back in 2001, Alan Deutschman’s The Second Coming of Steve Jobs. To get the point of view of the other “Steve” I read Steve Wozniak’s autobiography, iWoz, How I Invented the Personal Computer, Co-Founded Apple, and Had Fun Doing It.  I watched the two biographical movies, Pirates of Silicon Valley from 1999 and the one from 2013 with Ashton Kutcher, Jobs. The first movie is a lot of fun, exploring the initial rivalry between Jobs and Bill Gates.  The second has been criticized but I like it also, and Kutcher’s resemblance to Jobs is uncanny.  I am looking forward to seeing Aaron Sorkin’s version when it comes out. I also read Fire in the Valley by Michael Swaine and Paul Freiberger, which is a free-ranging and entertaining history of the PC era and on which the first movie mentioned above was based.  Finally there are a number of documentaries on YouTube that address the early personal computer era.  One of the best is the 3-part Triumph of the Nerds.  There are numerous videos on YouTube of Jobs in action, from the earliest days of Apple until shortly before his death.

Reading and watching this stuff makes me nostalgic. I bought an Apple II+ in 1981 shortly after moving to Houston, Texas and starting my fellowship in electrophysiology. It was my reintroduction to computers after my brief fling back in my college days in the early 1970s. As underwhelming as its capacities were judged by today’s standards (base configuration had 48 KB RAM, 40 column all caps text display, 128 KB floppy drives and a MOS Technology 6502 CPU running at 1 MHz), I loved that little machine and was amazed by it. Using its 8 open expansions slots (something Woz insisted on and surprisingly prevailed in getting over Jobs’s objections) I had that thing decked out with an 80 column lowercase text display card, a 1 MB RAM-disk, memory expansion to 64 KB, and a CP/M card — all at considerable cost on a fellow’s salary.  For software I had WordStar for word processing, Turbo Pascal for programming, VisiCalc (the first spreadsheet program), dBase II (a database program) and lots of games, including the very first version of Flight Simulator. It worked well and was fun to use but over the years it was replaced by more powerful systems and eventually I threw it all out. Now I kind of wish I had kept it (or at least sold it on eBay). I kept all my old Byte magazines though, and paging through them is a trip down memory lane.  It’s fun to revisit those days when Microsoft with its software that could run on anything (as long as it was compatible with an IBM PC) appeared to be heading towards  victory over poor  Apple, despite the coolness of their Macintosh computers. As we all know, a lot has happened between then and now.

Isaacson’s book is very well written and, being the authorized biography, has a lot of material that the other books don’t. Nevertheless, the one period that Isaacson skimps a bit on, the time when Jobs was at NeXT and starting Pixar, is well fleshed out in the other two biographies, particularly Schlendler’s. His thesis is that the struggles at NeXT and Pixar were crucial for Jobs to become a better manager and thus be in a position to return to Apple and turn it around starting in 1997. Schlender also seems a bit more sympathetic to Jobs, though it is hard to paper over some of his worst characteristics.  For example, Jobs denied he was the father of his daughter Lisa, and he abandoned her when she was young. Later he acknowledged being her father and reconciled with her. This behavior seems particularly reprehensible given that Jobs himself was “abandoned” by his biological parents and was raised by foster parents. He eventually met his biological mother and his biological sister, the writer Mona Simpson. He discovered his biological father (who was a Syrian graduate student when Jobs was born) and actually had met him once by chance at a restaurant which his biological father owned, but neither realized the father-son relationship at the time. Jobs chose never to meet with his father again.

Jobs is a complex figure. He was self-centered and lacked empathy towards others. He could turn on the charm, but often in a calculating manner. His biographers point out his black and white approach to everything. To Jobs, other people and even things like food or computers or software programs were either perfect or they sucked. There was no middle ground. He may have mellowed somewhat as he grew older, but not much. Jobs’s genius appears to be that he was able to utilize both his strengths and his flaws together to inspire others to do their best (or get out of his way) and thus design and bring to market products that have certainly changed our world. In the process Apple became the wealthiest company on the planet.  But Jobs’s driving force was not wealth.  He aimed for perfection.

No Greek tragic hero is without his blind spot, and Jobs had his: his quirky views on health and diet. A child of the 60s growing up in California, he maintained a distrust of “western medicine” so that when diagnosed with a potentially surgically curable pancreatic cancer found incidentally on a routine CAT scan (he had a history of kidney stones, thus the CAT scan), he delayed surgery for 9 months. He tried various diets, alternative medicines, and acupuncture first. When he finally yielded to the surgery liver metastases were found, and after that, despite a liver transplant and aggressive chemotherapy it was only a matter of time before he succumbed.

Jobs’s genius was that he foresaw what most others didn’t: apart from the computer geeks like Steve Wozniak and the members of the Homebrew Computing Club back in the 1970s, most people don’t care about computer technology per se. They want to use these devices to listen to music, to read books and articles, to look up stuff, to keep in touch with friends, to watch movies, and to get their work done. For most, computer technology is just a means to an end. Steve Jobs realized this better than anyone else in the industry and had the overwhelming personality to find the best people and motivate them to do perform at levels they didn’t realize they were capable of.

One wonders what symphonies a 60 year old Mozart would have written. What songs were denied to the world when George Gershwin died of a brain tumor at age 38? What would Emily Brontë have written beyond Wuthering Heights if she had not died at age 30?  What other “insanely great” products were denied to the world when Jobs died at age 56?  Life at Apple goes on without Jobs. The hand-picked people he surrounded himself with continue without him. But his will be a tough legacy to uphold.

Who Can Write a Drug Dosage Calculator?

Several years ago I had an idea for a smartphone app that could be used to calculate doses for drugs that are prescribed frequently to patients with heart rhythm problems. These drugs include antiarrhythmics such as dofetilide and sotalol, and the new oral anticoagulants such as dabigatran and rivaroxaban. These drugs are handled by the kidneys, and dosage is dependent on kidney function. The package inserts for these drugs advise the correct drug doses based on the calculated creatinine clearance, a formula that involves the patient’s weight, age, sex and serum creatinine. Once the creatinine clearance is calculated, a lookup table is used to determine the dose. For example, here is the rivaroxaban dosing information:

xarelto

Medical calculator apps are common and invariably include a creatinine clearance calculator. The problem I had was trying to remember all the different creatinine clearance cutoffs for each dose of each drug. This seemed like perfect job for an app. Just fill in the information needed to calculate the creatinine clearance and have the app figure out the creatinine clearance and look up the dose. Thus my app EP Mobile was born. Over the years I have added many more modules to the app, including everything from algorithms localizing accessory pathways to entrainment mapping, but the original concept was to provide the drug dose calculators which remain a key part of the app.

Or maybe not. I routinely update the app, and submitted an update a week ago to Apple (not related to the drug dose calculators). For the first time ever I received a rejection from Apple. They quoted this from their App Store Submission Guidelines:

22.9 Apps that calculate medicinal dosages must be submitted by the manufacturer of those medications or recognized institutions such as hospitals, insurance companies, and universities

Attached were screenshots of the offending calculators:

A drug dose calculator
A drug dose calculator

I am a physician. Part of my job is to calculate medicinal dosages, as the legalese above terms it. This is not the job of hospitals, insurance companies, or universities. Ultimately I as a physician am legally responsible for calculating correct dosages. Yet somehow physicians are left off the list of those qualified to submit apps that calculate drug dosages. The development of an app that simply does what the drug package insert instructs the physician to do in order to calculate a drug dosage, but in an easier manner, should not be restricted to drug companies, hospitals, insurance companies (insurance companies?) or universities. The few of us physicians who are also app developers are certainly in as good a position as any of these other parties to develop apps like this. The algorithms to calculate these doses are extremely simple.  As my app is open-source, the source code is freely available for anyone to inspect to make sure the calculations are coded properly.

I appealed this decision to Apple and I hope they reconsider. I doubt they will. I see the handiwork of Apple’s legal department here. Don’t trust physicians to figure out what tools are useful on their own. Far better to let them go back to carrying around a bunch of drug company propaganda plastic rulers and let them do those creatinine clearance calculations by hand, using long division. Just like back in the good old days.