Tag Archives: Software Development

Remote working and management


My Office

My Office

Working as a freelancer, I have to deal with many remote works, including working remotely with my customer, my colleagues and my employees and it certainly has some different difficulties from other sitting together jobs. Here are lessons that I have been learning from these jobs:

Communication
Our good tool for communication is skype, IM and teamviewer. We try to keep a good and frequent communication with clients before our approach is too far from what they expect, or in case they want to change their requirement frequently.

As other oursourcing jobs, it is normal that we have to wake up early or sleep lately to match clients’ time as well as developers’time. Communication requires lots of patient and understanding from both sides. Many clients told me that they never meet a software developer like me, who can sit down, listen and talk with them about what they need, how to improve their app’s qualities. I am happy with this commendation. Sometimes, I even do not need to ask for bonus, but they are generous to give me more bonus to reward my efforts working for them.

Trust
Remote management requires trust on your employee. I am never a fan of a strict manager. My strategy is to manage adult, not manage children; therefore, we have to trust them working hard and passionate. We try to hire best developers that we can, and they should do their jobs automatically with integrity without any strict control from managers.

People may keep asking me how I manage my employees when I am in Australia, how to prevent them from cheating me. I do understand that with a loose management like this, it is hard to ensure 100% no cheating but whenever I hire a best developer with high motivation, they will just work on it themselves. An important part of managing is to foresee, to plan over the next few months to few years strategies not to just stand behind every developer to make sure they do not cheat. Trust and integrity are important.

This reminds me the time working at MultiNC, my first job. My boss was never in office, rarely asked us where the project was going on. What we, as developers do, is to try our best to create a best application based on the strategy that we set up. We frequently brought the products to the manager and asked for feedback.

Self-motivation
Trust will relate to self-motivation. You can only motivate yourself when you know that your managers trust you and you feel happy and freedom about your work. I would not be surprised when many developers feel bad about their jobs and think that they just do low level jobs. Because managers treat them as resources, give them low level jobs and never trust them in doing their jobs best. Money is not enough to motivate people. For me, people are motivated by giving them enough money, enough challenge and enough respect to do what they love doing.

My book: Community and Opportunities


My iPhone Book

My iPhone Book

I am happy to announce that I encountered a book contract with Apress to write about iphone development. This will be a great opportunity and new experience for me when I have never written a real book before.

That is just part of the main content of this blog, I want to share my own thought over community support (as I already said at this blog post about Community Support) and how it would help me to reach this kind of opportunities. An Apress staff contacted me after he read my blog series about iphone development. This helps me to restate again that if you do good thing for other people, chance will come back. Real chance, real value, not an artificial reputation.

Supporting community and make lives better is my personal long-term goal as well as my company’s long-term goal.

 

Advertising:

Visit vworker to hire best employees

Freelancer Lessons and Strategies

freelancer jobs

freelancer jobs

As my plan in Adelaide, I want to get some job to earn money as well as keep me up to date with industry technologies. However, this turns out to be much harder than I believe when Adelaide is such a small city that does not have many IT companies here.
Then, I started my second option in my plan to looking for freelancer jobs and going to websites that offer freelancer jobs to see what I can get from there, and things are growing up fast enough and I learnt some key lessons over the my new job.

 

Price

Price was my first concern over deals and bid to get accepted a project. However, I can see that most of times, price is not the top priority for employers. What they care is they can have a high quality product in a short amount of time with a reasonable price. My strategy is to pick a fixed hourly rate for myself when competing and then just calculating over the number of hours I need to work and give them a general price.
I try to convince people about quality, in many terms: communication and product. I think it is true for any work with clients to try to exceed their expectations, try to understand their problems well and do exactly what solves their problems. The price can be higher but we can save time, money and make people feel safe, they would hire us. So, don’t aim for only price. Put one that is reasonable and prove clients that it is worth every penny

Outsourcing

This is always a way to cut down the business cost. People hire me because they want to look for more reasonable price with the same quality. And I can make another step to outsource them back to Vietnam developers. It cut down the price for me and the client and I can save my time to more important jobs, such as studying in my university :) (Supposed to be the most important one)

There are certainly more aspects about management when you have to do outsource and communication with customers when both of these are remote only. I don’t forget about technology lessons that I learnt and expect to learn and work over these freelancer works. These will be shared on the next entry.

References:

Image source: http://freelancejobfeed.blogspot.com/

Windows Phone 7 v.s iPhone Presentation in Barcampsaigon

Windows Phone 7 and iPhone Presentation

Windows Phone 7 and iPhone Presentation

Here is my presentation with Nghia Dang on the topic comparing the differences between Windows Phone 7 and iPhone Development. I share it here for others who cannot come. Contact me (vodkhang@gmail.com) or Nghia (nghiadang@kms-technology.com) if you have any questions:

Kms-Technology

iPhone Code Generation – Property

This is my new generation script, mainly copied from here with some improvements to meet my needs:

XCode Code Generation

XCode Code Generation

- Change the dealloc to [self.variable release] instead of [self.variable dealloc];

- Change the @outlet variable to check for the “UI” prefix rather than letting it put IBOutlet everywhere or I have to use 2 scripts at the same time.
- Add some of my own into the assign list

The second one is not a perfect solution for IBOutlet but considering that it doesn’t harm much except let some annoying IBOutlet out.

iPhone Http Server – Bug Fix

Recently, I encountered a serious bug in Cocoa Http Server (for iPhone) that took me and my colleagues time to fix it. However, it turned out to be a simple, easy to fix bug.

If you use the sample code (e.g iPhoneHttpServer3.zip) in the google site, you will sooner or later, recognize a bug that if you upload a file B if file A is still uploaded, you get a crash. Another crash case is that you request to a page, turn off the server and turn it on again, and then upload a file into the server, you get a crash.

What’s going on? Why does this server not behave like any other web servers we know? Generally, the bug is due to the fact that some variables are not init in the correct place. The server assumes that whenever you send it a get request, it will init the data for handling the POST request, which is not always correct. Here is the way you can fix it. Or you can just redownload the whole sample code for CocoaHttpServer for iPhone here
In file HTTPConnection.h

@interface HTTPConnection : NSObject

{

// vodkhang

// Added properties

NSInteger dataStartIndex;

NSMutableArray *multipartData;

BOOL postHeaderOK;

}

// vodkhang

// Added methods

- (BOOL)supportsPOST:(NSString *)path withSize:(UInt64)contentLength;

@end

In file HTTPConnection.m

@implementation HTTPConnection : NSObject

/**

* This method is called after the socket has successfully read data from the stream.

* Remember that this method will only be called after the socket reaches a CRLF, or after it's read the proper length.

**/

-        (void)onSocket:(AsyncSocket *)sock didReadData:(NSData*)data withTag:(long)tag {

. . .

// Find some places look like this

if(expectsUpload)

{

// Reset the total amount of data received for the upload

requestContentLengthReceived = 0;

// Prepare for the upload

[self prepareForBodyWithSize:requestContentLength];

// Start reading the request body

uint bytesToRead = requestContentLength <

POST_CHUNKSIZE ? requestContentLength : POST_CHUNKSIZE;

[asyncSocket readDataToLength:bytesToRead

withTimeout:READ_TIMEOUT tag:HTTP_REQUEST_BODY];

// vodkhang

 // Add this line in

[self supportsPOST:@""  withSize:0];

}

else

{

// Now we need to reply to the request

[self replyToHTTPRequest];

}

}

// vodkhang

// Add this method:

/**

* Returns whether or not the server will accept POSTs.

* That is, whether the server will accept uploaded data for the given URI.

**/

- (BOOL)supportsPOST:(NSString *)path withSize:(UInt64)contentLength

{

//     NSLog(@"POST:%@", path);

dataStartIndex = 0;

multipartData = [[NSMutableArray alloc] init];

postHeaderOK = FALSE;

return YES;

}

@end

In file MyHTTPConnection.h

//  Remove properties dataStartIndex, multipartData and postHeaderOK
// Remove method `supportsPOST:(NSString *)path withSize:(UInt64)contentLength;`

In file MyHTTPConnection.m

// Remove method

- (BOOL)supportsPOST:(NSString *)path withSize:(UInt64)contentLength;

I hope it works well. If you have any problem, feel free to contact me at : vodkhang@gmail.com

iPhone App Performance Optimization

iphone performance

iPhone Performance Benchmark

Working in a power limited environment like mobile, and especially, iPhone here, we soon have to face with performance problem in many different kinds. Different than the web model where web front end (javascript) do some (usually not much) processing – also browsers support you a lot, iPhone native application usually has to do quite a lot of processing.

Image Source

For iPhone native app, you cannot add any hardware to help you to have better performance. The only way you can try to deal is to deal with the software code itself. I will list some few problems and solutions that I figure out these days when I really focus on optimization. The list is applicable somehow to other mobile areas like Android or limited environment like embedded device

1/ Benchmark

It is a really traditional advice, but you always have to remember to benchmark your code, even by using simple tools like NSLog or Instrument tool. You should only care about places that is slow in terms of your test rather than trying guess and error possible places.

2/ Test on iPhone device

This is another traditional advice but people usually forget. You have to test on the real iPhone device. Let me give you an example: on my iPhone simulator, a method runs within 1 second, but in my iPhone device, it takes 8 seconds, a huge difference.

So, when you test your app on the iPhone device, don’t just test for UI, memory or features that the simulator doesn’t have. Remember testing the performance as well.

3/ Multithreading and the main thread

Some people may come to you and tell you that iPhone device just has 1 core and you never need to care about multithreading. It is just WRONG.  You still need to do a lot of multithreading to reach a better level of performance.

The main thread will do the user touch event handler and view rendering. Then, if you use the main thread for some calculation that takes a lot of time then your UI just become frozen or not smooth when you scroll.

For UI like UITableView where users scroll between many cells, the runtime will run a loop over visible cells and set the contents. Because this process runs in a row not concurrently, and it will not allow you to view or scroll the UITableView until it returns all cells, you can possibly let some of the cell content run on another thread. (more about performance on UITableViewCell part).

The other reasons for using thread are well-known, heavy IO and network processing, all of them block processing and you need thread so that your main thread is not block. This will help to make users feel your app run with higher performance

But, be CAREFUL, Multithreading comes with its own disadvantages. For rendering the view, you should do it on the main thread or somtimes, your app will just crash randomly. Another traditional reason is that the CPU has to switch too much between threads and it takes more time than usual to finish a task

4/ Use Memory wisely

Some questions on stackoverflow that I sometimes see shows a scare feeling about memory. It is right that iPhone has limited memory but it doesn’t necessarily mean that you should use it as least as you can. Memory and Performance is always a trade-off problem, you must use it smartly

The right mind you need to keep is using that limited memory smartly. We all know the priority of speed is Memory > File and Local IO > Network, the fastest access is always using memory cache for the data. There are some problems for memory caching in iPhone:

    – You have to respond to 1 method in every UIViewController:  (void)didReceiveMemoryWarning. In this method, you have to smartly release some memory cache of data to reduce your memory usage.- Know what/when to cache something in memory. There are lots of Caching algorithms outside from simplest ones like: Random Replacement, Least Recently Used, Most Recently Used. It is also an issue of caching big images or caching lots of small images. It all depends on your app. For my app, my main view contains lots of thumbnail images that need displaying fast and the user can wait for seeing big images. So, we cache a lot of images (60-100) for just 2 MB of memory. Knowing how to balance memory usage and good performance will help you a lot

5/ Algorithms and Data Structure

For my case, I didn’t really need to solve big performance issue with Algorithm and Data Structure, but in a limited environment, a small mistake may lead to a big deal and hard to detect. My case was that I need to merge 2 data arrays from the network using some unique characteristics of elements.

The app works really well in the Simulator for about 50-100 for each array (less than 0.5 second) . However, when I tested on the device, the time surprised  me, 8 seconds (16 times slower). It cost me 1 hour to detect that I use 2 for loops through 2 arrays which means O(n2), and then, I changed it to a dictionary which reduced the algorithm to O(n) and took me back to 1 second. Phew! Finally, performance is up now

What I learnt here is that even we don’t ever need to deal with Massive Data, we still need to be careful about some algorithm and data structure. 50 elements are nothing in a desktop or server scale but can cause a huge issue on limited environments in iPhone. Another lesson is a remind for me that I should always test on the real device to get the real performance

6/ Reuse UITableViewCell to improve Scrolling Performance

This part is quite unique for iPhone but may be good for other people to learn. In iPhone, we have a concept of UITableView for displaying a list and a table can contain a lot of cell.

The problem is that rendering the Cell (or generally the UIView), takes lots of time and can cause the app to look like stuck when it is scrolling. Usually, if you use the default UITableViewController template, the template already gives you the code for reusing the UITableViewCell.

The only problem is when you create a custom UITableViewCell using some usual tutorials like this and this (especially using Interface Builder), they forget to tell you that setting a CellIdentifer in the UITableView is not enough to reuse a cell. What you need to do is to set it in InterfaceBuilder or write a method to return it. I know that many people will forget it and think that they still reuse the cell, but they don’t. I suffer the same problem until I did benchmark and found the problem recently.

Here are 2 good techniques:

Copied from Stackoverflow, this question:

1st way: Just implement a method with the appropriate method signature:

- (NSString *) reuseIdentifier {
  return @"myIdentifier";
}

2nd way:

How to Reuse a Cell in Interface Builder

Cell Reuse in IB

References:

1/ Web Caching, wikipedia

2/ Web Caching, Stanley Luong’s course material

3/ Stackoverflow – reuseable Cell

4/ Stackoverflow – custom UITableViewCell

Become Master of Xcode

 

Master of XCode

Xcode Master

For iPhone development guys (and Mac as well), we all want to be as productive as possible. And one of our important tools is Xcode. I can even say that if we can master of Xcode, we can double our productivity. The reason is not only the time that the tool can save us but the number of times it breaks our workflow, or make us become bored/tired of our jobs. We are all humans, and no human in the world wants to do the job that a machine can do. Ok, stop talking and I will show you my summary of tips/tricks and techniques that I feel very very useful for me.

Many of these tips is from this stackoverflow post (I just list what I feel is most productive), 2 famous videos called “Becoming productive in XCode”, and a famous cheat sheet that almost all of us know “Complete Xcode Keyboard Shortcut List

I also recommend you to go there and take a look because this post may be really personal and lack excellent tips that you want.

1/ Basic Hot Keys

File Cursor Movement

  • Header/Source File Switching: Option + Command + Up Arrow
  • Last cursor point switch back and forward: Option + Command + Left (Right) Arrow


Quick Help/Documentation

  • Jump to Definition of a symbol : Command + Double-Click on a symbol
  • Find Text in Documentation of a symbol: Option + Double-Click on a symbol: (Only works if you have they symbol’s Doc Set installed.)


Auto Complete

  • (previous) next auto-completion argument : (Shift) + Control + /
  • Auto completion pop-up list : Escape or Control + comma
  • (previous) next Auto completion choices movement: (Shift) + Control + period


Text Movement:

  • Cursor movement between words : Option + Left (Right) Arrow
  • Cursor movement camel-cased parts of a word: Control + Left (Right) Arrow
  • Beginning or end of line: Command + Left (Right) Arrow


Interface Builder:

  • Jump to class in Xcode : Command + Double-click on an object in Interface Builder’s
  • Drag a customized object back to Interface Builder’s Library for later reuse.
  • Object overlap, see object menu under mouse: Control + Shift + Click on an object :


Code Organizing:

  • Bold line in the function list: #pragma mark Foo
  • Auto complete the pragma: pm or #p
  • Notation convention: // TODO: or // FixMe
  • Commenting a line: Command + /


2/ Advanced Hot Keys

With advanced hot keys, you will rarely need to use the mouse. Because, everything you need to do with the mouse, you can do it with the hot keys.

  • Open File Quickly : Command + Shift + D and don’t forget that open quickly uses the current word as a search term.
  • Popup list of methods and symbols in the current file : Control + 2
  • Look up current symbol:  Control + Command + ?
  • Editor area to full screen : Command + Shift + E
  • Debug and Editor Mode switch in All-In-One XCode mode : Command + Shift + B


3/ Some useful scripting

I will tell you more about scripting in the next part, but currently, I think this list is basic enough:

Default Auto Completion list, show when you type

defaults write com.apple.Xcode XCCodeSenseAutoSuggestionStyle List

Turn Off Undo Warning

defaults write com.apple.Xcode XCShowUndoPastSaveWarning NO

Hope that now you can code iPhone app much faster with XCode

Git auto and tips (windows + OS X)

Git auto and configuration

Git Configuration Tips

1/ Configure git with your identity and colors:
To make some identity and colors change, type this line in Terminal:
vi ~/.gitconfig
Then enter (put your name instead of mine)
[user]
name = Khang Vo
email = vodkhang@gmail.com
[color]
ui = auto
2/ Git alias
You can also define some git aliases for the shell command line by doing vi ~/.gitconfig
Enter these lines (these aliases are just my suggestions — you can change it if you want, but here is my preference)
[alias] st = status ca = commit -am br = branch co = checkout lg = log -p au = add -u l = pull s = push
Reference:
https://git.wiki.kernel.org/index.php/Aliases

3/ Bash shell auto-completion

In Windows, auto completion is by default, in Mac OS, you have to manuall set it up to have auto completion. These steps will help you to have an auto complete git on your MAC machine. It also display the current branch when you are in a git repository.

cd /tmp
git clone git://git.kernel.org/pub/scm/git/git.git
cd git git checkout v`git --version | awk '{print $3}'` cp contrib/completion/git-completion.bash ~/.git-completion.bash cd ~ rm -rf /tmp/git echo -e "source ~/.git-completion.bash" >> .profile
vim .profile
Put the following line
PS1='u@h:W$(__git_ps1 " (%s)")$ '

Then restart your terminal

4/ Pull/Push auto-completion

By default, the git pull auto complete will contact with server. If you want to make auto-complete always complete using local branch names, then you can change the behavior.
This might only be useful if your local branch names are identical to remote branch names.

Edit the file
~/.git-completion.bash and around line 458, look for this code:

fetch)
if [ $lhs = 1 ]; then

        __gitcomp "$(__git_refs2 "$remote")" "$pfx" "$cur"
    else
        __gitcomp "$(__git_refs)" "$pfx" "$cur"
    fi
    ;;
pull)
    if [ $lhs = 1 ]; then
        __gitcomp "$(__git_refs "$remote")" "$pfx" "$cur"
    else
        __gitcomp "$(__git_refs)" "$pfx" "$cur"
    fi
    ;;
push)
    if [ $lhs = 1 ]; then
        __gitcomp "$(__git_refs)" "$pfx" "$cur"
    else
        __gitcomp "$(__git_refs "$remote")" "$pfx" "$cur"
    fi
    ;;
esac

…and change it to this:

fetch)

    if [ $lhs = 1 ]; then
        __gitcomp "$(__git_refs)" "$pfx" "$cur"
    else
        __gitcomp "$(__git_refs "$remote")" "$pfx" "$cur"
    fi
    ;;
pull)
    if [ $lhs = 1 ]; then
        __gitcomp "$(__git_refs)" "$pfx" "$cur"
    else
        __gitcomp "$(__git_refs "$remote")" "$pfx" "$cur"
    fi
    ;;
push)
    if [ $lhs = 1 ]; then
        __gitcomp "$(__git_refs)" "$pfx" "$cur"
    else
        __gitcomp "$(__git_refs "$remote")" "$pfx" "$cur"
    fi
    ;;
esac

(Notice that we changed the “fetch” and “pull” sections to use the same logic as “push”. This means it will be looking for local branch names instead of remote branches.)

Reference: http://superuser.com/questions/137689/git-pull-auto-complete-osx

http://blog.recursivity.com/post/834210510/there-is-something-rotten-in-the-state-of-computer

iPhone development tools

Working with Iphone development is working with OSX, and we always need good tools and software for both IPhone and OSX environment to boost our productivity and reducing the repetitive, boring jobs

1/ Multitouch, Accelerometer and more : ISimulate

An application allows you to use your real iphone to control the IPhone Simulator. There is nothing better than the real IPhone device to get the real user feeling. The reason is that it will save a lot of time for you when you only build on simulator, debugging on simulator and you have a wide screen to see.

2/ Memory static analyzer : Clang

Help you a lot in the managed memory environment of iphone development. Good news is that the new XCode (3.2) will integrate directly with Clang help you to analyze and find memory leak much faster.

3/ Google tool box for Mac

You cannot write a good iphone app development without writing good unit testing. And I suggest you to use Google toolbox for Mac with a lot of supports, easy to integrate into your project. It is better than the default OCUnit in XCode. It also really runs your code, which takes more time, but gives you a real, better result and can help you to deal with some File IO or real code you need to run when running unit test.

4/ UI Automation Test: XCode Instrument

Stop running the UI everytime you fix a bug or adding new feature. UI Automation Instrument is a best tool for you like robot proxy in web testing.

5/ Screen capture software: Jing

Good, free software with high quality captured video. Good use for demo.

Catupre Screen Software

6/ Chat client: Adium or Imo

Why do I put a chat client here? Everybody need some way of communication, especially if some of your co-workers or clients are not there. In Mac, you can use Adium to integrate a lot of chatting services like Gmail, yahoo…