Showing posts with label iphone. Show all posts
Showing posts with label iphone. Show all posts

Thursday, October 13, 2011

How to Update iPhone3GS to iOS5

Updating iPhone 3GS to iOS5 was not an easy thing to do:
  • Removed 6GB+ stuff from the device: apps, videos, books, music
  • Cleared 20GB free disk space at MacBook Pro
  • Installed all Mac OS updates released AFTER iTunes update
  • Reboot
  • Try to update for umpteenth time
That took about 3 hours on late Wednesday night and 2 hours on early Thursday morning with 5 hours sleep in between.

Pro tip: make sure you don't have any wake up alarms setup to tricker during update! It's e-x-t-r-e-m-e-l-y annoying to listen to the alarm, while not being able to shut it down. I had to skip Apple ID phase just to SHUT-THE-FC*K-UP clock alarm. Don't really care what did I screw up.

It was either that or introducing iPhone to my fine-tune hammer. Very close call (after all those hours wasted to fail with update).

Friday, May 27, 2011

Three Applications to Be Released

There are still some minor open issues, like icons, colors, title and writing webpages. Otherwise everything is just fine :) Well, besides releasing the apps, I mean. But that day is getting closer.

"Time" which shows current time and that's pretty much it. Lean, clean and simple on purpose, but I fear it might be too simple for Apple. Might have to add something to get approved, unfortunately.

"Font" application, since I just love fonts. There must be 50 fonts applications in App Store already, but wanted to do my own. Looks good, got some nice features and I have a list of things to add.

"Log" application to display in-device NSLog output. Needed this kind of application in "real work", but couldn't find any with requires features. The first release will be simple on purpose, need some feedback to decide what to add in next version. Too many choises to be made based only on single person's (me) feedback.

Thursday, March 10, 2011

New font with iOS 4.3

iOS 4.3 was released yesterday evening. Checked the built-in fonts right away and found out that none of the old ones are missing - and that there's a brand new font in both iPhone and iPad: Noteworthy.

Pre-release rumours said it was added for iPad Notes application, replacing Chalkboard SE. Looking at Notes in iOS 4.3 both iPhone and iPad are using Noteworthy.

Wednesday, March 2, 2011

What to Do When Screen Auto-Lock Doesn't Work During Phonecall

Lesson 1: When iPhone is in headset mode, screensaver doesn't activate and/or screen doesn't go black. So unplug your headphones from the headphones socket... but remember this only effects proximity sensor.

Lesson 2: When you are debugging on hardware, the device is connected with USB cable to laptop. This cable does charging and thus screen won't go black. Unplug the USB cable, too. Now start recalling how debugging on hardware was done before cable connection was invented. Tip: log files!

Lesson 3: Something I've learned much earlier, still good to remember. If you're debugging something audio related (like I was), check ALL volume controls. There's a possibility that something has been muted!

Friday, January 28, 2011

Sunday, January 16, 2011

Comparing iPhone and iPad Simulator Fonts

After I checked new Fonts in iPhone 4.2.1 it was just a question of time until I would start wondering iPhone vs iPad fonts.

Here's a quick and small chart about iPhone & iPad fonts in simulator. Would do comparison between real devices, but don't have enough of those. Does anyone ever :)

Tuesday, December 21, 2010

Localization Tips

Experimenting with Localization, wondering why doesn't it work like in books? Me, too!

You should have one folder per language, e.g. "en.lproj" for English and "fi.lproj" for Finnish. This folder should contain one language specific file, which contains localized text strings:
"myString1" = "Hello, World!";
...which you use in code:
NSLocalizedString(@"myString1", nil)

Wednesday, December 8, 2010

GDB: Program received signal: "EXC_BAD_ACCESS"

When your program crashes (not if, but when) with an error message...
GDB: Program received signal: "EXC_BAD_ACCESS"
...you know that there is most likely a memory leak somewhere. Your code just tried to access something, which was supposed to be there, which used to be there, which is going to be there, which should have been there - but right now is missing.

Sunday, November 28, 2010

Fonts in iPhone 4.2.1

I've always been intertested in "fonts", so one of the first things to do after installing iPhone 4.2.1 was to checked available fonts. Don't know about others, but I'm pretty sure Apple Color Emoji wasn't in previous iOS version! Now I'm wondering about the others...

Thursday, November 11, 2010

How to Undo Past Last Point

This is one of those things you do only once, thus easily forgotten. Did it for "my" machine, but now I'm a contractor using customer machine.

So how do I get rid of this annoying warning note, when I want to undo after saving a file:
You are about to undo past the last point this file was saved. Do you want to do this?
Open Terminal window and type:
defaults write com.apple.Xcode XCShowUndoPastSaveWarning NO
Restart Xcode and you're fine. Until next machine.

How to Define UITableViewCell reuseIdentifier for loadNibNamed

When you create UITableViewCells, it's important to use reuseIdentified. This lets iOS recycle your table cells, thus improving performance and minimizing memory use. Using it is pretty simple:

static NSString *idCell = @"MyCellId";
cell = (UITableViewCell *)[aTableView dequeueReusableCellWithIdentifier:idCell];
Try to reuse an already existing, but not currently used, cell created earlier with given identifier "MyCellId". If such isn't found, create a new one:
if (cell == nil)
{
    static NSString *nibcell = @"MyCell";
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:nibCell owner:self options:nil];
    cell = (UITableViewCell *)[nib objectAtIndex:0];
}
This code requires a separate stand-alone XIB, which contains nothing but your UITableViewCell. But how do you define the reuseIdenfier? That property is read-only and created when table cell is created.
reuseIdentifier
A string used to identify a cell that is reusable. (read-only)
@property(nonatomic, readonly, copy) NSString *reuseIdentifier
Open your XIB in Interface Builder, select UITableViewCell object, open "Table View Cell Attributes" (press command-1) and write your hardcoded magical string "MyCellId" into "Identifier" field. Use the same string in your code as reuseIdentifier.

Warning: you should NEVER access objects inside XIB (NIB) by magical index into array! Apple might change "something" in next Xcode release and thus break your code. You should use IBOutlets. You have been warned.

...yes, this is one of those sad "don't do as I do, but as I tell you to" cases...

Thursday, October 28, 2010

EGOTableViewPullRefresh for multiple UITableViews

Wanted to add a "Pull To Refresh" feature similar to Tweetie2, so i looked around to see if there was any reusable code (screenshot from Zattr).

Cocoanetics (ex-Dr. Touch) has a good article explaining"pull to refresh" internal workings, well worth investing the time and effort to read. Recommended! However he's solution was not reusable for me, since I don't have UITableViewController. Fortunately he referenced Enormego's solution using UITableViews, including a walk-through with changes.

Monday, October 11, 2010

How to Find Out Width of Truncated UILabel Text

Found out my tip "How to Float an Icon after UILabel" worked only in positive scenarios. If your text string is longer than UILabel width, icon could have been pushed out of sight. In worst case nobody would ever have seen the icon!
// Title
label = (UILabel *)[cell viewWithTag:1];
label.text = @"This is a very long title which is too long";

// Icon
image = (UIImageView *)[cell viewWithTag:10];
image.image = [UIImage imageNamed:@"logo.png"];
Some measurements of different methods, just to check what is available:
CGSize frame1 = label.frame;
// 205x21
CGSize frame2 = [label sizeThatFits:label.frame.size];
// 291x19
CGSize frame3 = [label.text sizeWithFont:label.font constrainedToSize:label.frame.size];
// 163x19
CGSize frame4 = [label.text sizeWithFont:label.font constrainedToSize:label.frame.size lineBreakMode:label.lineBreakMode];
// 203x19
CGSize frame5 = [label.text sizeWithFont:label.font forWidth:label.frame.size.width lineBreakMode:label.lineBreakMode];
// 203x19
Next icon positioning. Here you should have calculations to compensate for different icon sizes (in case all of your icons are not same size):
// Icon positioning
CGSize frame = image.frame;
frame.origin.x = label.frame.origin.x + frame5.width + 4;
image.frame = frame;
Ok, now that's perfect (until next defect report)!

Thursday, October 7, 2010

How to Get Rid of Keyboard with a Tap on Background part2

There was a nice way to remove keyboard by using UITextView, but that has stopped working with iOS4. At least I got such a defect report for beta application. This time I will remove keyboard using UIButton, let's see how long that will work:
- (IBAction)removeKeyboard
{
    [textField1 resignFirstResponder];
    [textField2 resignFirstResponder];
}
Open your view in Interface Builder, create new custom full screen UIButton to cover everything, select UITextFields and UIButtons (etc.) one by one and "Send to Front" via Layout menu. Connect UIButton "Touch Up Inside" to your callback and that's it.

Nice, easy, simple, fast - what more can you ask for!

Wednesday, October 6, 2010

How to Float an Icon after UILabel

Want to place a floating icon right after a variable lenght text string - using Interface Builder? Wonderful helper that IB tool or so I thought...

First create a UITableViewCell template with IB, put there a fixed lenght UILabel followed by a UIImageView. No problems, their values are easy to setup at cellForRowAtIndexPath with view tag id numbers:
UILabel *label = nil;
UIImageView *image = nil;
CGRect frame;

// Title
label = (UILabel *)[cell viewWithTag:1];
label.text = @"Title text";
But how to "float" that image right after text string? UILabel is fixed sized, so that won't help. Have to check the size of label.text instead:
// Icon
image = (UIImageView *)[cell viewWithTag:10];
image.image = [UIImage imageNamed:@"logo.png"];

// Icon positioning
frame = image.frame;
CGSize f = [label sizeThatFits:label.frame.size];
frame.origin.x = label.frame.origin.x + f.width + 4;
image.frame = frame;
That's it, very simple! Just beware that your tag numbers MUST be unique.

I had a problem that Interface Builder wanted to set UITableViewCell tag same as my image tag. No errors, no warnings, no indications of problem - except that I couldn't get my image frame no matter how much I banged head into brickwall! Removing tag didn't help, it just automagically came back. Ouch!

Tuesday, October 5, 2010

How to Disable UITabBarItems but Only Temporarily

User is allowed to use only one UITabBar item, until he has done something e.g. made a selection on list. Other tabs are available after that. Access to tabs can be blocked again e.g. if user chooses to delete current "entry".

Tab access control is done in AppDelegate, since it owns UITabBarController and UITabBarItems. Just set up delegate handling - and that's the key: either there is a delegate to block tabs or there is none for free access:
@interface MyAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate>
{
   UITabBarController *tabBarController;
}
...
- (BOOL)tabBarController:(UITabBarController *)aTabBarController
shouldSelectViewController:(UIViewController *)viewController
{
  if (
    ([aTabBarController.viewControllers objectAtIndex:1] == viewController) ||
    ([aTabBarController.viewControllers objectAtIndex:2] == viewController)
  )
  {
    // Disable switch to tab 1 and 2
    // Check: otherViewController to enable
    // Check: SomeViewObject to disable
    return NO;
  }
  else
  {
    // Tab ok at index 0
    return YES;
  }
}
Access control can be enabled in any other class/file:
- (void)blockTabAccess
{
  MyAppDelegate *app = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
  app.tabBarController.delegate = app;
  [app SwitchToTab:kTabFirst];
}
Access control can be disabled in any other class/file:
- (void)releaseTabAccess
{
  MyAppDelegate *app = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
  app.tabBarController.delegate = nil;
  [app SwitchToTab:kTabSecond];
}
Some consider it poor design to access AppDelegate directly from "anywhere" and further more to use it to control application state. My defense are the classic a) it's easy b) it's fast c) it works and d) sometimes central control place is a good thing.

Btw this works only as long as you don't need UITabBarControllerDelegate for any other purpose. You have been warned.

Tuesday, September 28, 2010

Note about MKAnnotation Protocol implementation

Sometimes you just have to take things as they are given, just like that. For example adding MKAnnotation protocol support all you have to do is create an instance variable called "coordinate":
@interface MyPointItem : NSObject <MKAnnotation> {
    NSString *title;
    NSInteger distance;
    CLLocationCoordinate2D coordinate;
}
As Apple documentation says:
"An object that adopts this protocol must implement the coordinate property."
There you are. As long as you remember, WHY you have a variable called "coordinate" INSTEAD OF "location". If you don't remember and apply Natural Naming to your code, your application will start crashing horribly for mysterious reasons...

Friday, September 3, 2010

How to Create Human-readable Geo Coordinate Strings

How to create human-readable coordinate strings, a code snippet that I wrote long time ago. Released here as a reminder for The Next Time (there's always a next time):
CLLocationCoordinate2D loc = mapView.userLocation.coordinate;

BOOL loc_NS;
if (loc.latitude > 0)
{
    loc_NS = YES;
}
else
{
    loc_NS = NO;
    loc.latitude *= -1;
}

int lat_d = floor(loc.latitude);
loc.latitude -= lat_d;
loc.latitude *= 60;
int lat_m = floor(loc.latitude);
loc.latitude -= lat_m;
loc.latitude *= 60;
int lat_s = floor(loc.latitude);

BOOL loc_WE;
if (loc.longitude > 0)
{
    loc_WE = NO;
}
else
{
    loc_WE = YES;
    loc.longitude *= -1;
}

int lon_d = floor(loc.longitude);
loc.longitude -= lon_d;
loc.longitude *= 60;
int lon_m = floor(loc.longitude);
loc.longitude -= lon_m;
loc.longitude *= 60;
int lon_s = floor(loc.longitude);

location.text = [NSString stringWithFormat:@"Location: %d°%d′%d″%@ %d°%d′%d″%@",
    lat_d, lat_m, lat_s, loc_NS ? @"N" : @"S",
    lon_d, lon_m, lon_s, loc_WE ? @"W" : @"E"];
Based on Wikipedia article about Geographic coordinate conversion.

Thursday, July 22, 2010

How to Solve Ad Hoc release "value not permitted by a provisioning profile"

Ever since I submitted an application to App Store I've had lots of problems creating Ad Hoc release. Though first fix was simple, it's not a complete solution.

Error messages are:

Thu Jul 22 11:46:34 jouni-iDevice installd[643] : entitlement 'keychain-access-groups' has value not permitted by a provisioning profile

Thu Jul 22 11:46:34 jouni-iDevice installd[643] : entitlement 'application-identifier' has value not permitted by a provisioning profile
...
Thu Jul 22 11:47:06 jouni-iDevice SpringBoard[28] : Application 'Zattr' exited abnormally with signal 11: Segmentation fault

This time the solution was found in TUAW article "devsugar: A better way to share ad-hoc builds".

Summary: instead of normal Build use Build and Archive, find your application, find the last date, press Share Application button and - The Critical Phase - verify your identity is your Ad Hoc Distribution Provisioning Profile. Save locally and install e.g. via iPhone Configuration Utility.

...suspect Ad Hoc release problem is caused by having two different provisioning profile files using same application id. I generate three applications (development, release test, public) from same sources with some compile time flags and different provisioning profiles and app ids. Guess code signing identities got mixed.

Thursday, July 15, 2010

How to Accept Self-Signed Server Certificate

We have public server, test server and release test server. Likewise I generate three different binaries, each connecting to different server. The problem is that test servers have self-signed certificates and iPhone fails by default in NSURLConnection sendSynchronousRequest. The error note is:

ERROR CODE -1202 = The certificate for this server is invalid. You might be connecting to a server that is pretending to be “xx.xx.xxx.xxx” which could put your confidential information at risk.
The solution with iOS4 is this one line:
#if (defined(TEST_VERSION) || defined(RELEASE_TEST_VERSION))
    [NSURLRequest setAllowsAnyHTTPSCertificate:YES
                                       forHost:[url host]];
#endif
    [NSURLConnection sendSynchronousRequest:request 
                          returningResponse:&response
                                      error:&error];
Please note that the specific line is undocumented class method and thus not used in official release, only for testing with simulator or ad hoc releases.

To remove compiler warning add this at the beginning of your file:
#if (defined(TEST_VERSION) || defined(RELEASE_TEST_VERSION))
@interface NSURLRequest (DummyInterface)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host;
+ (void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString*)host;
@end
#endif
More info at Dr. Touch article: Ignoring Certificate Errors on NSUrlRequest.

iOS5 update: this code might (or maybe not) help a little from my blog article Server API change from HTTP to HTTPS