Upgrading from Windows to a Mac

The last time I used Windows for more than a half-hour at a time was Windows 3.1, so temper what I say about Windows with your own experience. There are lots of superficial differences between Mac and Windows and one major difference. And that’s the way they handle the menubar. The first screen you see on your Mac has a menubar at the top of the monitor. There is an Apple and a bunch of menu commands. The stuff under the Apple never changes when you open new programs, but the stuff to the right of it does. The Apple is similar to the Start button on Windows. You can access the System Preferences and Sleep/Shut Down/Log Out there. There is also an item called Recent Items that is very handy for opening files that you recently worked on or Applications that you recently had open.

When you open a new program, the menubar at the top of the screen changes. It has the commands associated with the current program. All of the menubars start with File and Edit and all end with Help. In between, they differ but most have a View option. Programs that do text editing usually have a Format option. Here’s the big difference between Mac and Windows. When you open multiple documents on the Mac you don’t get new menubars, you get new document windows. Most programs lots of other little windows that they use for palettes. Sometimes they open automatically. Other times they don’t open until you select them from the menubar. You can move these around on the screen to wherever they make the most sense for you. Most of the time, when you quit an application, the next time it opens it will remember where you put the palettes and which ones were open.

One thing that I have heard is much different on Macs than on Windows is the way that folders are copied. On the Mac, if you drag a folder from one location to another and there is already a folder with the same name in that location, all of the contents of the existing folder will be replaced with the contents of the new folder. Same thing if you drag a file into a folder that has a folder with the name of the file. You will be prompted to replace it, but if you say yes, the folder no longer exists and there is a file there instead. I have been told that on Windows individual files are replaced if they have the same name. Existing files are not erased.

Don’t waste your money on anti-virus. Do keep vigilant about phishing attacks. They seem to have increased lately. My Windows guy recommends using the Microsoft anti-virus if you run Parallels for Windows.

I don’t do much fancy word processing, and when I do I use InDesign. I mostly use Bean http://www.bean-osx.com/Bean.html for formatted text. New Macs come with a free copy of Numbers and Pages which will open most Office documents. Pages and Numbers are very unintuitive to me, but if you are used to Microsoft products, I’ve heard that they are easy to pick up. Every once in a while someone sends me Excel spreadsheets and I use LibreOffice to open them. No one complains when I send them back, so I’m guessing it’s compatible. It’s also free.

If you do any audio processing download a free copy of Audacity.

Don’t bother downloading Flash or Adobe Reader. Most websites that use Flash have an HTML5 version that runs fine in Safari. Download a copy of Google’s Chrome browser for the sites that use Flash. Or you can turn on Developer mode and tell the website that you are an iPad. A lot of Mac users like Chrome better than Safari. Especially the geekier ones who like to use a lot of plug-ins.(Some of my demos only run in Flash and if you are a Stewart/Colbert fan you’ll need Flash to watch their clips.) There are also network TV shows that play better in Chrome and some YouTube clips won’t play without Flash.

You’ll also want to download Jumpcut for getting access to your clipboard. It lets you paste things you copied a while ago into the current document. I use it hundreds of times a day. Also free.

You also need Easy Envelopes for printing envelopes. It’s from Ambrosia Software or the Mac App store. Best $9.99 I ever spent. It’s a widget that installs on your dashboard (F12)

You should learn to use the dashboard. I have the current METAR (a Web Clip), a calculator, weather, a unit converter, and Easy Envelopes on my dashboard.

If people send you random videos (and you watch them) you’ll want to download VLC. It opens just about any video format.

If you want a flight simulator, purchase X-Plane.

There are some people who like to have everything on the desktop. I’m not one of them. I usually have whatever I’m currently working on there and then file it away when I’m done. The default place to store files is Documents. I have most of my stuff there. I created a folder called Current that I put in Documents. The name has a space in front of it so that it sorts first. I put all the stuff that I need to deal with in the near future in that folder. That way it’s not cluttering up my desktop and I don’t forget to deal with it.

Learn to use Time Machine. I have two Western Digital 3TB hard drives. I do a Time Machine backup on one every couple of days of them. The other one is in the hangar and I bring it home once a month to do a backup. That’s probably overkill for most people. If you organize your hard drive, you can probably make due with a Time Machine backup and a removable USB stick.

I’d recommend that you put anything that would be a real pain to replicate on a USB stick and keep it somewhere that your computer isn’t. I have my accounting data and my customer database backed up on USB sticks. Every time I go to the office I leave one stick and take home the other. Worst case I lose a couple of days of data. I have never personally had a catastrophic data loss, but I know plenty of people who have. YMMV

There are lots of right-click items that are really useful. If you are in a web browser, mail, or most programs that deal with words, right click on a word and you can do a dictionary lookup or search with Google. If you don’t have a mouse with a right mouse button, Control-click on the word. If you’ve misspelled the word, you get suggestions on how to spell it. Opening the spelling and grammar panel is also one of the options.

Vuescan for Mac will handle just about any scanner. It also has lots of scanning options. With a little work, Image Capture will do the same thing. You just need to download and install the TWAIN SANE Plugins. I haven’t needed to scan anything for a while, but it worked fine using Mountain Lion on two of my scanners that are at least 15 years old. They have plug-ins for Mavericks, but I haven’t tried them. http://www.ellert.se/twain-sane/

I also use Image Capture to get photos off my digital camera. For me, it works better than iPhoto. If you do lots of Photo work, you’ll want to get Aperture or Adobe’s Lightroom.

NSNotification

I wrote most of this post for StackOverflow since I’m getting multiple UIKeyboardDidShowNotification and UIKeyboardDidHideNotification notifications when I rotate the device and I can’t figure out why. But it has a good example of how to do notifications in iOS so I thought I’d post it here.

I have an app that lets you edit the text for each picture. (it’s in a UITextView.) Most of the time I need to slide the text up so you can see it above the keyboard, then I slide it down when you are done editing. Then I do a database update to save the new text. I use notifications to tell me when the keyboard is displayed and when it goes away. It works fine on iPad when the user taps the keyboard close icon on the keyboard. It also works fine if the user swipes to the next page and iOS closes the keyboard. Since iPhones and iPods don’t have a keyboard close key, I wrote a method to close the keyboard when the picture or background is tapped.

In my class that displays the pictures I start notifications when it is initialized.


- (id)initWithParentView:(UIView *)parentview  {
    
    self = [super init];
    if (self) {
        _parentView = parentview;
        if (ALLOW_DATABASE_EDITING) [self startNotifications];
    }
    
    return self;
}

- (void)startNotifications {
    
    // Listen for keyboard appearances and disappearances
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardDidShow:)
                                                 name:UIKeyboardDidShowNotification
                                               object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardDidHide:)
                                                 name:UIKeyboardDidHideNotification
                                               object:nil];
}

Note that the @selector() is the name of the method that is called when the notification center gets a notification.
The View Controller calls the hideKeyboard method in the View when the user taps on the picture.


- (void)dismissKeyboard {
    
    if (self.showArtic.keyBoardIsShowing) {
        [self.showArtic hideTheKeyboard];
    }
}
<code>

resignFirstResponder sends a notification that closes the keyboard. When it hides a notification is sent and the keyBoardDidHide method is called.
<code class='smaller'>
- (void)hideTheKeyboard {
    
    id <ShowArticDelegate> SA_delegate = _delegate;
    // Don't update the database when there is no text.
    if ( ![self.editableTextView.text isEqualToString:@""] ) {
        [SA_delegate updateTextInDatabase:self.editableTextView.text];
    }
    [self.editableTextView resignFirstResponder];
}

These methods respond to the notifications. I use block animations to move the text up and back. I also shade the background so it stands out a bit, but the picture is still visible under the text block. The self.keyBoardIsShowing flag is used in the view controller to decide whether to tell the keyboard to hide when the picture is tapped.


- (void)keyboardDidShow:(NSNotification *)notification {
    NSLog(@"keyboardDidShow called. Keyboard showing flag is %@.", self.keyBoardIsShowing ? @"YES" : @"NO");
    self.keyBoardIsShowing = YES;
    if (self.textShiftAmount > 0) {
        self.editableTextView.backgroundColor = [UIColor colorWithRed:240/255.0f green:240/255.0f blue:240/255.0f alpha:.5f];
        [self.parentView bringSubviewToFront:self.editableTextView];
        [UIView animateWithDuration:.7
                         animations:^{
                             
                             CGRect frame = self.editableTextView.frame;
                             frame.origin.y = self.pictButton.frame.origin.y + self.pictButton.frame.size.height - self.textShiftAmount;
                             self.editableTextView.frame = frame;
                             
                         }
                         completion:^(BOOL finished){
                         }];
    }
}

- (void)keyboardDidHide:(NSNotification *)notification {
    NSLog(@"keyboardDidHide called. Keyboard showing flag is %@.", self.keyBoardIsShowing ? @"YES" : @"NO");
    self.keyBoardIsShowing = NO;

    id <ShowArticDelegate> SA_delegate = _delegate;
    // Don't update the database when there is no text.
    if ( ![self.editableTextView.text isEqualToString:@""] ) {
        [SA_delegate updateTextInDatabase:self.editableTextView.text];
    }
    if (self.textShiftAmount > 0) {
        self.editableTextView.backgroundColor = [UIColor whiteColor];

        [UIView animateWithDuration:.7
                         animations:^{
                             
                             CGRect frame = self.editableTextView.frame;
                             frame.origin.y = self.pictButton.frame.origin.y + self.pictButton.frame.size.height;
                             self.editableTextView.frame = frame;
                             
                         }
                         completion:^(BOOL finished){
                             self.editableTextView.backgroundColor = [UIColor clearColor];
                         }];
    }
    
}

Programmatically move a segmented control.

I have a .xib file that I use for options. One of the options is a sound delay before I play a synthesized sound. Since synthesized sound is not available before iOS7, I figured that I’d hide the option. But that leaves a gap in the screen where the control used to be. This code moves the next segmented control up to where the original one was. Make sure you link the text label to the Files Owner by control clicking and dragging from the Files Owner to the label in Interface Builder section of Xcode.


if ( SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(@"7.0") ) {

    // Hide the delay control
    self.chooseDelaySegmentedControl.hidden = YES;
    self.targetSoundDelayText.text = @"";

    // Move the segmented control up
    CGRect scoringTypeFrame = self.chooseScoringTypeSegmentedControl.frame;
    scoringTypeFrame.origin.y = scoringTypeFrame.origin.y - 70.0f;
    self.chooseScoringTypeSegmentedControl.frame = scoringTypeFrame;
    
    CGRect scoringTypeTextFrame = self.scoringChoiceText.frame;
    scoringTypeTextFrame.origin.y = scoringTypeTextFrame.origin.y - 70.0f;
    self.scoringChoiceText.frame = scoringTypeTextFrame;
    
} 

Oddly enough, you can’t just change the x or y value, you need to change the whole frame.

Synthesize By Default

In 2012 Apple introduced Synthesize By Default in Xcode. You no longer have to synthesize instance variables. Just declare them as you normally would in the .h file and the compiler will automatically synthesize them for you. I learned how to use Xcode before the transition so I just learned about this by accident. If you haven’t done so, watch these two videos from WWDC 2012: Session 405 – Modern Objective-C and Session 413 – Migrating to Modern Objective-C.

Synthesize By Default is not available for NSManagedObjects so if your header file contains something like this:


@interface WordList : NSManagedObject

You’ll have to synthesize.

You can still manually create setters or getters and the compiler will automatically create the other accessor.

One caveat. I stopped supporting iOS4.3 and still have code that is compatible with iOS4. Since doesn’t have the weak indicator, you need to change assign to weak, then delete the ‘__unsafe_unretained id delegate;’ line. Then you can delete the @synthesize. If you still want to support iOS4, you’ll need to synthesize these variables.

Before


@implementation PracticeSightWords
@synthesize delegate = _delegate;


@interface PracticeSightWords : UIViewController {
    
    __unsafe_unretained id <PracticeSightWordsDelegate> delegate;
}

@property (nonatomic, assign) id <PracticeSightWordsDelegate> delegate;

After


@interface PracticeSightWords : UIViewController 

@property (nonatomic, weak) id <PracticeSightWordsDelegate> delegate;

I have my compiler warnings Turned up to 11 so I needed to turn off the warnings for “Implicit Synthesized Properties” in the ‘Warnings-Objective C’ section of the build settings.

New Icons and Launch Images for iOS7

iOS7 requires new images for the icons and launch image and Xcode now provides a new way of validating that you have all of the required images.

Just to see what Xcode would do, I created a new app from scratch and looked at the images it requires.

Launch Images

I then took a look at what an existing app looks like. The first thing I noticed is that I forgot to include the 100×100 iPad retina image. Then I noticed that the last four launch images are the same as the ones that I already have.

Launch Images

I manually added the Portrait Non-Retina and it automatically found the retina version. Then I added the Landscape Non-Retina and it found the retina. I looked in the .plist for the app and Xcode had added lines for the new files. Since I have over 20 apps I didn’t want to repeat this 20 or more times so I right-clicked on the file, opened the .plist as source, then copied the following lines.


<key>UILaunchImages~ipad</key>
  <array>
    <dict>
      <key>UILaunchImageMinimumOSVersion</key>
      <string>7.0</string>
      <key>UILaunchImageName</key>
      <string>Default-Landscape</string>
      <key>UILaunchImageOrientation</key>
      <string>Landscape</string>
      <key>UILaunchImageSize</key>
      <string>{768, 1024}</string>
    </dict>
    <dict>
      <key>UILaunchImageMinimumOSVersion</key>
      <string>7.0</string>
      <key>UILaunchImageName</key>
      <string>Default-Portrait</string>
      <key>UILaunchImageOrientation</key>
      <string>Portrait</string>
      <key>UILaunchImageSize</key>
      <string>{768, 1024}</string>
    </dict>
  </array>

I pasted these lines into the same place in each of the .plists.

While I was at it, I added a line to my pre-iOS7 images list for the file I forgot to include. That section now looks like this:


  <key>CFBundleIconFiles</key>
  <array>
    <string>Icon.png</string>
    <string>Icon@2x.png</string>
    <string>Icon-72.png</string>
    <string>Icon-72@2x.png</string>
    <string>Icon-Small-50.png</string>
                <string>Icon-Small-50@2x.png</string>
    <string>Icon-Small.png</string>
    <string>Icon-Small@2x.png</string>
  </array>

I then used Xcode to add the new images. (Note: As far as I can tell, you can name them anything you want. I followed a logical extension of the old rules.) I used the same image for Spotlight iPad Retina and iPhone Retina (80×80) so I name it Icon-402x.png.
Xcode added an iPad section to the .plist. The .plist now looks like this:


<key>CFBundleIconFiles</key>
  <array>
    <string>Icon-40</string>
    <string>Icon-iPhone-60</string>
    <string>Icon.png</string>
    <string>Icon@2x.png</string>
    <string>Icon-72.png</string>
    <string>Icon-72@2x.png</string>
    <string>Icon-Small-50.png</string>
    <string>Icon-Small-50@2x.png</string>
    <string>Icon-Small.png</string>
    <string>Icon-Small@2x.png</string>
  </array>
  <key>CFBundleIconFiles~ipad</key>
  <array>
    <string>Icon-40</string>
    <string>Icon-iPad-76</string>
    <string>Icon-iPhone-60</string>
    <string>Icon.png</string>
    <string>Icon@2x.png</string>
    <string>Icon-72.png</string>
    <string>Icon-72@2x.png</string>
    <string>Icon-Small-50.png</string>
    <string>Icon-Small-50@2x.png</string>
    <string>Icon-Small.png</string>
    <string>Icon-Small@2x.png</string>
  </array>

Xcode has a new folder type for Asset Catalogs. I did not convert my icons to asset catalogs, but it looks like a good way to manage assets.