How to create .pem for apple push notification


cropped-mobile.jpg

To enable Push Notification for your iOS app, we will need you to create and upload the Apple Push Notification Certificate (.pem file) to us so we will be able to connect to Apple Push Server on your behalf.

Step 1: Login to iOS Provisioning Portal, click “Certificates” on the left navigation bar. Then, click “+” button.

enter image description here

Step 2: Select Apple Push Notification service SSL (Production) option under Distribution section, then click “Continue” button.

enter image description here

Step 3: Select the App ID you want to use for your BYO app (How to Create An App ID), then click “Continue” to go to next step.

enter image description here

Step 4: Follow the steps “About Creating a Certificate Signing Request (CSR)” to create a Certificate Signing Request.

enter image description here

To supplement the instruction provided by Apple. Here are some of the additional screenshots to assist you to complete the required steps:

Step 4 Supplementary Screenshot 1: Navigate to Certificate Assistant of Keychain Access on your Mac.

enter image description here

Step 4 Supplementary Screenshot 2: Fill in the Certificate Information. Click Continue.

enter image description here

Step 5: Upload the “.certSigningRequest” file which is generated in Step 4, then click “Generate” button.

enter image description here

Step 6: Click “Done” to finish the registration, the iOS Provisioning Portal Page will be refreshed that looks like the following screen:

enter image description here

Then Click “Download” button to download the certificate (.cer file) you’ve created just now. – Double click the downloaded file to install the certificate into Keychain Access on your Mac.

Step 7: On your Mac, go to “Keychain”, look for the certificate you have just installed. If unsure which certificate is the correct one, it should start with “Apple Production IOS Push Services:” followed by your app’s bundle ID.

enter image description here

Step 8: Expand the certificate, you should see the private key with either your name or your company name. Select both items by using the “Select” key on your keyboard, right click (or cmd-click if you use a single button mouse), choose “Export 2 items”, like Below:

enter image description here

Then save the p12 file with name “pushcert.p12” to your Desktop – now you will be prompted to enter a password to protect it, you can either click Enter to skip the password or enter a password you desire.

Step 9: Now the most difficult part – open “Terminal” on your Mac, and run the following commands:

cd
cd Desktop
openssl pkcs12 -in pushcert.p12 -out pushcert.pem -nodes -clcerts

Step 10: Remove pushcert.p12 from Desktop to avoid mis-uploading it to Build Your Own area. Open “Terminal” on your Mac, and run the following commands:

cd
cd Desktop
rm pushcert.p12

Now you have successfully created an Apple Push Notification Certificate (.pem file)! You will need to upload this file to our Build Your Own area later on. 🙂

Advertisements

CoreData Day-1 :: What is coreData ?


cropped-mobile.jpg

Core Data:: Core Data is an object graph and persistence framework provided by Apple in the Mac OS X and iOS operating systems. It was introduced in Mac OS X 10.4 Tiger and iOS with iPhone SDK 3.0. It allows dataorganised by the relational entity–attribute model to be serialised into XML, binary, or SQLite stores.

Core Data Features

The Core Data framework provides generalized and automated solutions to common tasks associated with object life-cycle and object graphmanagement, including persistence. Its features include:

  • Change tracking and undo support.Core Data provides built-in management of undo and redo beyond basic text editing.
  • Relationship maintenance.Core Data manages change propagation, including maintaining the consistency of relationships among objects.
  • Futures (faulting).Core Data can reduce the memory overhead of your program by lazily loading objects. It also supports partially materialized futures, and copy-on-write data sharing.
  • Automatic validation of property values.Core Data’s managed objects extend the standard key-value coding validation methods that ensure that individual values lie within acceptable ranges so that combinations of values make sense.
  • Schema migration.Dealing with a change to your application’s schema can be difficult, in terms of both development effort and runtime resources. Core Data’s schema migration tools simplify the task of coping with schema changes, and in some cases allow you to perform extremely efficient in-place schema migration.
  • Optional integration with the application’s controller layer to support user interface synchronization.Core Data provides the NSFetchedResultsController object on iOS, and integrates with Cocoa Bindings on OS X.
  • Full, automatic, support for key-value coding and key-value observing.In addition to synthesizing key-value coding and key-value observing compliant accessor methods for attributes, Core Data synthesizes the appropriate collection accessors for to-many relationships.
  • Grouping, filtering, and organizing data in memory and in the user interface.
  • Automatic support for storing objects in external data repositories.
  • Sophisticated query compilation.Instead of writing SQL, you can create complex queries by associating an NSPredicate object with a fetch request. NSPredicate provides support for basic functions, correlated subqueries, and other advanced SQL. With Core Data, it also supports proper Unicode, locale-aware searching, sorting, and regular expressions.
  • Merge policies.Core Data provides built in version tracking and optimistic locking to support automatic multi-writer conflict resolution.

Why Should You Use Core Data?

There are a number of reasons why it may be appropriate for you to use Core Data. One of the simplest metrics is that, with Core Data, the amount of code you write to support the model layer of your application is typically 50% to 70% smaller as measured by lines of code. This is primarily due to the features listed above—the features Core Data provides are features you don’t have to implement yourself. Moreover they’re features you don’t have to test yourself, and in particular you don’t have to optimize yourself.

Core Data has a mature code base whose quality is maintained through unit tests, and is used daily by millions of customers in a wide variety of applications. The framework has been highly optimized over several releases. It takes advantage of information provided in the model and runtime features not typically employed in application-level code. Moreover, in addition to providing excellent security and error-handling, it offers best memory scalability of any competing solution. Put another way: you could spend a long time carefully crafting your own solution optimized for a particular problem domain, and not gain any performance advantage over what Core Data offers for free for any application.

In addition to the benefits of the framework itself, Core Data integrates well with the OS X tool chain. The model design tools allow you to create your schema graphically, quickly and easily. You can use templates in the Instruments application to measure Core Data’s performance, and to debug various problems. On OS X desktop, Core Data also integrates with Interface Builder to allow you to create user interfaces from your model. These aspects help to further shorten your application design, implementation, and debugging cycles.

What Core Data Is Not

Having given an overview of what Core Data is and does, and why it may be useful, it is also useful to correct some common misperceptions and state what it is not.

  • Core Data is not a relational database or a relational database management system (RDBMS).Core Data provides an infrastructure for change management and for saving objects to and retrieving them from storage. It can use SQLite as one of its persistent store types. It is not, though, in and of itself a database. (To emphasize this point: you could for example use just an in-memory store in your application. You could use Core Data for change tracking and management, but never actually save any data in a file.)
  • Core Data is not a silver bullet.Core Data does not remove the need to write code. Although it is possible to create a sophisticated application solely using the Xcode data modeling tool and Interface Builder, for more real-world applications you will still have to write code.
  • Core Data does not rely on Cocoa bindings.Core Data integrates well with Cocoa bindings and leverages the same technologies—and used together they can significantly reduce the amount of code you have to write—but it is possible to use Core Data without bindings. You can readily create a Core Data application without a user interface

Common method in Swift


1. Check for any field empty in NSDictionary

class func checkforEmptyValueinDictioanty(dic:NSDictionary)-> Bool{

for (keyVal, dataVal) in dic {

  if (dataVal.length()==0){

                println(\(keyVal): \(dataVal.length()))

                return false

            }

            

        }

        return true

    }

2.Email validation

class func isValidEmail(testStr:String) -> Bool {

let fullNameArr = testStr.componentsSeparatedByString(“@”)

        var firstPart: String = fullNameArr[0]

        if let range = firstPart.rangeOfCharacterFromSet(NSCharacterSet.letterCharacterSet()){

 }else{

            return false

        }

      let emailRegEx = “[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}”

 var emailTest = NSPredicate(format:“SELF MATCHES %@”, emailRegEx)

        let result = emailTest.evaluateWithObject(testStr)

        return result

    }

3. Alert in Swift

class func commonAlert(title:String,msg:String,curView:UIViewController){

        var device : UIDevice = UIDevice.currentDevice();

        var systemVersion = device.systemVersion;

        var iosVerion : Float = (systemVersion as NSString).floatValue

        if(iosVerion >= 8.0) {

    

        var alert = UIAlertController(title: title, message: msg, preferredStyle: UIAlertControllerStyle.Alert)

            alert.addAction(UIAlertAction(title: “Ok”, style: UIAlertActionStyle.Default, handler: nil))

                  // return alert

            curView.presentViewController(alert, animated: true, completion: nil)

        }else{

            let alert=UIAlertView(title: title, message: msg, delegate: self, cancelButtonTitle: “ok”)

            alert.show()

           

        }

    }

4. NSUserDefaults in swift as common function

class func saveToUserDefault(value:AnyObject, key:String)

    {

        NSUserDefaults.standardUserDefaults().setObject(value, forKey:key)

        NSUserDefaults.standardUserDefaults().synchronize()

    }

    

    class func userDefaultForKey(key:String) -> String

    {

        return NSUserDefaults.standardUserDefaults().objectForKey(key) as NSString

        

    }

    class func userDefaultForAny(key:String) -> AnyObject

    {

        return NSUserDefaults.standardUserDefaults().objectForKey(key) as AnyObject!

    }

    

    class func userdefaultForArray(key:String) -> Array<AnyObject>

    {

        return NSUserDefaults.standardUserDefaults().objectForKey(key) as Array

    }

    

    class func removeFromUserDefaultForKey(key:String)

    {

        NSUserDefaults.standardUserDefaults().removeObjectForKey(key)

        NSUserDefaults.standardUserDefaults().synchronize()

        

    }

5.Get screen height and width

let _screenWidth=UIScreen.mainScreen().bounds.size.width

let _screenHeight=UIScreen.mainScreen().bounds.size.height

Use different font text in a Label in swift


let secondLabel=UILabel(frame: CGRectMake(0, 16, _screenWidth2, 20))

        secondLabel.textColor=UIColor.whiteColor()

        secondLabel.textAlignment=NSTextAlignment.Center

        secondLabel.font=UIFont(name: “Arial”, size: 12)

        bottomView.addSubview(secondLabel)

        

        let attrSting=NSMutableAttributedString(string: “I agree to the Terms of Service and Privacy Policy.”)

        

        NSLog(“text length is %d”, attrSting.length)

        

        attrSting.addAttribute(NSFontAttributeName, value: UIFont(name: “Helvetica-bold”, size: 14), range: NSMakeRange(15, 16))

        

        attrSting.addAttribute(NSFontAttributeName, value: UIFont(name: “Helvetica”, size: 12), range: NSMakeRange(31,4 ))

        

        attrSting.addAttribute(NSFontAttributeName, value: UIFont(name: “Helvetica-bold”, size: 14), range: NSMakeRange(35, 15))

        

        secondLabel.attributedText=attrSting

Use HexColor in Swift as a color


Add it in your class 

extension UIColor {

   convenience init(red: Int, green: Int, blue: Int) {

       assert(red >= 0 && red <= 255, “Invalid red component”)

       assert(green >= 0 && green <= 255, “Invalid green component”)

       assert(blue >= 0 && blue <= 255, “Invalid blue component”)

       self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: 1.0)

   }

   convenience init(netHex:Int) {

       self.init(red:(netHex >> 16) & 0xff, green:(netHex >> 8) & 0xff, blue:netHex & 0xff)

   }

}

Use it where you need…….

var color = UIColor(red: 0xFF, blue: 0xFF, green: 0xFF)

var color2 = UIColor(netHex:0xFFFFFF)

Pop to specific View controller in iOS


First Method ::

- (void) RetunToSpecificViewController{

    for (UIViewController *controller in self.navigationController.viewControllers) {
        if ([controller isKindOfClass:[AnOldViewController class]]) { 
        //Do not forget to import AnOldViewController.h

            [self.navigationController popToViewController:controller
                                              animated:YES];
            break;
        }
    }



Second Method ::

NSArray *array = [self.navigationController viewControllers];

[self.navigationController popToViewController:[array objectAtIndex:2] animated:YES];
Best Of Luck.

Develop first Android Game with AndEngine


There are many frameworks you can use to make games on Android – the most popular being libGDX, AndEngine and Cocos2D-X. Each engine has its pros and cons.
Cocos2D-X (which we previously covered in a two-part series here and here) is great for making cross-platform games, but it does bring along a bit of extra complexity.
What if you just want to get a simple game working on Android the quickest and easiest way? This is where AndEngine comes in handy! Its API is very easy to use and it takes hardly any time to learn the ins and outs of the engine.
You’ll put AndEngine to work creating a version of the famous mathematical puzzle the Tower of Hanoi. Before you begin, make sure you’ve read my previous two tutorials on Getting Started with Android (here and here), or have some Android development experience under your belt.
Keep reading to get started with AndEngine!
All About the AndEngines
AndEngine logo
Which do you like better, this or the Cocos2D logo?
First, here’s a brief overview of AndEngine, including what I like and dislike about it.
AndEngine is currently available in two flavors: GLES1 and GLES2. As you might have gathered from the name, the GLES1 version supports OpenGL ES 1.x. Almost 99% of Android devices can run a game built using this version.
GLES2, as you might guess, supports OpenGL ES 2.0. This branch is actively being worked on, and nearly 93% of current Android devices can run a game that’s been made with this branch.
AndEngine Pros:
It has a complete 2-D scene graph, with a very easy-to-use API.
It works really well with the Android activity lifecycle.
It has a number of extensions that can be added as plugins.
It’s free :]
AndEngine Cons:
The biggest problem I’ve faced while using AndEngine is that the API is undocumented. This can increase the development time, as you sometimes need to go through the engine source code to figure things out. Don’t worry though – I’ve got you covered in this tutorial! :]
Getting Started
Now that you know a bit more about AndEngine, it’s time to download the source code and set up the environment.
Note: Since AndEngine is hosted on GitHub, you could always clone the git repository for AndEngine to get the source code for the project. However, this requires that you have git installed on your machine and that you are able to work on the command line.
Open up your browser and go to the AndEngine github page. You should see a link on the page to download the repository as a ZIP file. Use that to download a copy of the AndEngine project. Or, you should be able to use this link to download the file directly.
Extract the downloaded ZIP file to a convenient location on your hard drive.
Now that you’ve got the source code for the game engine, if you want, you can also download the code for additional AndEngine extensions. In this tutorial, you will not be using any of the extensions but you will need all of them in place if you wanted to try out the AndEngine sample project, which is also available on GitHub.
The sample project is a great way to learn the different ways to use AndEngine and you can always get the latest sample project and the extensions by downloading each of them from GitHub, setting up the projects, and building the sample. However, that is probably beyond the scope of this tutorial and so we’ll leave that to you to figure out, if you’re interested :] You can find it all at https://github.com/nicolasgramlich.
Setting Up the Environment
Before you start coding, there are a few things you should know about AndEngine:
OpenGL ES 2.0: The currently developed version of AndEngine is the GLES 2.0 version. This version requires OpenGL ES 2.0 support in order to function. So you need to make sure that your device (or emulator) supports OpenGL ES 2.0. If you are using the emulator to test, then you need graphics acceleration support and this is there only in the latest SDK Tools version. As of this tutorial, the latest SDK Tools version available is revision 19. Make sure that you have at least this version installed. To upgrade, please follow the instructions given here.
Android 4.0.3: You also need Android SDK Platform API 15, Revision 3 or higher in order to test OpenGL ES 2.0 based code on the emulator. So make sure that you’ve upgraded to at least Android 4.0.3, which is API 15. You emulator used for testing AndEngine code should be using Android 4.0.3.
Emulator: If you are using the emulator to test AndEngine code, you need a virtual device which has GPU emulation enabled and is running at least Android 4.0.3. So check your virtual device configuration and edit it if your device is not set up appropriately.
Andengine3
With that done, it’s time to start Eclipse, the IDE usually used for Android development. So go ahead an start Eclipse.
The version of AndEngine that you downloaded from GitHub already contains an Eclipse project file. You can simply import that by going to File->Import … That should open the following dialog:
Andengine1
Select “Existing Projects into Workspace” from the dialog and click “Next”. A new dialog should open where you must specify the location of the AndEngine project. It looks something like this:
Andengine2
Click the “Browse” button and browse to the folder where you extracted the AndEngine source ZIP file. The existing project should be detected and show up automatically in the dialog. Click “Finish”. And you should have the project imported into your Eclipse workspace – it’s that simple :]
If by some chance the extracted source is missing the Eclipse project information, you can create a new project by going to File->New->Project. A window like the one shown in the image below will open. Select Android Project and click Next.

Give the project a name: I suggest sticking with “AndEngine.” Select the “Create project from existing source” option. Next click the browse button, go to the location of the AndEngine source code and select Open. Once you’ve found the right location, press Finish. This will create a new project called AndEngine that you can view in the project navigator.

Your AndEngine project is now ready. This way, you can add your AndEngine project as a library to your tutorial project and the AndEngine library will be compiled in as part of your tutorial project.
The Tower of Hanoi
Time to start making your first Android game!! The game for this tutorial will be a simple version of the Tower of Hanoi puzzle. The finished project will look like this:

The objective of the Tower of Hanoi is to move all the rings over to the third rod, while only moving one ring at a time and without placing a larger ring on top of a smaller one.
Start by creating a new project. Open Eclipse and go to File->New and select Project, then select Android Project. Fill out all the details. I used the project name “TowerOfHanoi” and the package name “com.tutorial.towerofhanoi.” Feel free to use any name you wish, though it will be easier to stay in sync with the tutorial if you follow the same naming conventions.
Next add AndEngine as a library to your project. Right-click on the project and select Properties. Select Android in the left panel of the pop-up window. You should see a window like the one below:

From here you can add the engine as a library to the project. Click the Add button to add the AndEngine project. Once this is done, click Apply and then Okay.
Start Your AndEngine
Now you can begin coding. Open the src directory for the project via the Eclipse project navigator. If you drill down, (and if you used the suggested names) you should find a Java file called “TowerOfHanoiActivity.java”. (If you opted to name the first activity created something else, then find that file.) Open this file.
In Android development, an Activity is a single focused thing which interacts with the user. For instance, when you start an app, you can have a login activity which allows the user to login using their authentication credentials. And if the user doesn’t have a login, you might provide a second registration activity which will allow them to create a login.
The first file created by the project is also an Activity. And the first thing to do in our project is to change the class that this Activity extends. Instead of extending the Activity class, you want to make it extend a class called SimpleBaseGameActivity. And it’s fairly simple to do that, but in order to refer to the SimpleBaseGameActivity class, we need to add a few import statements for it. So we add that first to the top of the file under the existing import line:
import org.andengine.ui.activity.SimpleBaseGameActivity;
import org.andengine.engine.options.EngineOptions;
import org.andengine.entity.scene.Scene;
Note: Technically, you don’t have to always add the import statements first. You can always add your code in, look for the red underlines beneath classes, let the Eclipse code-fix tell you what import is needed and let it add the imports for you. But this might get a little bit confusing when you’re not sure which import to add when you get a several different choices. So in this tutorial, we’ll always add the imports first.
Now, just change the class definition line, similar to the following:
public class TowerOfHanoiActivity extends Activity {
To something like this:
public class TowerOfHanoiActivity extends SimpleBaseGameActivity {
The SimpleBaseActivity class provides additional callbacks and contains the code to make AndEngine work with the Activity life cycle. Each callback that it provides is used for a specific purpose. As soon as you extend this class, you’ll have to override three functions. Here is a brief description of each of those functions:
onCreateEngineOptions: This function is where you create an instance of the engine. Every activity that the game uses will have its own instance of the engine that will run within the activity lifecycle.
onCreateResources: This is the function where you’ll load all the resources that the activity requires into the the VRAM.
onCreateScene: This function is called after the above two callbacks are executed. This is where you create the scene for your game and use all the textures that you previously loaded into memory.
We will first add some empty placeholders for the above callbacks so that we have some skeleton code. Replace the existing contents of our TowerOfHanoiActivity class with the following (if you started with an automatically created Activity, you should have an onCreate method implementation):
@Override
public EngineOptions onCreateEngineOptions() {
// TODO Auto-generated method stub
return null;
}

@Override
protected void onCreateResources() {
// TODO Auto-generated method stub
}

@Override
protected Scene onCreateScene() {
// TODO Auto-generated method stub
return null;
}
Next, create a few static variables. These will be private to our class. So add the following code right below the class definition line:
private static int CAMERA_WIDTH = 800;
private static int CAMERA_HEIGHT = 480;
These two static variables define the width and height of the camera that the engine will use. This means that the final dimensions of the game scene will be equal to the camera size and width.
Next, you’re going to write code to initialize an instance of the engine. But that code is going to require several import statements in order to function properly. So first add the following imports to the top of the file below the existing import statements:
import org.andengine.engine.camera.Camera;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
Now, add the following code for the onCreateEngineOptions function, replacing the placeholder conent which is in there at the moment:
final Camera camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED,
new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);
In the above code, you create a new instance of the Camera class. Then we use that camera object to create the EngineOptions object that defines the options with which the engine will be initialized. The parameters that are passed while creating an instance of EngineOptions are:
FullScreen: A boolean variable signifying whether or not the engine instance will use a fullscreen.
ScreenOrientation: Specifies the orientation used while the game is running.
ResolutionPolicy: Defines how the engine will scale the game assets on phones with different screen sizes.
Camera: Defines the width and height of the final game scene.
Take a step back for a moment. As you know, Android runs on a lot of devices with different screen sizes. Keeping this in mind, it becomes very difficult to resize the game scene for each device. AndEngine comes with a unique solution to this problem: it will automatically scale the game assets to fit the screen size of the device.
If you set your CAMERA_WIDTH/CAMERA_HEIGHT to 480×320 and someone runs it on a phone with a 800×480 screen size, your game will be scaled up to 720×480 (1.5x) with a 80px margin (top, bottom, left, or right). Notice that AndEngine keeps the same aspect ratio and scales the game scene to the closest possible value to the actual screen size.
Loading Game Assets to VRAM
Now that you’ve initialized an instance of the engine, you can load all the assets required by the Tower of Hanoi game into memory. First download the game assets here.
Next create a new folder within the assets folder already present in your project. To do this, right-click on the assets folder and select New->Folder, name the folder “gfx” and copy all the downloaded assets to that folder.
To load these assets, we’re going to add the onCreateResources method. But as you might guess, our new code references several other classes for which we need to add imports. So add the following at the top of the file below the rest of the import statements:
import org.andengine.opengl.texture.ITexture;
import org.andengine.opengl.texture.bitmap.BitmapTexture;
import org.andengine.util.adt.io.in.IInputStreamOpener;
import org.andengine.util.debug.Debug;

import java.io.IOException;
import java.io.InputStream;
Now, replace the placeholder content in onCreateResources with the following:
try {
// 1 – Set up bitmap textures
ITexture backgroundTexture = new BitmapTexture(this.getTextureManager(), new IInputStreamOpener() {
@Override
public InputStream open() throws IOException {
return getAssets().open(“gfx/background.png”);
}
});
ITexture towerTexture = new BitmapTexture(this.getTextureManager(), new IInputStreamOpener() {
@Override
public InputStream open() throws IOException {
return getAssets().open(“gfx/tower.png”);
}
});
ITexture ring1 = new BitmapTexture(this.getTextureManager(), new IInputStreamOpener() {
@Override
public InputStream open() throws IOException {
return getAssets().open(“gfx/ring1.png”);
}
});
ITexture ring2 = new BitmapTexture(this.getTextureManager(), new IInputStreamOpener() {
@Override
public InputStream open() throws IOException {
return getAssets().open(“gfx/ring2.png”);
}
});
ITexture ring3 = new BitmapTexture(this.getTextureManager(), new IInputStreamOpener() {
@Override
public InputStream open() throws IOException {
return getAssets().open(“gfx/ring3.png”);
}
});
// 2 – Load bitmap textures into VRAM
backgroundTexture.load();
towerTexture.load();
ring1.load();
ring2.load();
ring3.load();
} catch (IOException e) {
Debug.e(e);
}
In the above code, you first create an ITexture object. ITexture is an interface. An object of this type is initialized to a BitmapTexture object, which, you guessed it, is used to to load a bitmap into VRAM. The above code creates ITexture objects for all the assets you downloaded, and loads them into VRAM by calling the load method on each object.
Now that you have all your assets loaded, you need to extract TextureRegions from your textures. Think of a texture as a giant canvas that has to have width and height values which are a power of 2 (a requirement of OpenGL ES). A TextureRegion, on the other hand, is a part or a region of a texture that does not have to have dimensions which are a power of 2.
Note: Instead of creating textures for each of your assets, you could have loaded all the assets into one texture and extracted the individual assets as TextureRegions. Doing this is out of scope for this tutorial, but I may cover it in detail in a future tutorial.
As you might guess, we have to add a few new import statements first:
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.texture.region.TextureRegionFactory;
Now, to hold the TextureRegions, add private variables to our class (again, at the top of the file, below the previous private variables):
private ITextureRegion mBackgroundTextureRegion, mTowerTextureRegion, mRing1, mRing2, mRing3;
Finally, add these lines of code to onCreateResources, right after the end of section #2 where you load the bitmap textures into VRAM:
// 3 – Set up texture regions
this.mBackgroundTextureRegion = TextureRegionFactory.extractFromTexture(backgroundTexture);
this.mTowerTextureRegion = TextureRegionFactory.extractFromTexture(towerTexture);
this.mRing1 = TextureRegionFactory.extractFromTexture(ring1);
this.mRing2 = TextureRegionFactory.extractFromTexture(ring2);
this.mRing3 = TextureRegionFactory.extractFromTexture(ring3);
The above code initializes your TextureRegions using the textures that you already loaded into VRAM.
Creating the Game Scene
It’s finally time to create the game scene! Of course, we need another new import:
import org.andengine.entity.sprite.Sprite;
Next, replace the placeholder content in onCreateScene with the following:
// 1 – Create new scene
final Scene scene = new Scene();
Sprite backgroundSprite = new Sprite(0, 0, this.mBackgroundTextureRegion, getVertexBufferObjectManager());
scene.attachChild(backgroundSprite);
return scene;
The above code first creates a Scene object. Next you create a sprite called backgroundSprite and attach the sprite to the scene. Notice that this method requires you to return the scene object. Think of a scene as a container with a number of layers, and each layer can have many sprites (TextureRegions) placed within it.
When creating a Sprite object, you pass four parameters. Here’s a brief description of each parameter:
xCoordinate: Defines the X-position of the sprite. The AndEngine coordinate system considers the top-left point as the origin.
yCoordinate: Defines the Y-position of the sprite.
TextureRegion: Defines what part of the texture the sprite will use to draw itself.
VertexBufferObjectManager: Think of a vertex buffer as an array holding the coordinates of a texture. These coordinates are passed to the OpenGL ES pipeline and ultimately define what will be drawn. A VertexBufferObjectManager holds all the vertices of all the textures that need to be drawn on the scene.
Compile and run the application. You should see something like this:

Nice, we’re starting to see something! However, this platform does look a little bit desert-ed (groan) ;]
The Three Towers
It’s time to add the sprites for the towers and rings – the final step before getting things moving with the game logic. Start by adding three private variables to the class. Declare the variables as follows:
private Sprite mTower1, mTower2, mTower3;
Next add the following lines of code to onCreateScene, right before the final return statement:
// 2 – Add the towers
mTower1 = new Sprite(192, 63, this.mTowerTextureRegion, getVertexBufferObjectManager());
mTower2 = new Sprite(400, 63, this.mTowerTextureRegion, getVertexBufferObjectManager());
mTower3 = new Sprite(604, 63, this.mTowerTextureRegion, getVertexBufferObjectManager());
scene.attachChild(mTower1);
scene.attachChild(mTower2);
scene.attachChild(mTower3);
You’ve defined three sprites, each using the TextureRegion of the tower that you loaded in onCreateResources.Then you added these sprites to your scene. That’s all there is to it!
Compile and run. You should now see the three towers placed in their proper positions.

And One Ring to Bind Them
Let’s talk a little about the game logic before you create your rings. Think of the towers as three stacks (I mean the data structure) – you can only remove the top-most element, and when you add an element it will always be on top. You’ll use these stacks when you write the game logic code.
To create the rings, we need to first make a custom class that will extend Sprite. You do this because every ring needs to know which stack it belongs to.
Right-click on the folder containing TowerOfHanoiActivity.java and select New->Class. You should see a dialog which you should fill in similar to the following:
Andengine4
Note that you probably would have “Source folder” and “Package” filled in automatically. All you’d need to do is type in the “Name” and click “Browse…” next to “Superclass” to find the Sprite class from AndEngine. That should create a Java file called “Ring.java.” Place the following code within the class implementation (after the public class line and before the closing curly brace):
private int mWeight;
private Stack mStack; //this represents the stack that this ring belongs to
private Sprite mTower;

public Ring(int weight, float pX, float pY, ITextureRegion pTextureRegion, VertexBufferObjectManager pVertexBufferObjectManager) {
super(pX, pY, pTextureRegion, pVertexBufferObjectManager);
this.mWeight = weight;
}

public int getmWeight() {
return mWeight;
}

public Stack getmStack() {
return mStack;
}

public void setmStack(Stack mStack) {
this.mStack = mStack;
}

public Sprite getmTower() {
return mTower;
}

public void setmTower(Sprite mTower) {
this.mTower = mTower;
}
Most of the code here is pretty straightforward. The object has three private variables. One is used to keep track of the weight of the tower; this is an integer value, i.e., the higher the value, the bigger the ring. The other two variables are used to store the stack that the ring belongs to and the tower on which it is currently placed.
You’ll also need to add the following import statements to the top of the file:
import java.util.Stack;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;
Now that we have the Ring class, to create and add the rings, add the following lines of code to onCreateScene, right before the return statement:
// 3 – Create the rings
Ring ring1 = new Ring(1, 139, 174, this.mRing1, getVertexBufferObjectManager());
Ring ring2 = new Ring(2, 118, 212, this.mRing2, getVertexBufferObjectManager());
Ring ring3 = new Ring(3, 97, 255, this.mRing3, getVertexBufferObjectManager());
scene.attachChild(ring1);
scene.attachChild(ring2);
scene.attachChild(ring3);
Compile and run to test.
Andengine5
You’ll notice that the rings are now on the first tower but you can’t move the rings. That’s because we haven’t worked out the game logic for placing and moving the rings. So that’s what you’ll do next :]
Game Logic
Ready to bring your Tower of Hanoi puzzle to life? As mentioned before, as the foundation of the game logic, you’re going to create three stacks, each representing a tower. Start by adding the following import for the Stack class to TowerOfHanoiActivity.java:
import java.util.Stack;
Next, declare the stack variables below the other private variables:
private Stack mStack1, mStack2, mStack3;
You’ll initialize these variables in onCreateResources. Add the following lines of code after the end of section #3:
// 4 – Create the stacks
this.mStack1 = new Stack();
this.mStack2 = new Stack();
this.mStack3 = new Stack();
When the game starts, all three rings should be in the first stack. Put the following code in onCreateScene right before the return statement:
// 4 – Add all rings to stack one
this.mStack1.add(ring3);
this.mStack1.add(ring2);
this.mStack1.add(ring1);
// 5 – Initialize starting position for each ring
ring1.setmStack(mStack1);
ring2.setmStack(mStack1);
ring3.setmStack(mStack1);
ring1.setmTower(mTower1);
ring2.setmTower(mTower1);
ring3.setmTower(mTower1);
// 6 – Add touch handlers
scene.registerTouchArea(ring1);
scene.registerTouchArea(ring2);
scene.registerTouchArea(ring3);
scene.setTouchAreaBindingOnActionDownEnabled(true);
In the above code, you do the following:
Added the rings to the first stack.
Set the stack variable of each ring as the first stack and the tower variable as the first tower.
To handle touch and movement of the rings, you registered each ring as a touchable area.
Enabled touch binding.
Now, you need to override the onAreaTouch method of the Sprite class. This is where you’ll add logic to move the rings. But that code in turn will require a method which checks whether a ring collided with a tower. You’ll write that code later, but you need to add an empty method place holder for collision detection as follows (you can add this to the end of the class):
private void checkForCollisionsWithTowers(Ring ring) {
}
You also need to add the following import in order for the ring movement code to be able to identify the relevant classes:
import org.andengine.input.touch.TouchEvent;
Now, replace the first three lines of section #3 in onCreateScene (where you defined the rings) with the following:
Ring ring1 = new Ring(1, 139, 174, this.mRing1, getVertexBufferObjectManager()) {
@Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float pTouchAreaLocalX, float pTouchAreaLocalY) {
if (((Ring) this.getmStack().peek()).getmWeight() != this.getmWeight())
return false;
this.setPosition(pSceneTouchEvent.getX() – this.getWidth() / 2,
pSceneTouchEvent.getY() – this.getHeight() / 2);
if (pSceneTouchEvent.getAction() == TouchEvent.ACTION_UP) {
checkForCollisionsWithTowers(this);
}
return true;
}
};
Ring ring2 = new Ring(2, 118, 212, this.mRing2, getVertexBufferObjectManager()) {
@Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float pTouchAreaLocalX, float pTouchAreaLocalY) {
if (((Ring) this.getmStack().peek()).getmWeight() != this.getmWeight())
return false;
this.setPosition(pSceneTouchEvent.getX() – this.getWidth() / 2,
pSceneTouchEvent.getY() – this.getHeight() / 2);
if (pSceneTouchEvent.getAction() == TouchEvent.ACTION_UP) {
checkForCollisionsWithTowers(this);
}
return true;
}
};
Ring ring3 = new Ring(3, 97, 255, this.mRing3, getVertexBufferObjectManager()) {
@Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float pTouchAreaLocalX, float pTouchAreaLocalY) {
if (((Ring) this.getmStack().peek()).getmWeight() != this.getmWeight())
return false;
this.setPosition(pSceneTouchEvent.getX() – this.getWidth() / 2,
pSceneTouchEvent.getY() – this.getHeight() / 2);
if (pSceneTouchEvent.getAction() == TouchEvent.ACTION_UP) {
checkForCollisionsWithTowers(this);
}
return true;
}
};
Notice that onAreaTouched returns a boolean value. When it returns true, the touch is consumed, otherwise it is passed down to other layers until someone consumes it. So the first thing you do in this method is check if the weight of the current ring is not equal to the weight of the first ring in the stack. If it is, that means this ring is the first element of the stack and so you can proceed to move it, otherwise you let the touch go since you can’t move this ring.
You also check in onAreaTouched if the type of touch is an ACTION_UP event, triggered when the finger is lifted. If it is, you call checkForCollisionsWithTowers whose primary purpose is to check if the ring has collided with (or rather, is touching) a tower. As you may recall, you added a placeholder for checkForCollisionsWithTowers already. Let’s fill the function in now.
Replace the placeholder method for checkForCollisionsWithTowers with the following:
private void checkForCollisionsWithTowers(Ring ring) {
Stack stack = null;
Sprite tower = null;
if (ring.collidesWith(mTower1) && (mStack1.size() == 0 ||
ring.getmWeight() < ((Ring) mStack1.peek()).getmWeight())) {
stack = mStack1;
tower = mTower1;
} else if (ring.collidesWith(mTower2) && (mStack2.size() == 0 ||
ring.getmWeight() < ((Ring) mStack2.peek()).getmWeight())) {
stack = mStack2;
tower = mTower2;
} else if (ring.collidesWith(mTower3) && (mStack3.size() == 0 ||
ring.getmWeight() 0) {
ring.setPosition(tower.getX() + tower.getWidth()/2 –
ring.getWidth()/2, ((Ring) stack.peek()).getY() –
ring.getHeight());
}
stack.add(ring);
ring.setmStack(stack);
ring.setmTower(tower);
}
The above code checks whether the given ring is touching a tower, if it is, whether it can be moved to that tower, and if yes, places the ring appropriately.
Build and run, and you should have a completely functional Tower of Hanoi game! There are only three rings, but that means you should be able to beat the game in no time. 😛
Where to Go From Here?
Here is the complete source code of the project.
There are a number of things left to be done, but these are easy enough to accomplish. So I’m going to leave them as an exercise for you :] Possible additions include:
Detecting when all the rings have been moved to the third tower and showing a Game Over pop-up.
Counting and displaying the total number of moves.
Calculating and displaying the minimum number of moves required. (Hint: with three rings, the puzzle can be solved in seven moves.)
Allowing the user to increase the difficulty by adding more rings. Legend has it that there is a temple where the priests are working on a version of this puzzle with 64 rings! I don’t suggest you create a version of this game with that many rings, unless you want to spend 580 billion years solving it!
Try your hand at these improvements and let me know how you fare in the forums!

Sencha Navigation Tutorial


1. Main panel issues are resolved now.
2. There are multiple viewport files in the development version. Keep only one while creating production or testing build with Sencha. Because Sencha by default includes all the classes of same name in the build.

——————————————————————————————

Slide navigation in mobile apps is a huge hit now-a-days. Starting from major players like Facebook, Google+ and Youtube, I see most of the dashboard or navigation style apps are using it. And not only it is a new concept, you should find it pretty useful if you have already used it.

I was looking for a similar ready-made component with Sencha Touch and found a number of them (check other example links at the bottom of this post). While all these examples serve the same functionality, I found these are bit complex for a newbie to understand and implement freely in their apps. So, I came up with a dead simple Slide Navigation Menu mostly with CSS3 and a very small chunk of Javascript code. The same navigation can work as leftright and top menu. Follow me.

Lets first create a Sencha Touch project. I used the latest Sencha 2.2 and Sencha CMD 3.1. By default the generated app has a Main view which is the main container for all other panes. But in our case, I created a Viewport view which actually holds the Main and Navigation panels. This Navigation view is the collapsible panel which can be Ext.List or Ext.Dataview or any other view component.

Take a look at the Main and Navigation panels. Both are simple panels with least amount of items inside.

Sencha views

Navigation.js 

1234567891011121314151617
Ext.define(‘SlideNav.view.Navigation’, {
extend: ‘Ext.List’,
xtype: ‘navigation’,
requires: [‘Ext.data.Store’],
config: {
cls: ‘nav-list’,
itemTpl: ‘{title}’,
data: [{
title: ‘Item 1’
}, {
title: ‘Item 2’
}, {
title: ‘Item 3’
}
]
}
});
view rawgistfile1.js hosted with ❤ by GitHub

Main.js

Ext.define(‘SlideNav.view.Main’, {
extend: ‘Ext.TabPanel’,
xtype: ‘main’,
config: {
tabBarPosition: ‘bottom’,
items: [{
title: ‘Home’,
iconCls: ‘home’,
html: [‘This is a very simple example of Facebook style slide navigation. ‘,
‘The component is mostly developed with CSS3 animations and a small bit of javascript code. ‘,
‘Use it freely in your Sencha Touch application’
],
styleHtmlContent: true
}, {
xtype: ‘titlebar’,
title: ‘Slide Nav’,
docked: ‘top’,
items: [{
align: ‘left’,
name: ‘nav_btn’,
iconCls: ‘list’,
ui: ‘plain’
}
]
}
]
}
});
view rawgistfile1.js hosted with ❤ by GitHub

Portfolio_Page_1

A navigation menu at left is the most popular one – lets start with that. At first we will give the Viewport container a hbox layout. The navigation menu will have a width of 250px and instead of giving Main panel flex:1, we will make it 100% width. In css, we will give the navigation menu a position:absolute and left:0; Now, if Main view’s z-index is greater than Slide nav, it will hide the slidenav behind it (check the figure). One point to remember, if your main panel is having a transparent background, do not forget to add a background to it. Else, the nav menu will be seen behind it.

On clicking nav button, we just set  translateX:250px for Main menu, and the Nav menu is now revealed – hence we get what we want. The concept is that simple.

Same concept can be applied to both right and top navigation too. So, here is our Viewport container:

Viewport.js

Ext.define(‘SlideNav.view.Viewport’, {
extend: ‘Ext.Container’,
xtype: ‘app_viewport’,
requires: [
‘Ext.TitleBar’
],
config: {
fullscreen: true,
layout: ‘hbox’,
items: [{
xtype: ‘main’,
cls: ‘slide’,
// Needed to fit the whole content
width: ‘100%’
}, {
xtype: ‘navigation’,
width: 250
}
]
}
});
view rawgistfile1.js hosted with ❤ by GitHub

All the views are done. We now need to add a handler for the nav button inside the controller where we will add or remove the css classes. We gave the Main panel a class “.slide”, which we will add animations with “.in” and “.out” classes.

CSS for left navigation

/* For left side navigation */
.slide ,
.nav-list {
-webkit-animation-duration: .200s;
-webkit-transition-timing-function: cubic-bezier(0.275, 0.080, 0.425, 0.855);
}
.slide {
background: #f1f1f1;
z-index: 1;
}
/* Main view */
@-webkit-keyframes slideout {
from {
-webkit-transform: translateX(0px);
}
to {
-webkit-transform: translateX(250px);
};
}
@-webkit-keyframes slidein {
from {
-webkit-transform: translateX(250px);
}
to {
-webkit-transform: translateX(0px);
};
}
.slide.out {
-webkit-animation-name: slideout;
-webkit-transform: translateX(250px);
}
.slide.in {
-webkit-animation-name: slidein;
-webkit-transform: translateX(0px);
}
/* Main view ENDS */
/* Nav menu view */
.nav-list {
height: 100%;
background: #222;
-webkit-box-shadow: inset -15px 0px 30px -15px rgba(0,0,0,1);
position: absolute !important;
left: 0;
}
.nav-list .x-list-item {
color: rgb(223, 223, 223);
border-bottom: 1px solid #000 !important;
border-top: 1px solid #333 !important;
font-size: 15px;
}
/* Nav menu view ENDS */
view rawgistfile1.css hosted with ❤ by GitHub

We add/remove these css classes in controller’s toggleNav() method. The controller at this point has only this method. You can use this method inside any of the views also. However, because we maintain the functional part in a controller, I preferred to put it there.

Sencha Controller

App.js

Ext.define(‘SlideNav.controller.App’, {
extend: ‘Ext.app.Controller’,
config: {
refs: {
main: ‘main’,
navigation: ‘navigation’,
navBtn: ‘button[name=”nav_btn”]’
},
control: {
navBtn: {
tap: ‘toggleNav’
},
navigation: {
itemtap: function (list, index, target, record) {
this.toggleNav();
}
}
}
},
/**
* Toggle the slide navogation view
*/
toggleNav: function () {
var me = this,
mainEl = me.getMain().element;
if (mainEl.hasCls(‘out’)) {
mainEl.removeCls(‘out’).addCls(‘in’);
} else {
mainEl.removeCls(‘in’).addCls(‘out’);
}
}
});
view rawgistfile1.js hosted with ❤ by GitHub

all-screens
And here is how the left navigation look. We can move the menu to right and top too. For right nav, we just need to change nav button align property to “right”. In css, we now have to make the initial position of Navigation view at “right 0;” which will fix it to extreme right of window. For main panel, we have the positions just opposite to what we have earlier. Find the code for this below.

Css for right navigation:

/* For right side navigation */
.slide ,
.nav-list {
-webkit-animation-duration: .200s;
-webkit-transition-timing-function: cubic-bezier(0.275, 0.080, 0.425, 0.855);
}
.slide {
background: #f1f1f1;
z-index: 1;
}
/* Main view */
.slide.out {
-webkit-animation-name: slideout;
-webkit-transform: translateX(-250px);
}
.slide.in {
-webkit-animation-name: slidein;
-webkit-transform: translateX(0px);
}
@-webkit-keyframes slideout {
from {
-webkit-transform: translateX(0px);
}
to {
-webkit-transform: translateX(-250px);
};
}
@-webkit-keyframes slidein {
from {
-webkit-transform: translateX(-250px);
}
to {
-webkit-transform: translateX(0px);
};
}
/* Main view ENDS */
/* Nav menu view */
.nav-list {
position: absolute !important;
height: 100%;
right: 0;
-webkit-box-shadow: inset 15px 0px 30px -15px rgba(0,0,0,1);
background: #222;
}
.nav-list .x-list-item {
color: rgb(223, 223, 223);
border-bottom: 1px solid #000 !important;
border-top: 1px solid #333 !important;
font-size: 15px;
}
/* Nav menu view ENDS */
/* For right side navigation ENDS */
view rawgistfile1.css hosted with ❤ by GitHub

For top navigation, we need to do following changes at Viewport.js:

  • Make Viewport layout “vbox
  • Change navigation panel’s width:250 to height:250
  • Change main panel’s width:100% to height:100%, and add width:100% to Main panel’s style

Css for top navigation:

/* For top navigation */
.slide,
.nav-list {
-webkit-animation-duration: .200s;
-webkit-transition-timing-function: cubic-bezier(0.275, 0.080, 0.425, 0.855);
}
.slide {
background: #f1f1f1;
z-index: 1;
}
/* Main view */
.slide.out {
-webkit-animation-name: mainSlideOut;
-webkit-transform: translateY(250px);
}
.slide.in {
-webkit-animation-name: mainSlideIn;
-webkit-transform: translateY(0px);
}
@-webkit-keyframes mainSlideOut {
from {
-webkit-transform: translateY(0px);
}
to {
-webkit-transform: translateY(250px);
};
}
@-webkit-keyframes mainSlideIn {
from {
-webkit-transform: translateY(250px);
}
to {
-webkit-transform: translateY(0px);
};
}
/* Main view ENDS */
/* Nav menu view */
.nav-list {
width: 100%;
background: #222;
position: absolute;
top: 0;
-webkit-box-shadow: inset 0px -15px 30px -15px rgba(0,0,0,1);
}
.nav-list .x-list-item {
color: rgb(223, 223, 223);
border-bottom: 1px solid #000 !important;
border-top: 1px solid #333 !important;
font-size: 15px;
}
/* Nav menu view ENDS */
/* For top navigation ENDS */
view rawgistfile1.css hosted with ❤ by GitHub

This is it. Hope you can use this functionality in your Sencha Touch apps. If you get any issue implementing this, do not hesitate to add a comment here. Whole source code of the extension is available for download at github.

Other resources:

  1. Slide navigation by Weston Nielson
  2. Draggable slide navigation

– See more at: http://innofied.com/simplest-slide-navigation-with-sencha-touch-2-2/#sthash.BrRPz1hJ.dpuf

Sencha Tutorial Part -4


In this article, we are going to complete the following tasks:

  • Add the delete note feature to the Note Editor View.
  • Implement the navigation back to the Notes List Container View when the Home button in the Note Editor View is tapped.
  • Modify the Notes List Container View so it renders the notes grouped by date.

Deleting Records from a Sencha Touch Data Store

The Delete Note workflow begins when a user taps the Delete Button on the Note Editor View:

This Button needs a tap handler, which we will add to the NoteEditor Class, in the NoteEditor.js file:

1 var deleteButton = {
2     xtype: "button",
3     iconCls: "trash",
4     iconMask: true,
5     handler: this.onDeleteButtonTap,
6     scope: this
7 };

As we did with the Save Button, we are using the handler and scope configs to map the function that will handle tap events on the Button, as well as to pass the View as the scope for the handler function.

Of course, we need to add the onDeleteButtonTap() function to the NoteEditor Class:

1 onDeleteButtonTap: function () {
2     console.log("deleteNoteCommand");
3     this.fireEvent("deleteNoteCommand"this);
4 }

This is the same pattern we’ve used to emit events from the Views throughout the application. We capture the event triggered from a control in the View, and create a View event that is in turn captured by the Controller.

Over in the Notes Controller, we are going to map a handler function to the deleteNoteCommand event fired by the Note Editor View. We will do this in the control config, under the noteEditor key:

1 control: {
2     notesListContainer: {
3         // The commands fired by the notes list container.
4         newNoteCommand: "onNewNoteCommand",
5         editNoteCommand: "onEditNoteCommand"
6     },
7     noteEditor: {
8         // The commands fired by the note editor.
9         saveNoteCommand: "onSaveNoteCommand",
10         deleteNoteCommand: "onDeleteNoteCommand"
11     }
12 }

Now we can implement the onDeleteNoteCommand() function like so:

1 onDeleteNoteCommand: function () {
2  
3     console.log("onDeleteNoteCommand");
4  
5     var noteEditor = this.getNoteEditor();
6     var currentNote = noteEditor.getRecord();
7     var notesStore = Ext.getStore("Notes");
8  
9     notesStore.remove(currentNote);
10     notesStore.sync();
11  
12     this.activateNotesList();
13 }

Here, we acquire references to the Note Editor, the note loaded into the editor, and the Notes Store. Remember that the getNoteEditor() function is a routine the framework created for us when we declared the editor in the refs config:

1 refs: {
2     // We're going to lookup our views by xtype.
3     notesListContainer: "noteslistcontainer",
4     noteEditor: "noteeditor"
5 }

Our next steps in onDeleteNoteCommand() are to remove the current note from the store and make the changes permanent:

1 notesStore.remove(currentNote);
2 notesStore.sync();

Finally, we activate the Notes List Container View:

1 this.activateNotesList();

Another quick check on the emulator should confirm that at this point we are able to delete notes.

Navigating Back To the Main View

In order to navigate from the Note Editor View back to the Notes List Container View without making any changes to a note, we need to add a tap handler for the Home Button in the Note Editor Class:

1 var backButton = {
2     xtype: "button",
3     ui: "back",
4     text: "Home",
5     handler: this.onBackButtonTap,
6     scope: this
7 };

We will define the onBackButtonTap() function as follows:

1 onBackButtonTap: function () {
2     console.log("backToHomeCommand");
3     this.fireEvent("backToHomeCommand"this);
4 }

In the Controller, we will map this event to the onBackToHomeCommand() handler function:

1 control: {
2     notesListContainer: {
3         // The commands fired by the notes list container.
4         newNoteCommand: "onNewNoteCommand",
5         editNoteCommand: "onEditNoteCommand"
6     },
7     noteEditor: {
8         // The commands fired by the note editor.
9         saveNoteCommand: "onSaveNoteCommand",
10         deleteNoteCommand: "onDeleteNoteCommand",
11         backToHomeCommand: "onBackToHomeCommand"
12     }
13 }

And the onBackToHomeCommand() function will look like this:

1 onBackToHomeCommand: function () {
2  
3 console.log("onBackToHomeCommand");
4 this.activateNotesList();
5 }

At this point, we can use the emulator to check that a tap on the Home Button activates the Notes List Container View.

Setting Up Grouping in a Sencha Touch List

One important usability detail we are missing is the ability to render the cached notes grouped by date. It’s amazing how easily we can accomplish this in Sencha Touch. Let’s first define a grouper config for the Notes Store:

1 Ext.define("NotesApp.store.Notes", {
2     extend: "Ext.data.Store",
3     requires:"Ext.data.proxy.LocalStorage",
4     config: {
5         model: "NotesApp.model.Note",
6         proxy: {
7             type: 'localstorage',
8             id: 'notes-app-store'
9         },
10         sorters: [{ property: 'dateCreated', direction:'DESC'}],
11         grouper: {
12             sortProperty: "dateCreated",
13             direction: "DESC",
14             groupFn: function (record) {
15  
16                 if (record && record.data.dateCreated) {
17                     returnrecord.data.dateCreated.toDateString();
18                 else {
19                     return '';
20                 }
21             }
22         }
23     }
24 });

As of this writing, groupers are not explained very well in Sencha Touch’s documentation. However, it is not difficult to make sense of this config’s properties. The groupFn config is the function used to generate the label for the group. In our case, the label will be the date the notes were taken:

The sortProperty config defines the value that will be used to sort the groups. If you do not include this config, the fields will be sorted based on the value returned by the function defined with the groupFn config. The direction config specifies the direction to sort the groups.

The last change needed to implement grouping consists of adding the grouped config to the NotesList Class:

1 Ext.define("NotesApp.view.NotesList", {
2     extend: "Ext.dataview.List",
3     alias: "widget.noteslist",
4     config:{
5         scrollable:'vertical'
6     },
7     config: {
8         loadingText: "Loading Notes...",
9         emptyText: "</pre>
10 <div class="\&quot;notes-list-empty-text\&quot;">No notes found.</div>
11 <pre>
12 ",
13         onItemDisclosure: true,
14         grouped: true,
15         itemTpl: "</pre>
16 <div class="\&quot;list-item-title\&quot;">{title}</div>
17 <div class="\&quot;list-item-narrative\&quot;">{narrative}</div>
18 <pre>
19 "
20     }
21 });

When we set the grouped config to true, the List will use the groups defined in its store, through the grouper config, to render its items appropriately.

Let’s check how the list looks after we turned on grouping. Start the emulator and confirm that the notes list has date groups similar to the following screenshot:

 

Sencha Tutorial part -3


we are going to create the Note Editor View. This is the View that will allow our users to create, edit and delete notes.

When we finish this article, our application will have the ability to create notes, and edit existing notes. Let’s get started building the Note Editor View.

 

Creating a Form Panel in Sencha Touch

We will place the View’s source code in the  NoteEditor.js file, which we will create in the view directory:

In the file, we will define an empty NoteEditor Class like so:

1 Ext.define("NotesApp.view.NoteEditor", {
2     extend: "Ext.form.Panel",
3     requires: "Ext.form.FieldSet",
4     alias: "widget.noteeditor",
5     config:{
6         scrollable:'vertical'
7     },
8     initialize: function () {
9  
10         this.callParent(arguments);
11  
12     }
13 });

The Note Editor is an extension of the Ext.form.Panel Class. As we will use a FieldSet Class instance in the View, we are asking the loader to download its source by using the requires config. We are also using the scrollable config to allow the contents of the Panel to scroll vertically. This stops the form from being cropped when its height is larger than the screen height of the device.

As we did with the Notes ListContainer Class, we are going to use the initialize() function to define the Note Editor’s components:

1 Ext.define("NotesApp.view.NoteEditor", {
2     extend: "Ext.form.Panel",
3     requires: "Ext.form.FieldSet",
4     alias: "widget.noteeditor",
5     config:{
6         scrollable:'vertical'
7     },
8     initialize: function () {
9  
10         this.callParent(arguments);
11  
12         var backButton = {
13             xtype: "button",
14             ui: "back",
15             text: "Home"
16         };
17  
18         var saveButton = {
19             xtype: "button",
20             ui: "action",
21             text: "Save"
22         };
23  
24         var topToolbar = {
25             xtype: "toolbar",
26             docked: "top",
27             title: "Edit Note",
28             items: [
29                 backButton,
30                 { xtype: "spacer" },
31                 saveButton
32             ]
33         };
34  
35         var deleteButton = {
36             xtype: "button",
37             iconCls: "trash",
38             iconMask: true,
39             scope: this
40         };
41  
42         var bottomToolbar = {
43             xtype: "toolbar",
44             docked: "bottom",
45             items: [
46                 deleteButton
47             ]
48         };
49  
50         var noteTitleEditor = {
51             xtype: 'textfield',
52             name: 'title',
53             label: 'Title',
54             required: true
55         };
56  
57         var noteNarrativeEditor = {
58             xtype: 'textareafield',
59             name: 'narrative',
60             label: 'Narrative'
61         };
62  
63         this.add([
64             topToolbar,
65             { xtype: "fieldset",
66                 items: [noteTitleEditor, noteNarrativeEditor]
67             },
68             bottomToolbar
69         ]);
70     }
71  
72 });

Within initialize(), after invoking callParent(), we proceed to define the top Toolbar, along with its two buttons, the Home Button and the Save Button. We then define the bottom Toolbar and the Delete Button.

The noteTitleEditor and noteNarrativeEditor are the fields we will use to edit the note’s title and narrative. They are instances of the Ext.form.Text and Ext.form.TextArea Classes.

Once all the View’s components are defined, we proceed to add them to the View. This is where we also add an Ext.form.FieldSet instance to enhance the appearance of the form. The title and narrative editors will render within the FieldSet:

1 this.add([
2     topToolbar,
3     { xtype: "fieldset",
4         items: [noteTitleEditor, noteNarrativeEditor]
5     },
6     bottomToolbar
7 ]);

Rendering a View In Sencha Touch

Before we start developing the features of the Note Editor, we are going to work on the code that will render this View when the New Button in the Notes List Container is tapped.

In the previous chapter of this tutorial we created the tap handler for the New Button, which fires the newNoteCommand event. We also added the onNewNoteCommand() listener to the Notes Controller. We will use this function to activate the Note Editor View.

To activate the Note Editor View in the Controller, we first need to acquire a reference to the View. We will use the noteeditor ref for this purpose:

1 Ext.define("NotesApp.controller.Notes", {
2  
3     extend: "Ext.app.Controller",
4     config: {
5         refs: {
6             // We're going to lookup our views by xtype.
7             notesListContainer: "noteslistcontainer",
8             noteEditor: "noteeditor"
9         },
10  
11    // Remainder of the controller’s code omitted for brevity.
12  
13 });

Remember, this ref automatically creates a getNoteEditor() function in the controller, which we can use to refer to the NoteEditor instance and make it the active View in the application.

Next, we need to modify the onNewNoteCommand() function:

1 onNewNoteCommand: function () {
2  
3     console.log("onNewNoteCommand");
4  
5     var now = new Date();
6     var noteId = (now.getTime()).toString() + (this.getRandomInt(0, 100)).toString();
7  
8     var newNote = Ext.create("NotesApp.model.Note", {
9         id: noteId,
10         dateCreated: now,
11         title: "",
12         narrative: ""
13     });
14  
15     this.activateNoteEditor(newNote);
16 }

Here things get more interesting. We are creating a new note, and passing it to the activateNoteEditor() function.

We are going to use the getRamdomInt() helper function to generate the unique id for a note:

1 getRandomInt: function (min, max) {
2     return Math.floor(Math.random() * (max - min + 1)) + min;
3 }

The activateNoteEditor() function will load the new note into the Note Editor, and make the Editor active:

1 activateNoteEditor: function (record) {
2  
3     var noteEditor = this.getNoteEditor();
4     noteEditor.setRecord(record); // load() is deprecated.
5     Ext.Viewport.animateActiveItem(noteEditor,this.slideLeftTransition);
6 }

Here we are taking advantage of the Ext.form.Panel’s setRecord() function, which allows us to load the values of a model instance into the form’s fields whose names match those of the model’s fields.

This function also uses the slideLeftTransition variable, which we need to define like so:

1 slideLeftTransition: { type: 'slide', direction: 'left' }

The transition will bring the Note Editor into view with a slide motion from the right to the left.

This is all the Controller needs to do in order to activate the Note Editor View when the New Button is tapped. However, we need to make the application aware of the NoteEditor Class.

Making The Application Aware Of A View

In the app.js file, we will add the new View to the views config:

1 views: ["NotesList""NotesListContainer""NoteEditor"]

We are also going to instantiate the View in the Application’s launch function:

1 Ext.application({
2     name: "NotesApp",
3  
4     models: ["Note"],
5     stores: ["Notes"],
6     controllers: ["Notes"],
7     views: ["NotesList""NotesListContainer","NoteEditor"],
8  
9     launch: function () {
10  
11         var notesListContainer = {
12             xtype: "noteslistcontainer"
13         };
14         var noteEditor = {
15             xtype: "noteeditor"
16         };
17  
18         Ext.Viewport.add([notesListContainer,noteEditor]);
19     }
20 });

Ready to check it out? Well, start the emulator. :-)

A tap on the New Button should render the Note Editor View:

Editing A Record Rendered In A Sencha Touch List

We also want to activate the Note Editor View when a note’s disclosure button is tapped:

In order to accomplish this, we need to revisit the onEditNoteCommand() function in the Controller, and add the code that will activate the NoteEditor:

1 onEditNoteCommand: function (list, record) {
2  
3     console.log("onEditNoteCommand");
4  
5     this.activateNoteEditor(record);
6 }

Incredibly simple thanks to the fact that the disclose event supplies the selected Note model instance to the handler through the record argument. All we need to do here is call activateNoteEditor(), which we created a few minutes ago.

Back in the emulator, we should be able to see the Note Editor render the selected note:

Now it is time to save the note. We need to take care of a few things in order for this to happen.

Using A LocalStorage Proxy In Sencha Touch

First, we need to stop using hard-coded notes as the data for the Notes store.

Up to this point, we have been using the data config to define a few hard-coded records in the store:

1 Ext.define("NotesApp.store.Notes", {
2     extend: "Ext.data.Store",
3     config: {
4         model: "NotesApp.model.Note",
5         data: [
6             { title: "Note 1", narrative: "narrative 1" },
7             { title: "Note 2", narrative: "narrative 2" },
8             { title: "Note 3", narrative: "narrative 3" },
9             { title: "Note 4", narrative: "narrative 4" },
10             { title: "Note 5", narrative: "narrative 5" },
11             { title: "Note 6", narrative: "narrative 6" }
12         ],
13         sorters: [{ property: 'dateCreated', direction:'DESC'}]
14     }
15 });

As we intend to cache notes on the device that runs the app, we are going to discontinue the data config in the store, and define a LocalStorage proxy as follows:

1 Ext.define("NotesApp.store.Notes", {
2     extend: "Ext.data.Store",
3     requires:"Ext.data.proxy.LocalStorage",
4     config: {
5         model: "NotesApp.model.Note",
6         proxy: {
7             type: 'localstorage',
8             id: 'notes-app-store'
9         },
10         sorters: [{ property: 'dateCreated', direction:'DESC'}]
11     }
12 });

LocalStorageProxy uses the HTML5 localStorage API to save Model data on the client browser. This proxy is ideal for storing multiple records of similar data. And it requires that we provide the id config, which is the key that will identify our data in the localStorage object.

Now the Notes store has the ability to save and read data from localStorage, and we can go back to the Views and Controller to take care of the functions that will save the data.

Adding Event Listeners To A Sencha Touch Controller

In the NoteEditor Class, let’s modify the saveButton declaration in the initialize() function like so:

1 var saveButton = {
2     xtype: "button",
3     ui: "action",
4     text: "Save",
5     handler: this.onSaveButtonTap,
6     scope: this
7 };

The handler config defines the handler function that will run when a user taps the button. To make sure we run the handler in the scope of the NoteEditor, we set the scope config to this.

Now we can define onSaveButtonTap() as follows:

1 onSaveButtonTap: function () {
2     console.log("saveNoteCommand");
3     this.fireEvent("saveNoteCommand"this);
4 }

No surprises here, right? As we’ve done with other handlers, we are capturing the Button tap event within the View and defining a View event, saveNoteCommand.

As we already know, the fact that the NoteEditor View broadcasts the saveNoteCommand event is not enough for the Controller to be able to listen to it. We need to tell the Controller where this event is coming from, which we did when we added the noteEditor entry in the refs config of the Controller:

1 refs: {
2     // We're going to lookup our views by xtype.
3     notesListContainer: "noteslistcontainer",
4     noteEditor: "noteeditor"
5 }

We will use the Controller’s control config to map the saveNoteCommand event to a handler function. Therefore, need an entry for the Note Editor in the control config:

1 control: {
2     notesListContainer: {
3         // The commands fired by the notes list container.
4         newNoteCommand: "onNewNoteCommand",
5         editNoteCommand: "onEditNoteCommand"
6     },
7     noteEditor: {
8         // The commands fired by the note editor.
9         saveNoteCommand: "onSaveNoteCommand"
10     }
11 }

Finally, we will define the onSaveNoteCommand() function like so:

1 onSaveNoteCommand: function () {
2  
3     console.log("onSaveNoteCommand");
4  
5     var noteEditor = this.getNoteEditor();
6  
7     var currentNote = noteEditor.getRecord();
8     var newValues = noteEditor.getValues();
9  
10     // Update the current note's fields with form values.
11     currentNote.set("title", newValues.title);
12     currentNote.set("narrative", newValues.narrative);
13  
14     var errors = currentNote.validate();
15  
16     if (!errors.isValid()) {
17         Ext.Msg.alert('Wait!', errors.getByField("title")[0].getMessage(), Ext.emptyFn);
18         currentNote.reject();
19         return;
20     }
21  
22     var notesStore = Ext.getStore("Notes");
23  
24     if (null == notesStore.findRecord('id', currentNote.data.id)) {
25         notesStore.add(currentNote);
26     }
27  
28     notesStore.sync();
29  
30     notesStore.sort([{ property: 'dateCreated', direction:'DESC'}]);
31  
32     this.activateNotesList();
33 }

We begin onSaveNoteCommand() acquiring references to the note being edited and the values in the form’s fields:

1 var noteEditor = this.getNoteEditor();
2 var currentNote = noteEditor.getRecord();
3 var newValues = noteEditor.getValues();

Then, we transfer the new values to the loaded note:

1 currentNote.set("title", newValues.title);
2 currentNote.set("narrative", newValues.narrative);

Model Validation In Sencha Touch

Next comes an important part, which is validation. To validate the new values we loaded into the model instance, we first call the model’s validate() function, and then call the isValid() function on the errors object returned by validate():

1 var errors = currentNote.validate();
2  
3 if (!errors.isValid()) {
4     Ext.Msg.alert('Wait!', errors.getByField("title")[0].getMessage(), Ext.emptyFn);
5     currentNote.reject();
6     return;
7 }

The Ext.data.Model’s validate() function iterates over the validations defined for the model, and returns an Ext.data.Errors instance containing Ext.data.Error instances for each model field that is invalid.

In our case, the only field with an attached validator is the note’s title. When we find that the model is invalid, we first display an alert using the validator’s configured message, and then call the model’s reject() function. This function reverts the modified fields back to their original values before we exit the onSaveNoteCommand() handler.

Saving Data Using LocalStorageProxy

In onSaveNoteCommand(), after confirming that the modified note is valid, we move on to save it on the device:

1 var notesStore = Ext.getStore("Notes");
2  
3 if (null == notesStore.findRecord('id', currentNote.data.id)) {
4     notesStore.add(currentNote);
5 }
6  
7 notesStore.sync();

As this routine works for new or edited notes, we need to find out if the note is new by searching the store using its findRecrod() function. If the note is new, we add it to the store.

The store’s sync() function asks the store’s proxy to process all the changes, effectively saving new or edited notes, and removing deleting notes from localStorage.

After the store’s records have been updated, we sort them by date:

1 notesStore.sort([{ property: 'dateCreated', direction:'DESC'}]);

Returning To The Main View

Our last step in onSaveNoteCommand() consists of invoking the activateNotesList() function. This is a helper function, similar to activateNoteEditor(), that will make the app’s main View active:

1 activateNotesList: function () {
2     Ext.Viewport.animateActiveItem(this.getNotesListContainer(),this.slideRightTransition);
3 }

In this case we are using a right-slide transition, which we will define like so:

1 slideRightTransition: { type: 'slide', direction: 'right' }

OK. What do you think about doing another quick check? This time we should be able to save a note: