Archiving and Unarchiving objects in Objective-C

Apple, iPhone, Objective-C No Comments »

Woohoo … my first Objective-C related post!

Ok, so this is nothing new but I thought I’d log a couple of things that caught me out as a NOOB to the whole iPhone development malarky.

First off archiving your objects is a way of saving them to a property list file that sits on your device and can be unarchived the next time your app loads as a way to persist data locally on the device. Very handy it is too. Now there are better ways to manage data in Obj-C … CoreData for a start. This is a much more powerful way to persist data to a SQL lite database and allows you loads more freedom in what you can actually archive. There are limitations to the property list method you see. You can only archive NS objects and simple scalars so your class structure needs to compensate for this. The ‘plist’ objects you can archive are … NSArray, NSDictionary, NSString, NSNumber, NSDate and NSData along with their mutable subclasses. The scalars are int, float, double etc.

I don’t want to write a massive chapter on this and there’s loads of information online about the technical ins and outs of what’s happening behind the scenes. What I do want to do is share the classes I’ve used in a recent project and explain in basics what’s happening.

Firstly we’ll create the object we want to be archived. Any object that needs to be archived and is a subclass of NSObject must adopt the NSCoding protocol. Take a look at this object …

DataModel Object for archiving

  1. /* INTERFACE */
  2.  
  3. #define kfavesArray @"favesArray"
  4. #define kCurrentFave @"currentFave"
  5. #define kCurrentFaveIndex @"currentFaveIndexPath"
  6.  
  7. #import <Foundation/Foundation.h>
  8.  
  9. @class FaveVO;
  10.  
  11.  
  12. @interface DataModel : NSObject <NSCoding>
  13. {
  14.         NSMutableArray *favesArray;
  15.         FaveVO *currentFave;
  16.         int faveIndex;
  17. }
  18.  
  19. @property (nonatomic, retain) NSMutableArray *favesArray;
  20. @property (nonatomic, retain) FaveVO *currentFave;
  21. @property int faveIndex;
  22.  
  23. -(void)addNewFaveLocation:(FaveVO *)fave;
  24. -(void)createNewFaveVOFromFaveVO:(FaveVO *)fave;
  25. -(void)setFaveLocation:(int)index;
  26. -(void)removeFaveLocation;
  27.  
  28. @end
  29.  
  30. /* IMPLEMENTATION */
  31.  
  32. #import "DataModel.h"
  33. #import "FaveVO.h"
  34.  
  35. @implementation DataModel
  36.  
  37. @synthesize favesArray;
  38. @synthesize currentFave;
  39. @synthesize faveIndex;
  40.  
  41. //------------------------------------------------------
  42. -(id)init
  43. {
  44.         if(self = [super init])
  45.         {
  46.                 favesArray = [[NSMutableArray alloc] init];
  47.         }
  48.        
  49.         return self;
  50. }
  51. //--------------------------------------------------
  52. -(void)addNewFaveLocation:(FaveVO *)fave
  53. {
  54.         if(!favesArray) favesArray = [[NSMutableArray alloc] init];
  55.        
  56.         [favesArray insertObject:fave atIndex:0];
  57.         currentFave = [favesArray objectAtIndex:0];
  58.         faveIndex = 0;
  59.        
  60.         NSLog(@"DataModel currentFave: %@ faveIndex: %i", currentFave,faveIndex);
  61. }
  62. //--------------------------------------------------
  63. -(void)setFaveLocation:(int)index
  64. {
  65.         currentFave = [favesArray objectAtIndex:index];
  66.         faveIndex = index;
  67.        
  68.         NSLog(@"DataModel currentFave: %@ faveIndex: %i", currentFave,faveIndex);
  69. }
  70. //--------------------------------------------------
  71. -(void)removeFaveLocation
  72. {
  73.         currentFave = nil;
  74.        
  75.         NSLog(@"DataModel currentFave: %@ faveIndex: %i", currentFave,faveIndex);
  76. }
  77. //--------------------------------------------------
  78. -(void)createNewFaveVOFromFaveVO:(FaveVO *)fave
  79. {
  80.         double lat = fave.lat;
  81.         double lon = fave.lon;
  82.        
  83.         FaveVO *newFaveVO = [[FaveVO alloc] initWithLabel:[NSString stringWithString:fave.label]
  84.                                                                                 streetAddress:[NSString stringWithString:fave.streetAddress]
  85.                                                                                                  city:[NSString stringWithString:fave.city]
  86.                                                                                                 state:[NSString stringWithString:fave.state]
  87.                                                                                                   zip:[NSString stringWithString:fave.zip]
  88.                                                                                                   lat:lat
  89.                                                                                                   lon:lon];
  90.         [favesArray addObject:newFaveVO];
  91.         [newFaveVO release];
  92. }
  93. //--------------------------------------------------
  94. -(void)dealloc
  95. {
  96.         [favesArray release];
  97.         [currentFave release];
  98.         [super dealloc];
  99. }
  100. //--------------------------------------------------
  101.  
  102.  
  103. //--------------------------------------------------
  104. #pragma mark NSCoding
  105. - (void)encodeWithCoder:(NSCoder *)encoder
  106. {
  107.         [encoder encodeObject:favesArray forKey:kfavesArray];
  108.         [encoder encodeObject:currentFave forKey:kCurrentFave];
  109.         [encoder encodeInt:faveIndex forKey:kCurrentFaveIndex];
  110. }
  111. //--------------------------------------------------
  112. - (id)initWithCoder:(NSCoder *)decoder
  113. {
  114.         NSLog(@"DataModel initWithCoder: %@", decoder);
  115.        
  116.         if (self = [super init])
  117.         {
  118.                 self.favesArray = [decoder decodeObjectForKey:kfavesArray];
  119.                
  120.                 self.faveIndex = [decoder decodeIntForKey:kCurrentFaveIndex];
  121.                 self.currentFave = [favesArray objectAtIndex:faveIndex];
  122.         }
  123.         return self;
  124. }
  125.  
  126. @end

This object also references another object called FaveVO this is an object that I’m feeding into an array and also adopts the NSCoding protocol so you can see that you can archive quite a complicated object overall.

The important stuff is after the line that says “#pragma mark NSCoding”. These methods (using Actionscript terminology but I don’t care) handle what happens when the encoder and decoder go to work on your object.

- (void)encodeWithCoder:(NSCoder *)encoder
{
 [encoder encodeObject:favesArray forKey:kfavesArray];
 [encoder encodeObject:currentFave forKey:kCurrentFave];
 [encoder encodeInt:faveIndex forKey:kCurrentFaveIndex];
}

The encodeObject message takes each of my class variables and copies them into an NSData object using the keys which I defined in the interface. These are unique identifiers that I can use when I want to decode them later like so :

- (id)initWithCoder:(NSCoder *)decoder
{
 if (self = [super init])
 {
  self.favesArray = [decoder decodeObjectForKey:kfavesArray];
  self.faveIndex = [decoder decodeIntForKey:kCurrentFaveIndex];
  self.currentFave = [favesArray objectAtIndex:faveIndex];
 }
return self;
}

And that’s all you need to know about the Object you want to archive. Next comes the class that I’m using to do the archiving and unarchiving.

Here’s the class :

Archiving and Unarchiving DataModel Object

  1. /* INTERFACE */
  2.  
  3. #import <Foundation/Foundation.h>
  4.  
  5. #define kFilename       @"dataarchive.plist"
  6. #define kDataKey                @"Data"
  7.  
  8. @class DataModel;
  9. @interface DataManager : NSObject {
  10.  
  11.         DataModel *dataModel;
  12. }
  13.  
  14. @property (nonatomic, retain) DataModel *dataModel;
  15.  
  16. -(NSString *)dataFilePath;
  17. -(void)initDataModel;
  18. -(void)applicationWillTerminate:(NSNotification *)notification;
  19.  
  20. +(DataManager *)sharedDataManager;
  21.  
  22. @end
  23.  
  24. /* IMPLEMENTATION */
  25.  
  26. #import "DataManager.h"
  27. #import "SynthesizeSingleton.h"
  28. #import "DataModel.h"
  29. #import "FaveVO.h"
  30.  
  31. @implementation DataManager
  32.  
  33. SYNTHESIZE_SINGLETON_FOR_CLASS(DataManager);
  34.  
  35. @synthesize dataModel;
  36.  
  37. //-----------------------------------------------------------------------------------------------------
  38. - (NSString *)dataFilePath
  39. {
  40.         NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  41.         NSString *documentsDirectory = [paths objectAtIndex:0];
  42.         return [documentsDirectory stringByAppendingPathComponent:kFilename];
  43. }
  44. //-----------------------------------------------------------------------------------------------------
  45. -(void)initDataModel
  46. {
  47.         NSString *filePath = [self dataFilePath];
  48.        
  49.         if([[NSFileManager defaultManager] fileExistsAtPath:filePath])
  50.         {
  51.                 NSLog(@"FILE EXISTS");
  52.                
  53.                 NSData *data = [[NSMutableData alloc] initWithContentsOfFile:[self dataFilePath]];
  54.                 NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
  55.                
  56.                 DataModel *decodedDataModel = [unarchiver decodeObjectForKey:kDataKey];
  57.                
  58.                 dataModel = [[DataModel alloc] init];
  59.                
  60.                 NSEnumerator *enumerator;
  61.                 enumerator = [decodedDataModel.favesArray objectEnumerator];
  62.                
  63.                 FaveVO *decodedFaveVO;
  64.                
  65.                 while (decodedFaveVO = [enumerator nextObject])
  66.                 {
  67.                         [dataModel createNewFaveVOFromFaveVO:decodedFaveVO];
  68.                 }
  69.                
  70.                 int index = decodedDataModel.faveIndex;
  71.                 dataModel.faveIndex = index;
  72.                 dataModel.currentFave = [dataModel.favesArray objectAtIndex:index];
  73.                
  74.                 [unarchiver finishDecoding];
  75.                 [unarchiver release];
  76.                 [data release];
  77.         }
  78.         else
  79.         {
  80.                 NSLog(@"FILE DOES NOT EXIST");
  81.                
  82.                 dataModel = [[DataModel alloc] init];
  83.         }
  84.        
  85.         UIApplication *app = [UIApplication sharedApplication];
  86.         [[NSNotificationCenter defaultCenter] addObserver:self
  87.                                                                                          selector:@selector(applicationWillTerminate:)
  88.                                                                                                  name:UIApplicationWillTerminateNotification
  89.                                                                                            object:app];
  90.         
  91. }
  92. //-------------------------------------------------------------
  93. - (void)applicationWillTerminate:(NSNotification *)notification
  94. {
  95.         NSLog(@"Application will terminate");
  96.        
  97.         NSMutableData *data = [[NSMutableData alloc] init];
  98.         NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
  99.        
  100.         [archiver encodeObject:dataModel forKey:kDataKey];
  101.         [archiver finishEncoding];
  102.         [data writeToFile:[self dataFilePath] atomically:YES];
  103.        
  104.         [archiver release];
  105.         [data release];
  106. }
  107.  
  108.  
  109. //--------------------------------------------------
  110. -(void)dealloc
  111. {
  112.         [dataModel release];
  113.         [super dealloc];
  114. }
  115.  
  116.  
  117. @end

The initDataModel method looks for the property list and then uses the NSKeyedUnarchiver object to decode the objects. When the application terminates the objects are encoded using the NSKeyedArchiver object. The class listens for the ApplicationWillTerminate notification using the NSNotificationCenter object. This is similar to the Actionscript event model that uses listeners. The NSEnumerator object is used to step through an array of objects. The decoded FaveVO objects are then sent through to my DataModel class and passed to the createNewFaveVOFromFaveVO method which is where the objects are re-created as shiny new objects. Remember the NSKeyedUnarchiver object is released so you need to retain the objects you need … usually better to create new ones within the correct scope.

Adobe vs Apple? Sod the developers … what does the user want?

Apple, Flash, iPhone, rant, Web tools No Comments »

There’s been all kinds of heated debate and colorful invective surrounding the latest events in the Adobe vs Apple altercation. It’s hard for me to take sides because as a Flash developer for over ten years now and as a loyal Mac user for nearly 20 I’m finding that I do sympathise with both sides.

I find it distasteful that Apple should introduce section 3.3.1 merely days before the release of CS5 and Adobe’s new ‘compile Flash to iPhone app’ feature. It’s really quite underhand and will effect a lot of people’s livelihoods and damage business. Let’s not forget it’s not just Adobe that will be affected by this change. Unity3D and other 3rd party tools will not be able to release apps on the store. Some great apps like the ‘Star Wars Trench Run’ may need to be removed and as I understand it with my limited knowledge of these things some of the larger publishers like EA may also be affected as their games use 3rd party interpreters and tools that will be outlawed by Apple’s new rules.

On the other side though, Adobe should never have introduced this feature without the approval of Apple. They rushed this thing out and in the process have gambled with the livelihoods of hundreds of developers who have put their stake in iPhone app development with Flash.

Basically I think both parties have been very arrogant and have damaged a lot of reputations in the industry … mainly developers. We’ve got decent, honest people at each others throats when all they want to do is work together to make amazing, engaging content.

But the biggest victim in all this is the user. People buy iPhones and wonder why they can’t see the rich content they’ve come to expect. They struggle trying to view Flash content in the browser that hasn’t been built properly or they haven’t got the correct plug-in installed. What does the user want? Why is it all going wrong?

Fifteen years ago I was building CD-Rom titles in Director 3 which at the time was owned by Macromedia. We started using Flash 2 when it was released so we could include animated SWF content in our Director titles. We then started building Flash content for the web. At the time there was no such thing as ‘web standards’ … HTML was pretty basic and browsers were packed full of plug-in’s developed so you get the most out of your browsing experience. You had the ‘Real’ or ‘Quicktime’ plugin to watch video, ‘Shockwave’ allowed you to play amazing games online and ‘Flash’ exploded all over the web because it brought the browser to life and allowed us to build truly engaging rich content without loading new pages to update content.

In the present day we have a completely different type of internet. Web standards have evolved to the point that we now have a perfectly reasonable alternative to Flash integrated into the browser. HTML5 and WebGL allows us to build rich engaging content without a plug-in. In fact Flash is probably one of the few plugins people are still required to install into their browser to view a vast majority of content. And this is where Adobe have failed the user. Director died a death because people didn’t need to publish CD-Roms anymore and Flash should have evolved so the user didn’t need to use a plug-in in their browser.

Adobe should have adapted Flash so it output HTML5 and WebGL 3D content. The AIR runtime is fine on the desktop (although I will always choose a native Mac OS app) and will be just fine on the Android platform, hell they might even integrate it into their OS. But it’s in the browser they’ve failed and if they want to see Flash content on the iPhone they need to improve their tools (like Flash or Dreamweaver) so they produce standards compliant, rich, interactive content in the browser natively. This, after all, is what the user wants.

And Steve, stop being so evil. You’re forgetting what Apple was supposed to stand for. You should watch your 1984 Keynote speech every morning to remind yourself.

Some links on the subject …

http://www.smashingmagazine.com/2010/04/12/the-gradual-disappearance-of-flash-websites/

http://www.devwhy.com/blog/2010/4/12/its-all-about-the-framework.html?lastPage=true#comment8034519

http://mashable.com/2010/04/10/steve-jobs-adobe/

http://theflashblog.com/?p=1888

http://blog.codecomputerlove.com/2010/04/09/have-apple-crushed-cs5-flash-to-iphone-opportunity/

UPDATE: Apparently Flash to HTML5 was showcased during a ‘sneak peek’ session at MAX 2009 but has not made it into the new CS5 release. This is a real shame … Adobe could have made some real progress there.

UPDATE UPDATE: Apple have already started pulling apps. Scratch is an education tool built by MIT … it’s now not educating children in computer science.

Apple also banned this app for being too satirical!

Apple Magic Mouse – first impressions

Apple, rant 2 Comments »

Ok … so I’ve always had a love/hate relationship with Apple Mice. When Apple release a new mouse I always ‘love’ the idea of them but using them has always left me ‘hating’ myself for yet again wasting my money on a sub-standard device and proclaiming ‘why oh why can’t Apple get it right!’

Apple have not fared well with mouses, meeces, mice over the years and who can forget the absolute atrocity that was the first generation iMac mouse … my god that thing stunk! If you weren’t adjusting the thing in your hand to get it to point in the right direction you were treating the unbearable RSI that had developed in your arm within the first 10 seconds of using it.

It’s this point that is my main gripe with Apple Mice. I’ve suffered from RSI over the many years of pixel-pushing I’ve put in and the only way to use a mouse painlessly is to minimise as much as possible the movement required to get your pointer from one corner of the screen to the other. For this reason I’ve always used rather expensive high-resolution mice that I can crank up to a super-fast speed. Mac mice have never been able to match the speed I require so my wrist hardly ever has to lift off the desktop. For anyone suffering from RSI this is my top tip … go into your mouse settings and crank that speed up as fast as it will go. If you have trouble adjusting do it very gradually over a period of a few weeks but aim for the top speed that will result in micro movements of the hand with no need to lift your wrist. You may also need to purchase an expensive mouse with a high-resolution … something with lasers and shit. You might also want to stick to a WIRED solution … yes, forget the wireless option if you need very fine control. I’ve tried Bluetooth mice in the past and they are way to erratic to provide the sensitivity you need.

Which brings me to my MacBook and the fact that I’m actually spending more of my time on the trackpad that I am with a mouse and I don’t mind at all. Multi-touch on my MacBook is like a breath of fresh air and has totally revolutionised the way I use my Mac. In fact I wish I could do more with it. I love the two-finger scrolls and the pinches and stuff but I want to change spaces with swipes for instance or select text with pinches. With this in mind you can understand why I’ve been quite excited (and skeptical) about the release of Apple’s new Magic Mouse. This mouse promises to incorporate some of the great new features of multi-touch into the shell of a mouse without any buttons. Will the multi-touch be programmable and allow me to use the swipe gestures to swap between spaces? Will the sensitivity and speed of the mouse be improved? Will the swiping on the mouse cause RSI as you try to hold the mouse in position while also swiping? Will it run on my Mac running Snow Leopard without a firmware update? If it requires the firmware update is that going to kill my Mac? Hmmm … questions indeed.

Well, it’s just arrived so here are the answers …

So, there you go. Firstly I’m quite disappointed about the left & right click being a normal ‘clicky’ click instead of a ‘tappy’ click … do you know what I mean? I was expecting to be able to just gently touch to the left or right over the mouse surface to get a click but this is not the case. You can click anywhere on the surface of the mouse however but it is an actual ‘click’ lazy fingers!

My other slight gripe is the swipe action. It’s really hard to do while holding the mouse as you’ll see in my video above. I guess time will tell if I find myself using it. I need to test it in PDF docs to see if I can mimic the three-finger swipe functionality on the trackpad for paging. I doubt this will work.

Another thing that you’ll find is now missing from your life is the middle-button on your mouse. It’s now completely gone. I had this setup as a cool shortcut for ‘spaces’ so I could quickly manage my desktop. I’ve found a way around this however and here’s a screencast explaining what I did:

Overall though, a nice mouse that fits nicely in your hand, the speed has improved and the tracking seems nice and smooth. Not quite the amazing technology I was expecting but hey, what do you want?!

A Reg review : http://www.reghardware.co.uk/2009/10/23/review_accessories_apple_mighty_mouse/

Check out the guts of the new Magic Mouse : http://www.reghardware.co.uk/2009/10/22/ifixit_magic_mouse/

And here’s a history of the Apple Mouse : http://vectronicsappleworld.com/macintosh/mouse.html

UPDATE: There’s a third-party utility that will give you loads of extra gestures and control over your Magic Mouse … including the elusive tap-click and middle mouse button click. I’ve tried it out and actually I think the tap-click is a bit fiddly on the mouse. It’s fine on the trackpad where you have the entire area to tap onto but on the mouse you have to be specific about where you tap and 50% of the time your taps don’t register. Maybe Apple will get this right later on. We’ll see. Try out the software for yourself for free for 10 days here.

Introducing Slider – the new Flex Mobile Framework

Actionscript, Apple, Flash, Flex, iPhone 4 Comments »

So the big news from the Adobe MAX conference yesterday was the announcement that Flash Player 10.1 will allow Flash Platform developers to create content for a range of other devices including Mobile, NetBooks and Set-top boxes. The new player will include some new multi-touch events to take advantage of this capability on Mobile, MacBook’s and Windows 7 touch-enabled devices. I’ll be looking at these events myself when they release the updated SDK and player and will be sure to post some examples and experiments.

Bigger news came in the form of a spoof ‘MythBusters’ video exploring the ‘myth’ that you can’t produce Flash content for the iPhone. Yes, Adobe will be compiling native iPhone content directly from Flash CS5. There’s no Flash plugin in the browser on the iPhone but the new FP10.1 touch events will work apparently. The compiler technology is way over my head but here’s the press release and some information on labs. It seems that Adobe have snuck a few iPhone apps onto the store in advance and the example I’ve played with, Chroma Circuit, performed very well (and is really addictive).

This got me thinking about the future for apps on the iPhone if Flash peeps all rush off trying to submit their content to the store. For a start Apple are going to be struggling to keep on top of their approval process. Apple is very strict when it comes to the Human Interface Guidelines (HIG) and the iPhone Dev kit that most devs use to generate UI elements on the iPhone ensure that developers ‘toe the line’ and by and large result in a design consistency that has been part of their success with the device. Now, I know there are already a lot of god awful apps on the iPhone that seem to deviate from the HIG exceedingly but it isn’t just the appearance of an app that is the issue here. Developing apps for the iPhone is a tricky, slippery business. Memory management and proper garbage collection is vital to the performance of the app and without thorough testing and a decent authoring/debugging environment like XCode it’s going to be very difficult indeed to create a decent iPhone app in Flash. So how will we develop decent apps for the iPhone or any of the other devices for that matter?

Well, while everyone was tweeting about the iPhone news I found myself reading through the Mobile dev FAQ’s and noticed this …

Can I use the Flex Framework to create content for the iPhone?

While it is possible to create iPhone content using the desktop Flex Framework, we do not recommend it. The Flex framework is currently optimized for execution in a desktop environment. The performance, UI, and interaction models have not been optimized for mobile devices.

Adobe is working on a mobile Flex Framework, which should be better suited for iPhone development.

What? That last line got me very excited. And then I saw the link.

And here’s a sneak preview!

Flex for mobile devices

Here’s the app they built running on an iPhone :
Flex Mobile Framework

Interesting bit of trivia is that the codename ‘Slider’ is a joke based on a conversation in which the original Flex framework was compared with a nice juicy burger for developers and so the mobile framework would be a smaller burger … a ‘slider’. As a brit … I don’t get it.

So, there’ll be a new lightweight Flex framework that will allow us to produce UI elements and advanced layouts for mobile devices and this framework is currently codenamed ‘Slider’. Now, personally the iPhone thing could be painful but lets not forget about all of the other devices that we can now develop for. A project will need to change state dynamically to fit within a range of screen sizes, layout will be extremely important as people expect their content to adjust to different orientations and the implementation of themes is also going to be huge. The Flex framework is perfect for this type of development and the Spark/FXG partnership is lightweight and flexible.

Reading the FAQ I noticed this …

On what platforms will Slider run?
The initial Slider framework will be optimized to run on high-end smartphones (phones with a processor speed of 400Mhz or more, 128MB of RAM), and will initially target standalone application environments such as Adobe AIR. This matches the category of devices targeted by Flash Player 10.

Reading between the lines here but does this suggest that the AIR runtime will also be available on devices?

UPDATE: This video on Adobe TV talks about how the process of developing the iPhone app is very similar to building an AIR app. So I guess there wont be an AIR runtime for mobile devices.

Building Mobile Applications with Adobe AIR

Some interesting information in that video. Hardware acceleration will be supported via the use of the cacheAsSurface property.

Ted Patrick has a great post on developing iPhone apps with CS5 including source. Check it out.

Here’s a real good cast of the Secret Session from yesterday with Richard Galvan which explores a bit more about the new features of Flash Pro CS5 including the Text framework and support for ligatures and flow.

They’ve added integration between the Flash IDE and Flash Builder so you can launch FB4 from the Flash IDE and setup workflows between the two environments including launching Flash pro to test from FB. This is going to be great for managing assets in Flash while coding in Flash Builder. Code snippets in Flash Pro let non-coders add interactivity too. This will allow large agencies with teams to have their tech dude add all the common code the designers need to build banners for example. Code completion in Flash mimics FB too … finally!

I’m expecting more news today in the second keynote and will update this post. If you are at MAX and see any demos of the Slider framework then please leave me a comment and let me know what you saw and heard.

Handy unassigned Keyboard shortcuts for Eclipse

Actionscript, Apple, Design, Flex No Comments »

I’m getting quite into my keyboard shortcuts in Eclipse now and can honestly say that with a bit of effort and perseverance they are well worth taking the time to learn. There are two that aren’t assigned that are very handy to set up should you be inclined. They are the Shift Left & Shift Right commands for indenting your code. At the moment I can write, duplicate, delete & select lines of code with my keyboard but when it comes to indenting the selections I always have to reach out for the mouse. Today I decided enough was enough and I decided to assign these commands to some keys.

Go to the preferences panel in Eclipse and under General / Keys you’ll find a handy editor for assigning keyboard combination’s to common Eclipse commands for all of the perspectives you have loaded. Find the Shift Left & Right commands within the Edit category and then assign them to whatever you want. I have chosen alt-cmd-LEFT or alt-cmd-RIGHT combo as this will work nicely when I’m using alt-up or down to move lines of code around.

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in