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.  








Sunday, January 20, 2013

Provisioning Profiles - a labor of love

Well, this provisioning profile thing has turned out to be quite a bear - as it always is. Yesterday, I found a post in stack overflow that seemed to be getting to the root of the issue. Today, I'm going to try to see if it works.

The first thing I'm doing is backing up the project (I know - I need to put it on git or svn).

Wait. I need to rename my device, because right now it's confusingly called "My Name's iPod" when it's an iPhone. Arghh.

I deleted my app profiles, but when I try to create a new one, it's showing up with the iPod name, though (as before) with the correct id for my iPhone.

Ok, I had to delete the old one, then added the device from Xcode's organizer view. A small victory, at least. It's showing up now as iPhone (which, btw, I renamed in organizer also just by double-clicking).

Ok, for grins I'm going use the assistant to create a provisioning profile.

At the launch:


"Introduction
To run an application you're developing for iPhone, iPad or iPod touch, you must have a Provisioning Profile and a Development Certificate installed on your device and your Mac. The Provisioning Assistant will guide you through the steps to create and install your Development Provisioning Profile and iOS Development Certificate."

So, the profile and dev cert have to be on *both* the device and the Mac. 

Ok, now select an app. 

That's good. The app name is "JlptVocabQuiz". 

Now,  choose an existing iPhone device - pick my iPhone (just renamed). 

Now, "Use your existing developer certificate".  Ah, it's all starting to make sense. This wizard really organizes the process nicely. 

Now:

"Name your Provisioning Profile

A Provisioning Profile is a collection of your App ID, Apple device UDID, and iOS Development Certificate that allows you to install your application on your device."

This is really nice. Pulling it all together. Now, I just need to give a name.

"Enter a common name or description for your Provisioning Profile using alphanumeric characters. The description you specify will be used throughout the Provisioning Portal to identify this Provisioning Profile."

Let's call "JlptProfileForIphone". 

"Step 1: Download

Download the Provisioning Profile to your Mac."

Ok, it's in the download folder:

"Step 2: Install
Connect your device to your Mac and drag the downloaded Provisioning Profile into the ‘Organizer’ window within Xcode. This will automatically install the .mobileprovision file in the proper folder."

Ok - should I clean out the provision profile entries from project file first? I think I will. 

Ok - new error. Problem with linking to flurry analytics. Delete all references and the library - and successful build!

Let's see if it runs on the device....

Took a couple of tries, but yes - finally the app on the iPhone. But - the mp3s aren't sounding. On to the next problem. 









Saturday, January 19, 2013

Getting down with Provisioning Profiles

So, I'm going to give an another crack at getting my programming to run on the 4s. So, last Jan 1, I ending up getting tangled up in a web of developer certificates, provisioning profiles, team certificate requests, organizer displays showing the wrong name and the right device, and so forth and so on until I was thoroughly lost. I'm still lost, but have no choice but to try to hack my way out of this digital forest. Do other people have this kind of trouble?

 Oh, yeah, one thing I did do was download Xcode 4.5, which was the one thing I did figure out I needed. Let's bring that up and see what happens when I try to run the app. Ok, when I bring up the app, I get a much clearer message than last time (I think): "Provisioning profile 'JLPT Vocabulary Quiz Development Profile' has expired".

So, I guess the provisioning profile is stored on my macbook, say on the keychain, or with the app, as opposed to on the device.The reason is that the phone is new, and therefore the provisioning profile couldn't be on my device.

 Ok, I went to organizer, and all the profiles related to my app were expired. I tried pressing the "renew" button for the profiles, but nothing. So, I'm just going to delete them. How could they have been on my iPhone anyway?

Ok, I just went to https://developer.apple.com/ios/manage/provisioningprofiles/index.action and deleted the profile there, but I still get the same error when I do a build on Xcode. What next? Wow. I think I might have screwed up with all my deleting. I saw an entry on SO that said you just have to right-click on your device in organizer and then just select "add device to profile". But - the profile is gone. I just deleted it. Rats.

So, now I think I have to recreate it.  Ok, in the provisioning portal, under provisioning, the developer tag, I selected "new profile'. I pasted the profile name in. For the app name, it gave me a list of app names to choose from. Three of them roughly match my app name, so I'm picking the one that looks most final (these are names I would've created before.

Wow. It's put the expired profile names that I deleted back in the list! Amazing. And the one I just tried to recreate now has a "pending" status. Let's refresh it. Active!

Ok, I think I need to download it now or something. Ok, when I download it, it hopped into the download folder, and I dragged to to the Xcode icon (btw, why don't they call it xCode? That spelling is so much more intuitive). Xcode automatically went to organizer after that, and now it says the profile is valid - let's try a build.

Nope. Not yet. Let's try the "add device to provisioning portal" again, since the profile was created with only the old iPod as the device.

Well, I tried doing the same thing with the other provision profile with my app name, and somehow the organizer was showing me the expired profiles again! (which I deleted).

Btw, I also modified the settings in Xcode so to add the profile name for signing on the app store, debug and whatever the other one is.

Ah, now at least I'm getting a different error message: "Provisioning profile '814FA14A-2A11-4447-BB5A-1CFE7AC042FC' can't be found" No idea why it's looking for that crazy string.

Ok, this SO entry looks *very* interesting (437 upvotes, never seen so many).

"Sometimes your xcode project file gets messed up, especially if you have an old project and first created it with an older version of xcode/iphone sdk. What you need to do is open up the project file in a text editor, search for the 'long string' from your error and manually erase that line. In fact, you should just go ahead and erase any line that points to any provisioning profiles. Then reopen the project in xcode, go to the settings and reselect your new profile. This clears up issues like that most of the time.

The lines that point to the provisioning profiles will look like this:
 PROVISIONING_PROFILE = "487F3EAC-05FB-4A2A-9EA0-31F1F35760EB"; "PROVISIONING_PROFILE[sdk=iphoneos*]" = "487F3EAC-05FB-4A2A-9EA0-31F1F35760EB";

also in the same thread:

"The .xcodeproj file is actually a directory, like an application bundle, If you right click it in finder, you can select show package contents, and then you will see several files inside (or in terminal just cd into it). The actual project file is the one in there with a .pbxproj extension. Once you open it with a text editor the lines you are looking for should start with 'PROVISIONING_PROFILE = or' '"PROVISIONING_PROFILE[sdk=iphoneos*]" ='. Delete all of those and then you should be good"

also:

"I found that, in addition to the above, I had to delete all of my profiles, re-download them from the provisioning portal, and reimport them into XCode. Then, in Build Settings / Code Signing, select the proper profile for all build configurations.

However, in Xcode 4.2 and later, there is a much easier way to access this text and select and delete it. In the Project Navigator on the left, select your project (the topmost line of the Project Navigator). Now simply choose View > Version Editor > Show Version Editor. This displays your project as text, and you can search for PROVISIONING and delete the troublesome line, right there in the editor pane of Xcode."

Phew. I think I'll tackle this tomorrow. Hopefully, I've finally gotten to the bottom of this tangled web of yarn.


Tuesday, January 1, 2013

iO6 6 needs a Xcode 5!

Well, I'm getting back into iPhone development *a little bit*. I've haven't been doing it for a while because of, well, other priorities, like locking down this new job I've got. But I did some development on the app a while back, and since then I've gotten an iPhone 4S (nice!). I strongly recommend for anyone Virgin Mobile's plan, which provides *unlimited data* for $30 bucks a month. The catch is you need to purchase the iPhone 4 or 4s model, with the 4s running at around $400 bucks as of late December.

Anyway, so my first obstacle is getting the program to run on the 4s. It appears (the device) on the organizer, but when I try to run the app, it gives me an error message: "Xcode cannot run using the selected device." "No provisioned iOS devices are available with a compatible iOS version. Connect an iOS device with a recent enough version of iOS to run your application or choose an iOS simulator as a destination".

Well, that's a surprisingly wordy yet somewhat helpful message. I suspect that it's only checking for previously provisioned devices, which at this point is my iPod touch, which I haven't updated for a while and therefore probably is running the old version of the iOS?

I'm not sure, but I think I need to provision the new device (4s) for development. Ah, actually, I missed this message on the Organaizer: "The version of iOS on “My Names’s iPod” does not match any of the versions of iOS supported for development with this installation of the iOS SDK. Please restore the device to a version of the OS listed below, or update to the latest version of the iOS SDK; which is available here."

Hmmm, I get conflicting advice from Google. I know there's a yellow dot next to the device name on Organizer - it should be green. Also, it's called "My Name's iPod Touch" which is bad since I'm connected to a 4s, yet its showing up, correctly, as an iPhone 4s as the device type.

Also, I'm pretty sure I never provisioned it for development or anything else yet.

So...what does it want? I'm thinking I need to provision this device, at least. If I right click on provisioning, and click help, I get a menu, which leads me to this:

Obtaining Certificates and Provisioning Profiles
 1. In the Devices organizer, select Provisioning Profiles in the Library section.
 2. Click Refresh.

What is a provisioning profile, exactly?
 "A provisioning profile is a collection of digital entities that uniquely ties developers and devices to an authorized iPhone Development Team and enables a device to be used for testing."

Great. Clear as mud.

"A Development Provisioning Profile must be installed on each device on which you wish to run your application code."

Well, whatever this frikkin' development provisioning profile is, it needs to be on the device. So I need to do this somehow.

"Each Development Provisioning Profile will contain a set of iPhone Development Certificates, Unique Device Identifiers and an App ID."

Brilliant. It needs an "iPhone Development Certificate" - another mysterious piece of digital gobbledy-gook which this russian doll of a process throws at us.

"Devices specified within the provisioning profile can be used for testing only by those individuals whose iPhone Development Certificates are included in the profile."

Ok, I will need a developer certificate - for inclusion in the developer provisioning profile - which must be installed on the device. Is there a PowerPoint that could make this clearer? With all their money, you think Apple could have better docs than this.

"A single device can contain multiple provisioning profiles."

Confusing. So, you have the profile. It has a collection of development certificates, device ids, and an app id. It's easer to think of the development certificates as "developer" certificates, since they are tied to individual.

Only one development provisioning profile per app, it looks like.

So for me, I just have my app, my developer/ment certificate, and my iPhone (I don't care about the iTouch just now).

Brilliant. more legalese from the help screen:

 "Obtain your code signing certificates and provisioning profiles to run apps in development on your development device."

Now I need a code signing certificate.  There seems to be some implicit assumption that I actually know what a code signing certificate is.  I'm assuming it is different than the developer certificate, I guess, and certainly different than the provisioning profile (which is for the developer/app/device combined, not just the developer).

"You must enter your development-team credentials so that Xcode can download the provisioning profiles containing your development certificate."

Umm...wait - I'm not on a development team. Is this something I need to contend with? And, where do I enter the credentials? Btw, what is a "development team" in this context and why do I need to know about it?

"If your development team does not have a development certificate for you, Xcode requests one."

Highly unlikely that would be the case, since I'm the only developer and have no idea who or what the "development team" is supposed to be.  Also, I resent some obscure scrap of data on some Apple server being referred as a "Development Team" as if it was some kind of, you know, actual flesh and blood entity.

"If your keychain does not contain your development certificate but your team has the certificate, Xcode downloads it from your team."

Again, the team. How does Xcode know which "team" to request it from, anyway?

"If your role in the development team is Member, inform the appropriate person in the team that there’s a pending certificate request."

Great. Now I'm supposed to know what my "role" is on this heretofore unknown "team". And what would this "appropriate person" do with this knowledge of my pending developer certificate request?


"If necessary, after the request is approved, follow the steps again to download your development certificate."

Some happy circumstance will have occurred where my cert is now created and available.

"If you are the team distributor, Xcode requests and downloads your team’s distribution certificate, in addition to downloading your development certificate."

A "team distribution certificate"? I can't take much more of this.

So, what is a certificate again? I think it's just a digital set of bits which can be encrypted by a public/private or private public key combination.

Appears to be a file with some info about the certificate's owner, and has the owner's public key. There's this whole thing about the certificate is signed by the CA (issuing authority) by creating a "hash" of the file using some kind of algorithm, e.g. MD5, then encrypting it using their private key.

Then, when your system receives the message, it checks if the certificate is from a a trusted issuer (which it keeps in a list) and if so, the system uses its public key (stored with the CA in the list) to decrypt the hash value (which means it came from them, if your system succeeds in the decrypt of the signature). Then, you run the decrypted signature (the contents of the cert) through the same hash algorithm, and it matches (the one that came with the message?), then you know it hasn't been tampered with. Whew.

So, I guess you get a certificate issued to you by Apple. A Developer certificate. Now, how does that help us get this app running? It's got to be connected the provisioning profile for your device and app, so your app can run.

So, that's what we're trying to accomplish.

From the dreaded "help" file:

"In the Devices organizer, select Provisioning Profiles in the Library section. Click Refresh."

Well, that option isn't there, but there's an intriguing one called "Add device to provisioning portal."

What might a provisioning portal be? Is this addition simply a way for apple to keep track of apps you make?

Anyway, let's see what happens.  Hmm... "No iOS Development Certificate Found" "No iOS development certificate was found. Would you like Xcode to request one for you?"

Well, I thought I had one, otherwise how could I have tested an app on my iPod touch? Or do they mean on my iPhone?

Well, I think I'm going to go ahead and let Xcode request it. It should already be in my keychain, but, I don't remember off the top of my head how to get at it. I'm just going to plunge ahead with this.

Xcode says "Submitting CSR", then "waiting csr approval". then "checking for pending csr". Now it says "No iOS Distribution Certificate Found" and "would you like Xcode to request one on your behalf?" Well, I mean, I had one of those too, but let's go with it. Xcode (again) says "Submitting CSR", and I missed the rest, but now it says: "Export Developer Profile?"

"Xcode added a signing certificate to your keychain. To ensure you can export code signing on other macs, you can export a developer profile that contains a backup of all your certificates and profiles. Would you like to export your developer profile now?"

Well, I don't have another Mac, but my wife and daughter each have one. Anyway, "Export" is the default, so let's hop on that train.

"Save as: DeveloperProfileExport and give a password. Hmm...well, now I have a valid "iOS Team Provisioning Profile" which shows up in my devices list, but IIRC, I had to create a profile specifically for this app."

Let's try to run the app.

Nope. Same problem.

Well, I selected a base sdk, and now my .app is showing up as red in the product folder. One wasn't selected at all before that. I think that this is maybe an issue with the SDK as the original message stated.

\Duh. I should've seen this earlier. It's right there in organizer, after the "develop" prompt:

 OS Installed on My Name's i whatever: 6.0.1 (10A523)
 Xcode Supported iOS Versions Latest 5.1 (9B176)

 Clearly, I need to download the latest xCode, from here (according the original message): https://developer.apple.com/membercenter/index.action.

Unhelpfully, just the generic developer's menu. This confirms I need to got 4.5: To develop for iOS 6 you need xcode 4.5. Xcode 4.4.1 supports only 5.1 iOS version (Stack Overflow). Wow. Huge down, 1.8 Gig. That's a wrap for today.