Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Phonegap - Updating JavaScript and CSS without submitting the app to appStore

Is it possible to update the content of WWW folder in phonegap without submitting the app every time you make changes to appStore? Is there any legal issue with it?

like image 605
Ardavan Kalhori Avatar asked Oct 12 '12 18:10

Ardavan Kalhori


2 Answers

Short answer - yes, you can - but you need to relocate www before you can write to it.

Long answer - tighten up your shorts pilgrim, this might get bumpy....

So, when you package your app, the app bundle contains your www directory and all of the various and sundry parts of your PG self contained web app. Everything that is part of the app bundle is static - so it cannot be written to. You can, however, write to the NSDocumentDirectory for your application - it's private sandboxed storage area.

The first step is to (upon launch) copy your www folder into the NSDocumentDirectory.

Second, you'll need to override the CDVCommandDelegateImpl pathForResource method in order to point PG at the new www location.

At this point your app should be operating as it did when contained within the app bundle. One notable exception is that each of the files can now be modified.

My app is a base product which can have add-on content. If I included all of the add-on content, the app would be several hundred MB in size. So, I include the basic app with a single (sample) data package, and as users need to extend the product, they select additional data packages which are downloaded, extracted and copied into the appropriate subdirectory of the www folder as it exists in the NSDocumentDirectory.

As a bonus, if I find a bug in HTML - or want to add a feature, I can do so without resubmitting the app. The only reason I need to resubmit the app is if there is an Objective-C bugfix.

like image 69
Michael Avatar answered Nov 07 '22 13:11

Michael


This is just adding onto Michael's answer.

1 ) Copy your www folder into the NSDocumentDirectory: - for phonegap ios, add this to /ProjectName/Classes/AppDelegate.m

- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
    CGRect screenBounds = [[UIScreen mainScreen] bounds];

    self.window = [[[UIWindow alloc] initWithFrame:screenBounds] autorelease];
    self.window.autoresizesSubviews = YES;

    self.viewController = [[[MainViewController alloc] init] autorelease];
    //self.viewController.useSplashScreen = YES;

    // Set your app's start page by setting the  tag in config.xml.
    // If necessary, uncomment the line below to override it.
    // self.viewController.startPage = @"index.html";

    // NOTE: To customize the view's frame size (which defaults to full screen), override
    // [self.viewController viewWillAppear:] in your view controller.

    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];


    if ([[NSUserDefaults standardUserDefaults] boolForKey:@"AppFirstLaunch"])
        {
            NSLog(@"App already launched!");
        }
        else
        {
            [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"AppFirstLaunch"];
            [[NSUserDefaults standardUserDefaults] synchronize];

            NSLog(@"App launched for first time!");

            BOOL success1;
            NSError *error1;

            NSFileManager *fileManager1   = [NSFileManager defaultManager];

            fileManager1.delegate         = self;

            NSArray *paths1               = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

            NSString *documentsDirectory1 = [paths1 objectAtIndex:0];

            NSString *writableDBPath1     = [documentsDirectory1 stringByAppendingPathComponent:@"/www"];

            success1                      = [fileManager1 fileExistsAtPath:writableDBPath1];

            if ( success1 )
            {
                NSString *defaultDBPath1 = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"www"];
                NSLog(@"default SUCCESS / AppDelegate path %@",defaultDBPath1);
                success1 = [fileManager1 copyItemAtPath:defaultDBPath1 toPath:writableDBPath1 error:&error1];
            }
            else
            {
                if (![[NSFileManager defaultManager] fileExistsAtPath:writableDBPath1])
                    [[NSFileManager defaultManager] createDirectoryAtPath:writableDBPath1 withIntermediateDirectories:NO attributes:nil error:&error1];
            }
        }

    return YES;
}


2 ) To override the default path ( orig. set to www folder ), within CordovaLib/Classes/CDVCommandDelegateImpl.m, replace the body of the function:

-(NSString*) pathForResource:(NSString*)resourcepath


with:


- (NSString*)wwwFolderName
{
    NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    return [NSString stringWithFormat:@"%@/www",[searchPaths objectAtIndex:0]];
}

- (NSString*) pathForResource:(NSString*)resourcepath
{
    NSBundle* mainBundle           = [NSBundle mainBundle];
    NSMutableArray* directoryParts = [NSMutableArray arrayWithArray:[resourcepath componentsSeparatedByString:@"/"]];
    NSString* filename             = [directoryParts lastObject];

    [directoryParts removeLastObject];

    NSString* directoryPartsJoined = [directoryParts componentsJoinedByString:@"/"];
    NSString* directoryStr         = [self wwwFolderName];

    if ([directoryPartsJoined length] > 0)
    {
        directoryStr = [NSString stringWithFormat:@"%@/%@", [self wwwFolderName], [directoryParts componentsJoinedByString:@"/"]];
    }

    NSLog(@"default path %@",directoryStr);

    if (![[self wwwFolderName] isEqualToString:@"www"])
    {
        return [NSString stringWithFormat:@"%@/%@",[self wwwFolderName],@"shared/index.html"];
    }

    return [mainBundle pathForResource:filename ofType:@"" inDirectory:directoryStr];
}


Other References:

  • Copy Folder from main bundle to documents directory in iphone
  • How to detect first time app launch on an iPhone
like image 27
Dayne Mentier Avatar answered Nov 07 '22 13:11

Dayne Mentier