In your contract, specify a per-hour rate and keep track of your time. When you give your client the price, specify that this is an estimate and the actual result may be less or more.
Keep the client up to date on the progress, and when he inevitably makes suggestions, you can simply tell him the time it will take you (if change is outside original specifications) and he can decide whether the change is worth the money. Therefore only changes important to him will be added.
I would personally cover acceptable vs unacceptable (paid support vs free support) bugs in the contract, and that way you at least have something in writing from the get go. He will undoubtedly wonder why you should need that clause, so be upfront and explain that if a new OS update comes out that breaks something, that isn't free support. However, bugs in your code according to the original specification on the specified platforms would be covered.
However, I should mention I have only done freelance IT work rather than programming. This could possibly scare off clients, but just make sure your work sells itself, be more professional, outgoing, and helpful than the rest, and be forthcoming with your reasons for having a more strict contract.
Besides, a client who won't accept that clause is most likely a bad client.