Device types in iOS

I sometimes need to know the device type that the app is running on. I use this method in my Utilities class to do it. Updated for the new devices introduced in the fall of 2014.


+ (NSString *)deviceType {
    NSString *device = nil;
    CGSize screenSize = [[UIScreen mainScreen] bounds].size;
    CGFloat deviceScale = [UIScreen mainScreen].scale;

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
        device = @"iPhone Classic"; // Just in case it doesn't make it through the conditionals
        // Classic has a resolution of 480 × 320
        if( (screenSize.height == 480 || screenSize.width == 480) && deviceScale == 1.0f ) {
            device = @"iPhone Classic";
        // Retina has a resolution of 960 × 640
        } else if( (screenSize.height == 480 || screenSize.width == 480) && deviceScale == 2.0f ) {
            device = @"iPhone Retina35";
        // Retina 4" has a resolution of 1136 x 640
        } else if (screenSize.height == 568 || screenSize.width == 568 ) {
            device = @"iPhone Retina4";
        // iPhone 6 has a resolution of 1334 by 750
        } else if (screenSize.height == 667 || screenSize.width == 667 ) {
            device = @"iPhone 6";
        // iPhone 6 Plus has a resolution of 1920 by 1080
        // Reported size is 736 x 414
        } else if (screenSize.height == 736 || screenSize.width == 736 ) {
            device = @"iPhone 6 Plus";
        }

    } else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        device = @"iPad Classic"; // Just in case it doesn't make it through the conditionals
        if(deviceScale == 1.0f) {
            device = @"iPad Classic";
        } else if (deviceScale == 2.0f) {
            device = @"iPad Retina";
        }
    }
    //NSLog(@"The device is %@ scale is %f and the height is %f and width is %f", device, deviceScale, screenSize.height, screenSize.width);

    return device;
}

Things I can’t remember – Git

In git you clone a project—not checkout like in Subversion. You’ll probably want to put it in a directory that has a name that is the same as the project (or related to the project name).


$ git clone git://github.com/hubuser/importantProject.git importantProject

If you are hosting your own git server, you’ll probably use something like this.


$ git clone username@yourdomain.com:/www/importantProject/ importantProject

Once you’ve cloned the repository you’ll have the exact same files and file structure as the original. You’ll also be in the master branch.


$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working directory clean

You’ll also get a .git directory with the following files.


$ cd .git
total 28
-rw-r--r--   1 username  staff    23B Jun  2 09:31 HEAD
drwxr-xr-x   2 username  staff    68B Jun  2 09:31 branches/
-rw-r--r--   1 username  staff   312B Jun  2 09:31 config
-rw-r--r--   1 username  staff    73B Jun  2 09:31 description
drwxr-xr-x  11 username  staff   374B Jun  2 09:31 hooks/
-rw-r--r--   1 username  staff   8.8K Jun  2 09:34 index
drwxr-xr-x   3 username  staff   102B Jun  2 09:31 info/
drwxr-xr-x   4 username  staff   136B Jun  2 09:31 logs/
drwxr-xr-x   4 username  staff   136B Jun  2 09:31 objects/
-rw-r--r--   1 username  staff   107B Jun  2 09:31 packed-refs
drwxr-xr-x   5 username  staff   170B Jun  2 09:31 refs/

Now suppose I modify my robots.txt file.


$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

  modified:   robots.txt

no changes added to commit (use "git add" and/or "git commit -a")


$ git diff
diff --git a/robots.txt b/robots.txt
index 90098a4..3aa5532 100755
--- a/robots.txt
+++ b/robots.txt
@@ -1,3 +1,5 @@
 # robots.txt for http://www.rememo.info/

 User-agent: *
+Disallow: /order/
+

Before we commit the file, we need to stage it. The status command above tells you how to to it.


$ git add robots.txt

We can see the staged changes with:


$ git diff --staged
diff --git a/robots.txt b/robots.txt
index 3aa5532..abd2889 100755
--- a/robots.txt
+++ b/robots.txt
@@ -3,3 +3,4 @@
 User-agent: *
+Disallow: /order/


Now $git diff returns nothing because there are no unstaged changes.

We can add and commit it in one command.


git commit -a
[master 4623ad2] Added a disallow
 1 file changed, 2 insertions(+)

Alternatively, you can combine the commit with the message.


git commit -a -m "Added a disallow"
[master 4623ad2] Added a disallow
 1 file changed, 2 insertions(+)

You can remove files from the repository by deleting them from your work area. They will show up in the unstaged area or you git status output. You can also use git rm to remove a file.

Likewise you can rename a file with mv originalName newName and git will notice. Or you can use git mv originalName newName.

You can view the commits that you have made with git log.


$ git log
commit 4623ad2cbe4163e2d013c7e53728023e4d7163e6
Author: User Name < username@WellGolly.com >
Date:   Tue Jun 3 07:55:00 2014 -0700

    Added a disallow

commit 065b7362f9ad19d6e2fe69cde9629abf0beabb95
Author: User Name < username@WellGolly.com >
Date:   Mon Feb 24 09:00:03 2014 -0800

    Changed site name and added blank line at end of files

commit 61277e4d12636044e9b873608c325470d98577e0
Author: User Name < username@WellGolly.com >
Date:   Mon Feb 24 07:50:56 2014 -0800

    Started tracking changes to site with git.

If you want to see the changes that were made as well, use the -p option (page option) and the output will be piped into a pager where you can page through all the changes. Hit ‘q’ to quit the pager.

You can browse the commit messages with the –pretty option.


$git log --pretty=oneline
4623ad2cbe4163e2d013c7e53728023e4d7163e6 Added a disallow
065b7362f9ad19d6e2fe69cde9629abf0beabb95 Changed site name and added blank line at end of files
61277e4d12636044e9b873608c325470d98577e0 Started tracking changes to site with git.

Once you have identified the commit you want more info on you can display the info with git show and the first few digits of the hash. Usually five digits is enough to uniquely identify the commit, but you can use all of them if you want.


$ git show --format=raw 4623a
commit 4623ad2cbe4163e2d013c7e53728023e4d7163e6
tree 9c73a1afbfb9ec4930d3d4ac8d906e6ae4683df6
parent 065b7362f9ad19d6e2fe69cde9629abf0beabb95
author User Name <username@WellGolly.com> 1401807300 -0700
committer User Name <username@WellGolly.com> 1401807300 -0700

    Commit message

diff --git a/robots.txt b/robots.txt
index 90098a4..3aa5532 100755
--- a/robots.txt
+++ b/robots.txt
@@ -1,3 +1,5 @@
 # robots.txt for http://www.rememo.info/

 User-agent: *
+Disallow: /order/
+

Often you might be looking for the last time a particular file was changed. –name-only gives the name of the file, the commit message, and the hash.


$ git log --name-only
commit 4623ad2cbe4163e2d013c7e53728023e4d7163e6
Author: Gordon Miller <developer@well.golly>
Date:   Tue Jun 3 07:55:00 2014 -0700

    Added a disallow

robots.txt

commit 065b7362f9ad19d6e2fe69cde9629abf0beabb95
Author: jscarry <jscarry@learningfundamentals.com>
Date:   Mon Feb 24 09:00:03 2014 -0800

    Started tracking changes to site with git.

Reminder/README.txt
Reminder/Reminder.inc
:

SPF Record

Gmail has started bouncing my order confirmation emails so I need to start using some of the anti-spam indicators. One of them is an SPF record. Since I use Linode, there is a tab that lets me create the record. Deciding what to put in it is a bit complicated, but not too bad.

You can create a very simple SPF record or more detailed. I chose to get a little detailed in hopes that it would satisfy Google. You can find details of all the parameters at OpenSPF or Wikipedia.

The simplest record just says to allow all mail from the domain if there is a mail record in the DNS.


example.com  text = "v=spf1 mx ~all"

To see what an SPF record looks like, open the terminal and type the following


nslookup -type=txt Google.com

Your response should look like this:


google.com  text = "v=spf1 include:_spf.google.com ip4:216.73.93.70/31 ip4:216.73.93.72/31 ~all"

If you are using a Linode VPS, mail is sent using IPV6 so you also need an ip6 record. Linode itself uses MailChimp, so their SPF record is:


linode.com  text = "v=spf1 mx include:servers.mcsv.net ~all"

In my case, I set up my SPF record to include charter.net, since I also mail from the office and both my IPV4 and IPV6 address. In the Linode control panel, the data between the quotes is pasted into the form and Linode takes care of creating the record.

Removing items from NSMutableArray’s

I have an NSMutableArray in Objective-C that I want to remove items from so that it has just the number of items that will be displayed in a grid on the screen. The number of items varies, but on one screen it is 9. The array has more items, but I don’t necessarily know how many. [Remember that array items are numbered with an index starting at 0. So the last index number of my array of 9 items is 8′]

This is the original code that I tried.


NSUInteger itemsOnScreen = 9;
for (NSUInteger i = itemsOnScreen; i < gridItems.count; i++) {
    [gridItems removeObjectAtIndex:i];
}

This code doesn’t delete all of the items so I decided to start at the end and delete items until I there were only 9 left. This is the code that I ended up using.


NSUInteger itemsOnScreen = 9;

for (NSUInteger i = gridItems.count - 1; i > itemsOnScreen - 1; i--) {
    [gridItems removeObjectAtIndex:i];
}

It’s kind of ugly and after working with it it occurred to me why the original code didn’t work. As I started deleting items, the number of items, and hence the index of the last item changed. So it worked fine for the first few, but as I neared the end of the loop, there were no items with an index that matched i. If I just delete the first item after the 9 that I want, then the loop works fine.


NSUInteger itemsOnScreen = 9;
for (NSUInteger i = 0; i < gridItems.count; i++) {
    [gridItems removeObjectAtIndex:itemsOnScreen];
}