Sunday, September 28, 2014

Best resource to learn ios swift from Apple

With the release of xcode 6 and ios 8, swift is officially available for developers to create ios application. The following are some best resource from Apple to learn swift for ios programming:

Books:

Video

Friday, September 19, 2014

XCode 6 tips: storyboard zoom, ios 7 simulator, check id boolean type broken


1. In order to zoom xcode storyboard, right click on the storyboard window, and select the zoom percentage on the context menu. The shortcut key is too complex to remember.

2. As ios 7 and ios 7.1 are still used by many devices, so in addition to the ios 8 simulators installed with xcode 6, it is better to go to xcode preference->download menu to download the ios 7 and ios 7.1 simulator  for testing.

3. in ios 7,  the usual way to check whether an object is from boolean type is using
NSNumber * n = [NSNumber numberWithBool:YES]; 
if (strcmp([n objCType], @encode(BOOL)) == 0) {
    NSLog(@"this is a bool");
However the above way has broken in ios 8, the workaround is adding an additional check for the classname as below
 if (value != nil &&  [value isKindOfClass:[NSNumber class]] &&
        ( (strcmp([value objCType], @encode(BOOL)) == 0 ||

           (__bridge CFBooleanRef)value == kCFBooleanTrue || (__bridge CFBooleanRef)value == kCFBooleanFalse) ) ) {
    NSLog(@"this is a bool");

Thursday, September 18, 2014

NSUserDefault in xcode 6 ios simulator not deleted with application

After installing xcode 6, when deleting application from ios simulator, the data saved in NSUserDefault does not deleted with the application.

This is a bug in the xcode 6 simulator. To overcome this issue, either reset the simulator or call the below code in didFinishLaunchingWithOptions method

  NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
   [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
 

Tuesday, September 16, 2014

How to debug cordova javascript deviceready event

Debug cordova deviceready javascript event is not possible without making some change in cordova.js, as you cannot attach the desktop browser to the device uiwebview before the html file is loaded, but once it is loaded, the deviceready event is already fired and it is too late to attach the debugger.

In order to debug deviceready event, you can make a small change to do not call the deviceready event handler, until the debugger is attached. The following steps can be used to do so:

1.  In index.html's body element, add a button to manually fire mydeviceready event after the debugger is attached,    


<br><br><button onclick="document.dispatchEvent(new Event('mydeviceready'));">fire deviceready</button>

2. in Index.js and any other js files that listen on "deviceready" event,  change the event name from deviceready

document.addEventListener('deviceready', function 
to mydeviceready:
document.addEventListener('mydeviceready'

3. launch the app, and after attaching the desktop browser, click the "fire deviceready" button to debug device ready event handle.

It is also helpful to wrap cordova callbackFromNative function within setTimeout, so when debugging the cordova js callback, it will not hang in safari.

Sunday, September 14, 2014

how to copy and paste text from mac to ios and android

iOS simulator:

To copy text from mac to ios simulator, first select the text in mac, and then click "Command+c" to copy it.
Then on ios emulator, first click "Command+v", the string will not show up yet, you then need to select the text field and hold until the paste context menu is shown, select paste menu, the text will be pasted into the text field.



Android emulator:

The easiest way to copy text to android emulator is first selecting the text field in android emulator, and from mac terminal window, type the following command to send the string to the emulator


adb shell input text 'my text string to be copied to android emulator'

Sunday, September 7, 2014

How to add a child pane (page) in iOS setting app

The following steps can be used to to add a child pane (page) in iOS settings app for your application:
1. open settings.bundle, select the item after which you want to add the new item to open the child pane.
2. select "Editor->Add Item" menu to add a new dictionary item
3. expand the new dictionary item, change the type item to "child pane"
4. change the title item to the text you want to display
5. add a new filename item, set it to the plist file name, for example "mychildsettings"
6. open the folder of settings.bundle in Finder, then show the content of the settings bundle
7. copy setting.plist and renamed the copied file to mychildsettings.plist
8. open mychildsettings.plist in xcode and update its content to the settings you want to show in the child pane

When using NSUserDefault interface to get and set the item value defined in child pane page, there is no difference as the item defined in main settings plist file. Just need to specify the key to get and set the item value. Similarly, using registerDefault method also has no difference on the items.

The only small difference is if you need to read the default value defined in the child plist file for a item, you will need to specify the plist file name as below

NSDictionary *settingsInfo = [NSDictionary dictionaryWithContentsOfFile:[
                                                                             [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"] stringByAppendingPathComponent:@"mychildsettings.plist"]];

NSLog(@"%@", settingsInfo);

Note the key in NSUserDefault is case sensitive.

Monday, September 1, 2014

Understanding Entity Framework Code First

The feature of Code First for Entity Framework will allow developer to write code to manage data in database without first creating the table in the database. Although it is helpful in some case, it may also cause confusion if you are not sure what actually happened behind the door.

After the Entity Framework is added into the project, and the models are defined. You will need to create a dbContext class to define the dataset to expose the model as below
       [Table("Books")] // Table name
        public class Book
        {
            [Key] // Primary key
            public int BookID { get; set; }
            public string BookName { get; set; }
            public string ISBN { get; set; }
            public float price { get; set; }
        }

  public class BookDbContext :DbContext
    {
        public DbSet<Book> Books { get; set; }
        public DbSet<Review> Reviews { get; set; }
    }.

That is all required for Entity Framework to automatically create the database table with the proper schema. Note you do not need to define the connection string for the database, Visual Studio will automatically select the database based on the following rules:
  • If a local SQL Express instance is available (installed by default with Visual Studio 2010) then Code First has created the database on that instance
  • If SQL Express isn’t available then Code First will try and use LocalDb (installed by default with Visual Studio 2012)
  • The database is named after the fully qualified name of the derived context, in our case that is WebApplication1.BookDbContext

To verify this, run   command in Package Manager Console
Enable-Migrations
add-migration init
update-database

And then connecting to SQLExpress or localDB's database WebApplication1.BookDbContext, you will see the table scheme is automatically created.

At this moment, you can also update configuration seed method to create the initial data, once the code is added, just run "update-database" again will populate the record in the table.

At anytime, if you change the model class public property (scheme), you can run the below command again to update the database. Note seed method is run with the newschema update, so if you do not want to use the seed method to add the initial record again, then you will need commenting out the code in seeding method
add-migration myadditionchange
update-database


In certain cases, the database may already exist, and you only need to use code first to create the model table, if so, you will need to add a connectionstring in web.config under configuration section
<connectionStrings>
    <add name="BookContext" connectionString="Data Source=JOHN-PC\SQLEXPRESS;Initial Catalog=WebApplication1.BookDbContext;Integrated Security=True"
      providerName="System.Data.SqlClient" />
  </connectionStrings>

The name is used by contextdb's base class constructor to find the right connection string to use.
public BlogDbContext() : base("name=BookContext") 
        { 
        } 

Note if you get anything wrong during migration, you can always use 
enable-migrations -force
to reset the migration.