Sunday, February 17, 2013

Testing on an iPhone 5

So, I have a borrowed iPhone 5, which I'm planning to test my app on. I'll never get this process down, no matter how many times I do it. But, IIRC, you need to set up a "provisioning profile", which is unique to the developer, device and app.

If I try to run it without doing anything, I get this error message: "The entitlements specified in your application’s Code Signing Entitlements file do not match those specified in your provisioning profile." I'm assuming that it's because the app doesn't have a provisioning profile specifying the new device.

Ok, here's what I did:

1) Went to organizer, right clicked on the device (the iPhone 5) and selected "add device to provisioning portal"
2) Noticed from the link below that my app id must be a specific one (not wildcard) because it uses in-app purchases.
3) Since there was only one profile that matched the app name (see bundle-id in the plist) that was specific, I knew that had to be the one.
4) I checked the devices associated with the profile, and the iPhone was on it from step 1.
5) I downloaded the devices and double-clicked it.
6) That brought it into the keychain, I think.
7) I ran the app and it worked!

Here's the link I was looking at:


http://iphone.gumbypp.com/provisioning.html

"Provisioning is the way by which you can test on a device. Only iPhone developer program members get this privilege - which is reasonably priced at $99/year. All of the action starts at the Developer program portal. 

Here's what you need to do for on-device testing: 

    Create a certificate - this I have

    Create a specific or Wild-card App ID - have

    Add one or more test devices - would be nice to have to just add the device. 

    Create a provisioning profile

    Install the app on the test device(s)

    Go have a beer if it all worked!



Ok, what is my provisioning profile for this app? Maybe it's in Organizer, or Keychain. 

Well, Organizer has a couple of them. One is name "Jlpt Vocabulary Quiz App Profile". Created on 2/6/13, expiration at the end of this year. Another is the JLPT profile for iPhone. It was created 1/20/2013 and expires a year from that. 

Here's the part on certificates: 


Certificates
Enter the program portalClick on the "Certificates" link on the left panelSelect the "Development" or "Distribution" tabFollow the steps under the "How To" tab to actually create a certificate:Generating a Certificate Signing RequestSubmitting a Certificate Signing Request for ApprovalApproving Certificate Signing RequestsDownloading and Installing Development CertificatesSaving your Private Key and Transferring to other Systems


You'll probably need at least one development certificate and one distribution certificate. You'll need a development certificate if you want to test with the APNS (Apple Push Notification Service) sandbox, or if you want to debug on the device with Xcode. I've never needed more than one of each. The distribution certificate can be used for both Ad Hoc and App Store distributions. Each certificate can be mapped to one or more devices in a profile when provisioning.


Note: make sure that you install the "WWDR Intermediate Certificate". 

Adding devices:

DevicesThis is how you add a new device (iPhone, iPod Touch and maybe even the new iPad) to your account. Such devices can then be provisioned with a development or distribution profile to run apps that are not available in the App Store (this is called "Ad Hoc" distribution).Adding new devices:    Enter the program portal    Click on the "Devices" link on the left panel    Click on "Add Devices" to enter each device's ID (40 hex characters). The device ID is available from iBeta (a free download from the app store) or from iTunes by clicking on the "Serial Number" label in the device's "Summary" tab. See here for more info.Note: You can only have 100 devices per license-year. If you delete a device, the slot won't actually be available until the renewal date of your license. Once you add a device after your renewal date, all used slots get locked-in until the NEXT year. "







Saturday, February 16, 2013

Converting to iPhone 5 - step 2.

Ok, today I'm going to try to get a non-spash-screen to work in the iPhone.

Since there was a separate image for the splash, I wonder if I need a separate image for all the screens? Or can auto-resize somehow work?

One guy on SO says

"You shouldn't change the size of your xibs, because you'll want your app to work on both old and new phones. However, you may want to change the autoresizing masks of some of the views in your xibs so that they stretch to fill the larger screen."

Ok, this looks good:

"Make sure, your Xibs/Views use auto-layout to resize themselves.

Use springs and struts to resize views.

If this is not good enough for your app, design your xib/storyboard for one specific screen size and reposition programmatically for the other."

Ok, step one is to figure out how to get the xibs to auto-layout.

Ah, wait, that's the one that only supports the iPhone five.

It's the auto-resizing masks that I need.

I found a post that says use the size inspector in the nib to set it. So, if I click on the size inspector, I get that display which has the struts and springs - looks like a square with a shock absorber.

Clicking on view doesn't let me do anything with it, but if I click on image view, it lets me select arrange position view of "resize vertically". Let's give it a try.

Hmm.. Nothing. Why not?

I just have a feeling I'll need to create a new screen size and code for it. Urgh.

This resizing thing seems to be more oriented toward landscaping. It has to do with when the superview changes size. But, it's not changing size, it's starting out at that size. Could that be the problem, somehow?

Whoah - this guy has *exactly* the same problem i do:

http://stackoverflow.com/questions/12595049/iphone-5-cant-get-images-to-auto-resize

and no answers!

I think I'm just going to go straight to loading a separate image based on the difference size.


CGRect screenBounds = [[UIScreen mainScreen] bounds];
if (screenBounds.size.height == 568) {
    // code for 4-inch screen
} else {
    // code for 3.5-inch screen
}

But, what do I put inside those lines? How do I load the image?

How about this:


UIViewController *viewController3;

  if ([[UIScreen mainScreen] bounds].size.height == 568)
  {
    UIViewController *viewController3 = [[[mainscreenview alloc] initWithNibName:@"iphone5screen" bundle:nil] autorelease];               
  }    
  else
  {
     UIViewController *viewController3 = [[[mainscreenview alloc] initWithNibName:@"iphone4screen" bundle:nil] autorelease];
  }


What does initWithNibName do? Do I have to have a separate nib file? Thats' not cool.

hmm...I just saw a suggestion to set the image size to the iphone 5 size, and let it be cropped...

That would be easy. Hmmm...no. It just shows the stretched image taking the same area as the previous unstretched image.

Ok, here's the trick. Just go to the nib, select attributes, and set the size to "retina 4 full screen".

Then click on the image view, which is now showing the white space, and drag it down to the bottom of the containing view.

Actually, I ended up setting the size to "none". In a couple of views, I set the size physically like this:

background = [UIImage imageNamed: @"plum_blossoms3_568.png"];
    
Although, the "_568" is not a good name, because the real size is 468 x 548 pixels for the one I name 568, because I just took the existing height / 4 * 5 and increased the height to that. 

A couple of the views had image views instead of loading the image as shown above, and I just changed the attached view to the _568 and it seemed to work ok. Although, on on display, I had to use the struts in the nib to anchor the top and bottom by setting them red, which turns off auto-sizing from the center view to the superview, which means the distance is fixed, thus the anchor. Note that setting the autosize to red on the inside allows the view to expand, so I did that for the vertical and it fixed the problem.

Alright, next step - the grueling process of testing on on a borrowed iphone 5! 





iPhone 5 - changing to, and running on.

So, I decided to submit my app, and they came back saying they needed screenshots for an iPhone 5. It's always something! So, when I ran it on an iPhone 5 simulator, of course the bottom of the display is all white, because the display is longer. I think this is going to be yet another painful process, because I vaguely remember struggling to get the background, which is based on a ragged, parchment kind of motif to fit. It other, this is going to *SUCK*.

Anyway, we'll never know until we try. So, let's google something basic like convert app to iphone 5.

"You definitely need to install XCode 4.5, and to create a new splash image for the 4-inch screen, called Default-568h@2x.png.
You shouldn't change the size of your xibs, because you'll want your app to work on both old and new phones. However, you may want to change the autoresizing masks of some of the views in your xibs so that they stretch to fill the larger screen."

I'm on 4.6, so that's not an issue. This new splash image, I don't have any idea.

It would be nice if I just have to change some autoresizing masks.

This one has a ton of upvotes:


  1. Download and install latest version of Xcode.
   // I did that recently

  1. Set a 4-inch launch image for your app.
// This must be "create a new splash image for the 4-inch screen, called Default-568h@2x.png."

  1. This is how you get 1136 px screen height (without it, you will get 960 px with black margins on top and bottom).
// 960 must be the 3.5 

  1. Test your app, and hopefully do nothing else, since everything should work magically if you had set auto resizing masks properly.
// 

  1. If you didn't, adjust your view layouts with proper auto resizing masks or look into Auto Layout if you only want to support iOS 6 going forward.

  1. If there is something you have to do for the larger screen specifically, then it looks like you have to check height of [[UIScreen mainScreen] bounds] (or applicationFrame, but then you need to consider status bar height if it's present) as there seems to be no specific API for that.

Example:
CGRect screenBounds = [[UIScreen mainScreen] bounds];
if (screenBounds.size.height == 568) {
    // code for 4-inch screen
} else {
    // code for 3.5-inch screen
}
Also note: The auto-rotation API has changed completely, take a look at that as well if your application supports any rotation other than default.
// Ok, let's create an image called Default-568h@2x.png that's 4 inches high (why's it named
// 568, which is 1/2 1036 px?

Hmm - what's my current splash screen named?

So, I found an older blog which says there's a function built-in to iOS which automatically loads the splash screen, no coding needed. The iPhone 4 splash is 960 by 640, which is easy to remember because 960 is just like 9630 without the 3 and 640 is like 6420 without the 2. Also, the 6 in 960 is the first digit of the 640.

More good info:
"The splash screen image should be in PNG format. By default, you should name the image file for lower screen resolution as “Default.png”. For the image intended for Retina Display (i.e. 640 x 960 screen resolution), name the file as “Default@2x.png”. The “@2x” is a standard scale modifier used in iOS. All image files designated for displaying in Retina Display should name with the optional string “@2x”.

Let's see if I have anything named that...no such luck.

Ok, let's display it in the simulator - command - s saves it directly to the desktop. Then, double-click on the image and brings it up automatically in preview. Go to tools, size and see it's very nicely in 960 x 640. So, next step is see how to get it into the app. to display.


Ok, well, the splash page works. Of course, the others don't.  I'll tackle them in my next post.