Showing posts with label iOS. Show all posts
Showing posts with label iOS. Show all posts

Sunday, July 2, 2017

iOS 11 beta 1,2 - NSString sizeWithAttributes - breaking change and potential bug

Edge behavior of [NSString sizeWithAttributes] seems to be changed in iOS 11 beta 1 and 2. When asked for the


float size around 0.0;
    
    NSString *testString = @"Some test string";
    NSString *fontName = @".SFUIText-Semibold";
    
    UIFont *targetFont = [UIFont fontWithName:fontName size:size];
    
    CGSize stringUISize = [testString sizeWithAttributes:@
                           {
                           NSFontAttributeName: targetFont
                           }];

You may get very different from iOS 7- 10 values. Here is the test:



While running it on iOS 7-10, everything converges to zero string UI width:

2017-07-02 10:11:45.996 speedometer[23301:7084973] attempted font size: 1, calculated string width: 12.157471, delta: -12
2017-07-02 10:11:45.997 speedometer[23301:7084973] attempted font size: 0, calculated string width: 4.052490, delta: -4

2017-07-02 10:11:46.005 speedometer[23301:7084973] attempted font size: 0, calculated string width: 0.000000, delta: 0

 while on iOS 11 beta 1 and 2 the same test case is "stuck" on value 97 something on iPhone 6 Plus:

2017-07-02 08:29:07.157511+0200 speedometer[36517:257340] attempted font size: 4, calculated string size: 36.437256, delta: -36
2017-07-02 08:29:07.158646+0200 speedometer[36517:257340] attempted font size: 3, calculated string size: 28.340088, delta: -28
2017-07-02 08:29:07.159723+0200 speedometer[36517:257340] attempted font size: 2, calculated string size: 20.242920, delta: -20
2017-07-02 08:29:07.160738+0200 speedometer[36517:257340] attempted font size: 1, calculated string size: 12.145752, delta: -12
2017-07-02 08:29:07.161953+0200 speedometer[36517:257340] attempted font size: 0, calculated string size: 4.048584, delta: -4
2017-07-02 08:29:07.166740+0200 speedometer[36517:257340] attempted font size: 0, calculated string size: 97.166016, delta: -97
2017-07-02 08:29:07.167756+0200 speedometer[36517:257340] attempted font size: -1, calculated string size: 97.166016, delta: -97

2017-07-02 08:29:07.168736+0200 speedometer[36517:257340] attempted font size: -2, calculated string size: 97.166016, delta: -97

Looks to me as a broken "contract" and invariant. One would really expect the consistent behavior as it was since iOS7 and having the width of the string calculated as zero for zero font size and zero it should be downwards? Also string width jumping from about approaching zero values to 97.166016 when value got a bit on below zero looks inconsistent. Probably a missing unit test :)!

For me it looks like a bug and I'm reporting it to Apple now. Hopefully it will be fixed to the same consistent behavior as it used to be on iOS 7 - 10.

Defensive coding is like an alloc/release for me, I try to make it right and upfront, but doing static analysis later I found myself being "mentally away" way too often.

Yours and wishing you happy coding!
Stan.

Tuesday, April 11, 2017

UINavigationController - ask for confirmation on Back

Didn't expect this to be such a problem, but once you tap into the UINavigationController things become hairy.

Requirement:

When user leaves a screen by tapping on a "back" in navigation bar and there are changed data in the screen I should ask for a confirmation and keep user at the current UIViewController if she decided to continue editing the data.

Solution.

You may run into this: http://stackoverflow.com/questions/1214965/setting-action-for-back-button-in-navigation-controller/19132881#19132881 (particularly this: https://github.com/onegray/UIViewController-BackButtonHandler).

Once, I was trying to solve the keyboard accessory to be shown each time for each UITextField on shouldBeginEditing by writing a category for a UITextField. And here is something I learned in a hard way:

When you plan or see any category re-writing the existing framework method, STOP! Simple as this and go read on what can turn wrong with this.

The solution mentioned above use this:

1
2
3
4
5
@implementation UINavigationController (ShouldPopOnBackButton)

- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {

 if([self.viewControllers count] < [navigationBar.items count]) {

No go for me, no need to study, excuse for being abrupt :). But one part of code from this solution turned actually to be useful.

One of the comments on another post: http://stackoverflow.com/questions/20327165/popviewcontroller-strange-behaviour got me here: http://blog.macca.tech/2013/11/ios-prevent-back-button-navigating-to.html

And was not I lucky? It really makes sense, no private APIs, framework's UIViewController gets the chance to do its stuff always. What I wanted to improve though was that "safeDelegate" property and the way it is established. So I added a new method (into UISafeNavigationController.m):


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
-(id<UISafeNavigationDelegate>) popDelegate
{
    UIViewController *topController = [self topViewController];
    
    if ([topController conformsToProtocol:@protocol(UISafeNavigationDelegate)]) {
        return (id<UISafeNavigationDelegate>)topController;
    }
    
    return nil;
}

And then you can just substitute safeDelegate with popDelegate:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
{
    if (self.popDelegate && ![self.popDelegate navigationController:self
                                             shouldPopViewController:[self.viewControllers lastObject]
                                                                 pop:^{ [super popViewControllerAnimated:animated]; }])
    {
        if (self.navigationBar) {
            [self restoreViewsForNavigationBar:self.navigationBar];
        }
        return nil;
    }
    
    return [super popViewControllerAnimated:animated];
}

Also note lines 7-9 where I call a new method (borrowed from the first stackoverflow solution that I actually criticize :)):


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
-(void) restoreViewsForNavigationBar: (UINavigationBar *) navigationBar
{
    for(UIView *subview in [navigationBar subviews]) {
        if(0. < subview.alpha && subview.alpha < 1.) {
            [UIView animateWithDuration:.25 animations:^{
                subview.alpha = 1.;
            }];
        }
    }
}

This is to avoid the back arrow in the navigation bar looking as disabled when answer from our controller to the shouldPop is NO.

Then protocol method in the related view controller may look like:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
- (BOOL)navigationController:(UINavigationController *)navigationController
     shouldPopViewController:(UIViewController *)controller pop:(void(^)())pop
{
    if (!_item.id) {
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:LSSTRING(@"Save the item?") message:LSSTRING(@"You are closing this screen by using Back button and have not saved the item.") preferredStyle:UIAlertControllerStyleAlert];
        
        [alert addAction:[UIAlertAction actionWithTitle:LSSTRING(@"Save and close") style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
            [self done:nil];
        }]];
        
        [alert addAction:[UIAlertAction actionWithTitle:LSSTRING(@"Don't save and close") style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
            [self doCancellationCleanup];
            if (pop) {
                pop();
            }
            
        }]];
        
        [alert addAction:[UIAlertAction actionWithTitle:LSSTRING(@"Cancel") style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
            
            
        }]];
        
        [alert show];
        return false;
    }
    
    return true;
}

Hope this can help someone! All the credit goes to Hong Kong Web Entrepreneur guy! Once again, here: http://blog.macca.tech/2013/11/ios-prevent-back-button-navigating-to.html

[UPDATE] In the end I had to rework the final part presented here - showing the confirmation as the way it is presented was not releasing the controller correctly and was not cleaning up the views as well. Quite bigger effort is required to get it right and it is not that generic in the end. But this is a good start! :).

Thursday, March 30, 2017

xcode 8.3 CompileStoryboard Internal error. UICGColor encodeWithCoder. Please file a bug at bugreport.apple.com and attach ...

Was dancing with my voodoo drum for a few minutes after upgrading to xcode 8.3 today. One of my storyboards that have existed for last 3 years suddenly started to cause the compile error:

CompileStoryboard bLocNote/taxi/EditTariffStoryboard.storyboard
2017-03-30 17:48:00.332 Interface Builder Cocoa Touch Tool[29650:5173036] *** Assertion failure in -[UICGColor encodeWithCoder:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3600.7.47/UIColor.m:1549
2017-03-30 17:48:08.466 ibtoold[29647:5172916] [MT] IBPlatformTool: Wrote failed marshalling request diagnostics to path: /var/folders/8j/x30frbx948l8djrb6ff7mljc0000gn/T/IB-agent-diagnostics_2017-03-30_17-48-08_415000
/* com.apple.ibtool.errors */
/Users/stanislavdvoychenko/Documents/code/speedo/bLocNote/taxi/EditTariffStoryboard.storyboard: error: Internal error. Please file a bug at bugreport.apple.com and attach "/var/folders/8j/x30frbx948l8djrb6ff7mljc0000gn/T/IB-agent-diagnostics_2017-03-30_17-48-08_415000". 

Was compiling fine just an hour ago on xcode 8.2.1! Ok, it tells something on not liking the UIColor, and log it mentions further says colors should be RGB or White space. I went by "binary search" removed everything from the storyboard except the table view -> build still fails. Only value catching the eye was "Tracking" color for the section view saying showing a black stripe with no color name, I have many of these assigned in other places though, guess it is still somehow different in this storyboard, so I reselected a "black" color for it:


And it compiled! Huraaay and back to programming!

Thursday, March 16, 2017

Inherited uiviewcontrollers references in one storyboard. This class is not key value coding-compliant for the key ...

I often inherit my UIViewControllers to add functionality on top of already existing. All works fine, but today I ran into the weird problem. Setup like this:



Where rangeItemEditor view controller inherits from itemEditor view controller. All outlets connected in the parent view controller. On row tap I do performSegue and then this:

This class is not key value coding-compliant for the key ...

Complaining about one of the outlets. After standard troubleshooting, checking that .destinationViewController is right, bunging my head a bit against the wall and trying [navigationController push] which worked I looked more carefully at the Storyboard ID values for these references. Here is obviously a good one:



And the other one, inherited rangeItemEditor had it empty. Filling it in and running again proved the idea that missing Storyboard ID in Identity tab for a references storyboard is a bad thing. I was not clearing this out though, not sure how it happened to be empty.

Thought I'd share to make your troubleshooting of similar cases faster!

In the end I got rid of these references in the storyboard and used [navigationController push]. Why? I just really don't want these crashes when xcode UI Editor decides to remove something behind the scenes. I've witnessed this "open the file -> get the mess" already in xcode storyboards and I really better stay safer here with using old gold manual push. Staying away from the magic until it has predictable results :).

Monday, February 20, 2017

Working around WITH not being available in older versions of sqlite.

For one of my iPhone apps I need to rename route points to match their order as they are inserted or deleted, I started with an easy WITH version:


[NSString stringWithFormat:@"WITH wcte (id, wname) AS (SELECT w.id, '%@ ' ||  (SELECT COUNT(*) + 1 FROM waypoint WHERE vY1 < w.vY1) as wname FROM waypoint w)  UPDATE waypoint SET \"name\" = (SELECT wname FROM wcte WHERE id = waypoint.id) WHERE \"name\" LIKE '%@ %%' OR \"name\" is null OR \"name\" = ''", LSSTRING(@"Point"), LSSTRING(@"Point")]

And ran into the problem when testing on iOS8.1, obviously its version of sqlite didn't support WITH at that time.

So here is the workaround solution for older sqlite versions:

[NSString stringWithFormat:@"UPDATE waypoint SET \"name\" = (SELECT '%@ ' || (SELECT COUNT(*) + 1 FROM waypoint w WHERE w.vY1 < w1.vY1) FROM waypoint w1 WHERE w1.id = waypoint.id) WHERE \"name\" LIKE '%@ %%' OR \"name\" is null OR \"name\" = ''", LSSTRING(@"Point"), LSSTRING(@"Point")]

Not that nicely looking, but I'm still committed to support iOS8 for a few more months. If you are puzzled by that LSSTRING part - that's just my macro for the LocalizableString as I only want to rename these points that are named automatically and surely I want to name them in the localized manner. Punto it is in Spanish (I hope) :). vY1 is a cryptic name for the order column :).

Would not be publishing at all, but sqlite syntax sometime is surprising in what it can or can't do, so I thought I might save time to someone.

If you are into hiking, fishing, cycling or classic skiing here is the app link, it's free: https://itunes.apple.com/us/app/id1120906807


Thursday, May 26, 2016

Symbolicating bitcode crash logs in XCode

As of Xcode version 7.3 there is still a problem with symbolicating the bitcode crash logs. I've attempted several solutions, here and here, but here is what I came to:

1. Crash logs provided are for the dSYMs that Apple also provides. Just go to the iTunes connect and download them:



Once you have them right click on the crash in xcode -> "Show in finder" and copy to some target directory - that's actually a crashpoint file you are going to get.

My target directory is now ~\Desktop\crashes and here is how it looks:



Where #1 are dSYMs as copied from the iTunes connect. #2 is the crashpoint saved from the crash organizer window in xCode. #4 is a crash log extracted from the crashpoint file (right click and "show package contents")

To get #3 - a symbolicatecrash app, execute this in the target directory (xcode 7.3):


cp /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash symbolicatecrash

For different versions of xcode the location of symbolicatecrash will be different.

To get symbolicatecrash ready to operate execute:

export DEVELOPER_DIR='/Applications/Xcode.app/Contents/Developer'

Only one step is left! That's to get your crash log symbolicated:

./symbolicatecrash a.crash dSYMs/ > a.log

And the output file a.log is looking like:



Way better, is not it?

There are nuances that I would not touch here, like these dSYM files you downloaded are for different architectures and it would be the best to match your specific crash log to a corresponding dSYM. I'll leave this detail to you, my experience is that function names do match quite well, then it is just about the line of code information you'll be getting. In above picture, given crash and dSYM are matched well, you can see the line of code where the crash exactly happened. Otherwise you'd see +xyz there and that's not that helpful.

This is it. Please don't judge me strictly, I'm not an expert in any field, as I learnt over time :)! Knowing more than I do? Share your knowledge in the comments!

Yours,
Stan.

Thursday, April 14, 2016

xcode - Configure for analyzing. The scheme is not configured for analyzing.

I'm used to run analyzing cycle on my apps when moving closer to their public release. This time xcode (7.3 (7D175)) greeted me with:


"Edit the scheme to enable analyzing, or cancel the action." with that "Edit Scheme ..." was not opening anything and I didn't notice anything extra in the schema editor to enable analyzing.

I even created a clean new project to see if error would be present there as well, and it was.

So after scratching my head a bit I just set a RUN_CLANG_STATIC_ANALYZER as true for the target/build where I needed it:


This way I got the static analysis messages back.

Hope this can help someone!

Update. Or as Jaime Santana commented, just "launch Analysis from the menu option Menu -> Product -> Analyze". Thank you Jamie, that worked!

Friday, November 29, 2013

Apple MKMapView vs. Google iOS SDK map - CPU, compass image, center and rotate.

Why I didn't use native Apple's map a year ago when I was going through the options for my apps?

I was looking for the "live" map that would be able to follow your location, option to rotate so your heading can be always on top of the map and while it rotates it should rotate street names gracefully so they are not shown upside down.

Should I tell Apple maps for iOS6 failed miserably for all of those requirements. So I used Google's alternative. It gave me great rotation, street names handling and nothing to complain about.




Watching iOS7 location videos made me really intrigued, it looked like "oh, Apple fixed it all and brought us the map that can rotate correctly". I was really keen to try and after two months of fixing my apps for iOS7 and releasing them I finally got to try.... And I'm not sure this is it.

Why?

You basically have an option to either center the map yourself or set it up to track by itself:


[self.map setUserTrackingMode:[MKUserTrackingModeFollow|MKUserTrackingModeFollowWithHeading] animated:[true|false]

Well, there are few problems here. 

Rotate and center sync. If you want to rotate with one of the automated tracking options, you'd probably need to sync your rotation with the user location tracking animation. Otherwise, for my naive and short attempts the rotation and auto-tracking create weird effect of user location floating around its center. I didn't follow the path of trying to sync that yet and will see if this is worth an effort.

Compass image. Small extra annoying factor here is that once you rotate the map (set the map camera heading) to something not equal zero, the "compass" thingy appears in the right upper corner:



My first thought was - "oh, I'l move this thingy where I want or disable it for iPad version as I show heading elsewhere". Let me do a read up, let me google for it, let me study Apple's forum for it... What? I can't do it! I love Apple for things that were decided for us, it is part of their spirit and I'm glad they keep it even stronger now than before!

This compass thingy is not a big issue I can move my star button (that happened to be in this place by accident) - I'm not that picky.

It has glitches. From time to time it looks like map zoom is being reset for a moment and than re-established again. I can't really correlate it to whatever I'm doing (as I'm doing nothing but set camera's heading and I do for every location change while zoom "blink" only happens once in a longer while). And the first time I rotate it it goes through the field of black and white rectangular and then does it from time to time, probably when tiles has not been loaded yet for some area I suddenly need to expose by programmatic rotation. This never happens to the Google map.
+ When changing programmatically (or by setting the auto option with WithHeading) heading from 360 to 1, Apple's map rotates -360 + 1 degree. Like, this can't be true? I'm probably just silly. But Google does it right, and it makes me feel less silly and more desperate.
+ Compass image shows even when I have enableRotate to NO, but when phone points exactly to 0 heading, the compass image disappears. So when my user will drive exactly in North direction they know it by not seeing the image?! Very consistent!

I can center and rotate all by myself.

I'm a big boy, if I proved it with Google maps I can prove it everywhere?

Ok. I'm loosing that extra smooth animation for centering the map should I tell. But it just looks as it does for the Google maps, that would suffice. Seems to work just ok. So I was sitting and looking at that center and rotate I put together thinking "Stan, you are a genius, you proved it!".

As I tend to spend few minutes in this state, I felt how my lap is getting hotter, and hotter .... Oh oh, this is my beloved temperature based CPU profiling instrument! 

So here is the reason of why I'll be thinking twice now if I should use native Apple's map for the live map option, let me provide it here. On the top you'll see Apple's map consumption while centering and rotating and below it you'll see the same task executed by a Google map. If simulators doe this to my mac, I guess I can speculate the same CPU/battery consumption ratio will stay on real devices:


My story ends here, enough for this evening, I need to re-group, re-think, re-try, re-study ....








Sunday, September 29, 2013

iOS 7 vs iOS 6 memory consumption. OMG?

Known thing my app starts slower on iPhone 4 with iOS7 then it is on the same iPhone 4 with iOS6. This is pretty sad, but not the only sad thing...

As I'm profiling now the app before its soon to come release to AppStore, I got to the following screenshots for the fresh app start on iPhone 4 with iOS6:


Note the 1.55MB number. And now, the sad thing, same fresh start on iPhone5 with iOS7:


Noticed that 8.21MB?! I currently only have iOS7 installed on iPhone 5, so I can't compare iPhone 4 iOS7 vs iOS6 consumption, but I believe this iPhone 5/4 factor should not play any role here. It is just iOS thingy. 

While not that sad for iPhone 5/5s, it is pretty bad news for my users that are still on iPhone 4, apps are going to consume more. All apps, not only mine... App startup is becoming definitely heavier and those extra allocations in iOS7 are surely standing for more work done by iOS7 while starting the app.

Having read Steve's biography, it looks to me like a step away from the "saving lives" approach to plain MS's "throw more memory on it - problem solved".

May I be wrong? I hope!

Yours,
Stan.

Friday, August 24, 2012

AppStore fake reviews - more ...

Raw data for you, my reader. Why it is women's name fake reviews are mostly made from on the Apple AppStore? All those women that can't live without an iphone speedometer app in their car/motorbike?! Within a single day or two? Poor ladies!

Dear Apple, please help! Lets stop those Barbie apps and reviews?! And believe me, this exactly app is Galaxy III far from being accurate or fair! Dear Jessica Lovely, Stella Ried, Smith Erica and Angelina Sea, please just stop!!! HEEELP!


Sunday, March 11, 2012

Google Blogger Objective-C API. Integrating the lib.

Just a short note to recap the steps required.
The ultimate start is http://hoishing.wordpress.com/2011/08/23/gdata-objective-c-client-setup-in-xcode-4/ and http://stackoverflow.com/questions/8972875/ios-iphone-ipad-project-with-gdata-static-library-libgdatatouchstaticlib-a-f.

My only bit of info to add is that for blogger API you'll need to add also photo "service" (-DGDATA_INCLUDE_PHOTOS_SERVICE=1), otherwise you'll get stuck on something like: 'Use of undeclared identifier 'GDataMediaThumbnail'.


And the resulting size of the lib is 2.3MB, not that bad:


This is for iOS5, but note that I'm not using ARC on my project. You are welcome to take my app Here&Near for a spin to experience that soon coming integration.

P.S. If it screws then when archiving the project, read on here: http://stackoverflow.com/questions/5206536/archiving-project-in-xcode-incorrectly-creates-multi-application-bundle


Monday, November 21, 2011

iCloud – file backup with no UIDocument whistles. Part I.

I’m on a quest to add a backup feature to one of the iOS apps of mine (blocnote). App is only provided for iOS 5+ and my first option to use would be iCloud over Dropbox et al. I don’t want to use a UIDocument as well, as here it is only about simple file backup, no intent to keep this file in sync.

After reading what I could (as Apple docs on iCloud can’t really be taken as a good reference):

http://www.raywenderlich.com/6015/beginning-icloud-in-ios-5-tutorial-part-1
http://www.raywenderlich.com/6031/beginning-icloud-in-ios-5-tutorial-part-2
http://stackoverflow.com/questions/7795629/icloud-basics-and-code-sample

First stop would be to satisfy a requirement to create a single backup file from a sqlite db and put into the iCloud.

Providing some very raw bits of code here, only building proof of concept at this stage!

Checking for a iCloud availability:

+ (bool) isiCloudAvailable
{
    NSURL *ubiq = [[NSFileManager defaultManager] 
                   URLForUbiquityContainerIdentifier:nil];
    if (ubiq) {
        NSLog(@"iCloud access at %@", ubiq);
        return true;
    } else {
        NSLog(@"No iCloud access");
        return false;
    }
}

Getting db file copied inside the same documents directory:

NSString *bName = [NSString stringWithFormat:@"%@_%@%@",backupName,[Formatter dateToBackupNameString:[NSDate date]],@".db"];
    
    NSArray *searchPaths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentFolderPath = [searchPaths objectAtIndex: 0];
    
    NSString *backupPath = [documentFolderPath stringByAppendingPathComponent:bName];
    NSURL *backupUrl = [NSURL URLWithString:backupPath];
    
    NSError *copyError = nil;
    NSError *removeBckError = nil;
 
    if ([[NSFileManager defaultManager] fileExistsAtPath:backupPath]) {
        bool success = [[NSFileManager defaultManager] removeItemAtPath: backupPath error:&removeBckError];
        if (!success) {
            NSLog(@"Bck cleanup error: %@", [removeBckError localizedDescription]);
        }
    }
    BOOL copiedBackupDb = [[NSFileManager defaultManager] copyItemAtPath:dbFilePath toPath:backupPath error:&copyError];
    if (!copiedBackupDb)
    {
        NSLog(@"bck db copy error: %@", [copyError localizedDescription]);
        return NO;
    }

And moving a copy to iCloud:

    NSFileManager*  fm = [NSFileManager defaultManager];
    
    NSURL *ubiq = [[NSFileManager defaultManager] 
                   URLForUbiquityContainerIdentifier:nil];
    
    if (ubiq == nil) {
        return NO;
    }
    
    NSError *theError = nil;
    
    
    [fm setUbiquitous:true itemAtURL:backupUrl destinationURL:[[ubiq URLByAppendingPathComponent:@"Documents" isDirectory:true] URLByAppendingPathComponent:bName] error:&theError];
    
    if (theError != nil) {
        NSLog(@"iCloud error: %@", [theError localizedDescription]);
    }

Note that apple docs say you should not be using setUbiquitous on the main thread to avoid deadlocks. Plus there is no indication of progress is provided by this code yet to user. That will come…

Attention should be paid where exactly you move your file in iCloud. Without that destinationURL:[[ubiq URLByAppendingPathComponent:@"Documents" isDirectory:true] URLByAppendingPathComponent:bName] your file will end up in the common app documents&data container and user will have no ability to delete a separate backup file:

image

When put inside Documents in iCloud, files can be seen like:

image

And can be deleted by user out of iCloud nicely one by one.

This is it for today’s part, going for more exploration and will share as it goes.

Yours, Stan.

Sunday, August 28, 2011

On GPX files for Xcode 4.2

I totally enjoy the new location testing features of xcode 4.2. Ability to test with any fake location is really a blessing! Today I saw that the app is not working right in one of the locations (it works poorly in few of them, but I’m fixing intensively :)). That was South Brisbane, and my first chance to add a custom location.
After thinking for a while what would be the minimum data for a file required I actually found out that Xcode is capable of adding a minimalistic template for a start!:
image
That is what a file looks like:
<?xml version="1.0"?>
<gpx version="1.1" creator="Xcode"> 
    <wpt lat="49.930008" lon="15.369873">
         <name>South Brisbane, AU</name>
    </wpt>
</gpx>

Name the file nicely as its name is used when you pick it up:
image

To see how to add speed, accuracy, etc to your testing/simulation you may continue with: Use Automation to bring speed, accuracy, altutude, etc to your location app testing

Links:
GPX specification: http://www.topografix.com/gpx.asp
Google Maps 2 GPX: http://www.elsewhere.org/journal/gmaptogpx/

Tuesday, August 9, 2011

iPhone + Google App Engine + Plain Old Stan => Taxican. Part I.

I was lucky a week ago with Apple approving my first “reference” app to the app store. I thought I’d share the architecture and some specific design choices I applied for this app.

App itself serves for booking a taxi. There are quite few apps doing this on the app market, though I believe this one should expand on options beyond just simple google based directory.

Here goes a high level and quite simplified diagram:

image

Today, I only want to touch on API’s used and set a basis for future entries.

In order to find taxi companies when I don’t have a match in on-device db I used google local search api. I recommend to play with a playground page first: http://code.google.com/apis/ajax/playground/. Example of a sample request and response can be found here: http://code.google.com/p/toolsdotnet/wiki/GoogleApi.

Then for a situation when gps accuracy may be low, or you want taxi to pick you up at the bar where you are for example, I decided to integrate foursquare. So you can see the list of places “near” you and pick the right one as your pickup address. This API is named a “venues search” in Foursquare, and I aggregated some info I used here: http://code.google.com/p/toolsdotnet/wiki/Foursquare.

This is it for today. If you are curious, and reading this article fresh :), then app should be still free here: http://itunes.apple.com/app/taxican/id440230968?ls=1&mt=8, with supporting web site: http://www.taxican.com. Still work in progress, excuse the mess :)… If you like the thing, you can give it your facebook like on the web site, as …

, on the power of social media. Friend of mine told me today the customer didn’t consider his app/business worth consideration/solid because it didn’t have even 1k likes on a facebook! Ouuuch!

Saturday, July 30, 2011

iOS Universal App with “Twitter’s” stacked scrollview

For my next iOS project I want an effect that is akin to Twitter’s stacked scroll panels on iPad. It is not going to be exactly the same and should suit both iPad and iPhone screens.

First step was to find something to speed up the way to the Universal app. For myself I found the best starting point here: http://blog.corywiles.com/creating-a-universal-ios-app-tutorial. Make sure you don’t overlook a link to the git repo: https://github.com/kwylez/Universal-iOS-App-Template.

Then for the stacked scroll view a quick search led to the work of http://www.raweng.com/ team with repo here: https://github.com/Reefaq/StackScrollView.

Given all that, it was a no-brainer to put one and one together. Not going to repo this, so find all of the files required in this archive.

Just spread the files across the project as you wish and set the correct nib for iPhone and iPad in your project setting:



Huge credit to the guys mentioned above for making my life so much easier !