Thursday, November 1, 2012

ios 6 -- Access Address Book (Contacts)


In iOS 6, we need to get the permission to access user's contacts.(in ios 5 or below, it is no need to ask for permission).


Here is the code to access contacts works both iOS 6 and iOS 5 or below:



-(void)getAddressBookPermission
{
    
    if (ABAddressBookRequestAccessWithCompletion) { // if in iOS 6
  
    // Request authorization to Address Book
    ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);
    
    if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
        ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) {
            // First time access has been granted, add the contact
        });
    }
    else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
        // The user has previously given access, add the contact
    }
     else {
        // The user has previously denied access
        // Send an alert telling user to change privacy setting in settings app
    }
    }
    else{ // if not in iOS 6
     // just get the contacts directly
    }
}


This is the very useful tips for testing the Contacts pop up in iOS 6. 

Generally, the VERY FIRST time your app runs is the only time the ABAuthorizationStatus iskABAuthorizationStatusNotDetermined.  Then and only then will ABAddressBookRequestAccessWithCompletion() display the authorization prompt to the user.  Also, while in this state, ABAddressBookCreateWithOptions() DOES return a non-NULL ABAddressBookRef.  So there's no use in calling ABAddressBookRequestAccessWithCompletion() unless you're in this state.

If the state is kABAuthorizationStatusDenied or kABAuthorizationStatusRestricted, the only thing to do is let the user know that your app can't get access to the contacts, and if he/she WANTS your app to have access, he/she must go to Settings->Privacy->Contacts and OK the app.  (Initially, I thought I could, in this case, useABAddressBookRequestAccessWithCompletion() to ask the user for permission.  It would have been a lot more convenient for him/her.)

For testing purposes, there IS a way to get back to kABAuthorizationStatusNotDetermined.  You go to Settings->General->Reset and reset Contacts&Location.  This resets the contact and location permission settings for all apps.

Apple, if you're out there, the AddressBook docs SCREAM for more complete documentation!  This new permission stuff is quite unclear.  Even worse is any sort of docmentation about AB "sources".  A "source" is never even defined.  I figured them out but at great time-expense.  For example, nowhere is it stated that if you have multiple sources with the same contact, you'll get both contact records separately.  (One COULD assume that the system would take care of syncing contacts from multiple sources, but no.)  It's up the contact-displaying app to merge these contacts in a coherent UI.  It wouldn't so bad that this is a LOT of work if only it were documented somewhere. 

Wednesday, October 24, 2012

Performance Testing for Mobile Apps – Is Your App Ready for the Worst?

Here is artical for Mobile Apps testing

http://blog.infostretch.com/performance-testing-for-mobile-apps-a-new-game-indeed




There are some tools in the market that can help you with the performance/load, and stress testing conundrum in the mobile and web based apps space.
  1. Recent announcement by MicroFocus about SilkPerformer 9.0 (2012)  supports Mobile Web & Native apps testing on iOS, Android & BB platforms
  2. HP LoadRunner supports mobile web & native apps testing on iOS, Android, BB & WM platforms
  3. NeoLoad supports mobile web & native mobile apps
  4. JMeter supports mobile web app testing on simulators
  5. IBM Rational Performance Tester (RPT) supports mobile web app testing as well

Sunday, October 14, 2012

iOS -- CoreData data migration

Coredata provides a lightweight auto data migration method for the following conditions:

1. Simply add a new column.
2. Change a column to optional.
3. Change a optional column to compulsory, but have default value.

Step 1:
Create a new data version


1. Editor -> Add Model Version (expand your xcdatamodeld item) , type a name

2. Client on the xxxx.xcdatamodeld file and in the attribute page, set the current version



Step 2:

1. In App delegate , in method "persistentStoreCoordinator" change as follow:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (__persistentStoreCoordinator != nil) {
return __persistentStoreCoordinator;
}

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"WorkXP.sqlite"];

NSError *error = nil;
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

// handle db upgrade
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
// Handle error


return __persistentStoreCoordinator;
}


After that, for a lightweight data migration, user don't need to remove the old version app before they install the new one.



Monday, October 1, 2012

25 iOS design resources


Here is the link for 25 iOS design resources:

http://blog.jobbole.com/26093/



Sunday, September 30, 2012

Objective C InsertionSort


-(NSMutableArray*)InsertionSort:(NSMutableArray*)array
{
    for(int j=1;j< [array count];j++)
    {
        id key = [array objectAtIndex:j];
            int i =j-1;
     
       while (i>-1 && [array objectAtIndex:i] > key) {
                [array replaceObjectAtIndex:i+1 withObject:[array objectAtIndex:i]];
                i=i-1;
            }
        [array replaceObjectAtIndex:i+1 withObject:key];
    }
    return  array;
}

Wednesday, September 5, 2012

SQL tips and articles


Recently I found 2 useful SQL functions and would like to share with you.
This function is quite useful for a DBA.
For example:
DECLARE @Object varchar(100)
SELECT @Object = 'Mem.dbo.Member'
SELECT
      PARSENAME (@Object ,3),
      PARSENAME (@Object ,2), 
      PARSENAME (@Object ,1)

You could also apply the same concept to e.g. split IP format
For example: instead of using complex charindex
DECLARE @IP char(15)

SELECT @IP = '192.168.3.11'

SELECT
      PARSENAME (@IP ,4),
      PARSENAME (@IP ,3), 
      PARSENAME (@IP ,2),
      PARSENAME (@IP ,1)   

What it does is returning the first non-null argument. It is equivalent to CASE
CASE
WHEN (expression1 IS NOT NULL) THEN expression1
WHEN (expression2 IS NOT NULL) THEN expression2
...
ELSE expression
END


Sunday, August 26, 2012

Hosting WCF in IIS

Here is the config code for web.config for hosting WCF in IIS6, windows server 2003




Key:

1. Config endpoint behaviors, using webHttp

2. binding use webHttpBinding