Monday, December 27, 2010

Tips for starting a consulting business as a professional in the computing field

I came across this interesting article, covering some essential points for people thinking of jumping into the consulting fray.

Monday, October 04, 2010

how to fix framework names being displayed in red in Xcode

Sometimes you'll find that the framework names in some of your Xcode projects show up in red. This happens in versions as new as 3.2.4, it may be fixed in future versions. I wasn't able to find a definitive reason of why that happens, some people were suggesting that Xcode was not able to find those frameworks, but if that were the case, my project should have never built, and I had no issues building.

I think it's more likely a bug in Xcode, which stems from the fact that you can change the build settings, namely the base SDK, from multiple places.

One way is to select the current target from the "Groups & Files" pane, and do a File->Get Info, then select the "Build" tab, then pick the configuration you want to change, from the "Configuration:" list.

Another way is to go to Project->Edit Project Settings, then select the "Build" tab and do the same as above.

Yet another way to change the base SDK is to go to Project->Edit Project Settings, then select the "General" tab, then at the bottom of the screen there is a "Base SDK for All Configurations".

The bottom line is that you should make sure you have the proper base SDK set in all 3 places, for all configurations of interest. In my case I had a "missing SDK" on the third place, and that was painting the frameworks name in red, evan as the project would build fine.

Friday, October 01, 2010

Apple's in-app purchase pitfalls

I've been working on my first project for an iPhone app that uses in-app purchasing capabilities. In the process I encountered and fell through quite a few pitfalls. This is my attempt to document my ordeal, and help those who are experiencing the same issues.

When trying to test with the sandboxed App Store I got errors like : "Cannot connect to iTunes Store", or "Invalid Product Id". Getting things working in that environment is quite tricky, and you need to follow exactly the steps that Apple expects. So in other words, RTFM. The problem is that you need to have the right manual. I had followed the instructions from a book, which turned out to be incomplete, out-of-date and in some cases flat out wrong. Your best bet is to read the latest docs coming straight from Apple, as this is their technology and is subject to change.

I found a fine doc that helped me tremendously at http://developer.apple.com/library/ios/#technotes/tn2009/tn2259.html. You may also check out the dev forums at http://devforums.apple.com, for any current issues with the sandbox, or good advice.

Turns out that the root cause of my issues was the fact that:

1. I didn't have all contracts and banking/tax details set up in my iTunes Connect account

2. I was using a provisioning profile tied to a wildcard app id, which is not supported for in-app purchase

I wish Apple's tools were able to catch such errors, or the error messages at run time were more explicitly pointing to the real issue.

Getting iTunes Connect find my bank was tricky too. They're trying to look up banks based on transit number. It turns out that's not what's commonly referred to as transit numbers in Canada (usually 5 digits). No, to that you need to prepend the bank number (3 digits in my case). Your best bet is to search for the bank name and location, just make sure to use the full name instead of the commonly used abbreviations made up of initials.

Saturday, September 18, 2010

how to handle "Timed out fetching data. Variable display may be inaccurate." in Xcode while running GDB

I've been getting this error message in the debugger console of Xcode, while trying to debug some iPhone apps. At the same time it appears that GDB is freezing, after hitting a breakpoint and trying to step through the code, with the app being debugged eating up the available CPU juice.

Even if my app were very buggy, this still wouldn't be a reason to hang GDB, so I was starting to suspect that it may be a GDB issue. I discovered that if I moved my breakpoints the problem would disappear.

For example in the screenshot below, if I set the breakpoint anywhere on the lines 30-34 the problem appears, if I set it to line 36 the problem goes away.


While I don't know the root cause of this, a workaround is to move your breakpoint past the trouble zone.

Thursday, August 05, 2010

how to fix The 'view' outlet of 'File's Owner' is connected to 'View' but 'view' is no longer defined on ...

I've been getting this warning lately, following adding a new view controller, with its companion NIB file to an iPhone OS project built with Xcode 3.2.3.

While this warning could be legitimate, if someone removed an outlet definition from the source files, without updating the NIB, in this case it happened without me making any change. So the project would compile and run properly, then I'd add this controller, build and get this error.

Turns out this is a bug in Xcode, and it happens when you build the project while the app is still running in the simulator. Just quit the app, build and the warning goes away.

Thursday, July 22, 2010

how to duplicate a project in Xcode

 These steps seem to work for me in Xcode 3.2:

1. In the Groups & Files pane, control-click on the project name (e.g. "ExampleProj") and choose the "Reveal in Finder" option.

2. Make a copy of that folder (e.g. "ExampleProj copy") and rename it to the name you desire for your duplicate project (e.g. "ExampleProjDuplicate").

3. Go inside the new folder and rename the .pch and .xcodeproj entries (e.g. rename "ExampleProj_Prefix.pch" to "ExampleProjDuplicate_Prefix.pch" and "ExampleProj.xcodeproj" to "ExampleProjDuplicate.xcodeproj".

4. The .xcodeproj is actually a folder, you can see its content in Finder by control-click it and choose "Show Package Content". You should see a project.pbxproj file in there.

5. Open the project.pbxproj file in a text editor and replace all old references to the .pch file to the new one that you renamed at step 3 (e.g. replace all "ExampleProj_Prefix.pch" to "ExampleProjDuplicate_Prefix.pch")

6. Load the new project file (e.g. "ExampleProjDuplicate") in XCode and choose the "Build"->"Clean all Targets". 

7. Done.

Sunday, July 18, 2010

how to run PHP in interactive mode

One way is to invoke the interpreter from command line like so:

php -a

That seemed to be acting up lately for me, especially in failing to display any output sent with echo.

So I was looking for an alternative replacement, which I found here, courtesy of Facebook. It has all functionality I need.

It depends on Python to be installed on your machine. Once installed you invoke it by simply typing phpsh at the command line.

Sunday, July 04, 2010

how to use your own domain name to point to Amazon S3 content

If you use S3 to store content viewable on the web, it may make sense to keep your options open, for a possible switch to a different provider later on, if need be, that wouldn't result in broken links.

To do that you need to control the URL of your content, the full URL, including the host name, hence its full domain. I've been looking for a solution to this problem and I found an excellent post.

The gist is to create a subdomain for your content, e.g. content.example.com and map that subdomain through a CNAME DNS record to the Amazon's S3 domain. The essential thing is to have the name of your S3 bucket containing your content match exactly the name of your subdomain, that is, your bucket name for our example should be "content.example.com".

The post above mentions adding a trailing dot at the end of Amazon's domain. I guess that's dependent on your domain management console. In my case I'm using Godaddy's tools and found that trailing dot not necessary.

Thursday, July 01, 2010

how to upload in bulk to Amazon S3

Recently I had to upload a folder containing many files (over 60000) to Amazon S3 storage service.


Amazon doesn't have a tool for this, and their APIs seem to support transferring only one file at the time. I was looking for a solution that wouldn't tie up my computer for a long duration while doing the transfer piecemeal. So I thought why not make a tarball with my files and transfer it in one fell swoop via ftp on a Linux box running as an instance of Amazon elastic computing cloud EC2. Then the plan was to run some scripts to unpack the thing and transfer the files fast between EC2 and S3 servers, through Amazon's internal network.


Assuming you already have a subscription to Amazon's services, and know your way around EC2, here are the steps to take (you may need to change the things in pink to match your needs) :


1. look for a suitable AMI to base your instance on:
ec2-describe-images -o self -o amazon | grep getting-started


2. pick and run an instance
ec2-run-instances ami-3c47a355 -k gsg-keypair


2.5 wait until your instance is running, check on its status with
ec2-describe-instances 


3. log in to the instance
ssh -i id_rsa-gsg-keypair root@ec2-184-73-124-245.compute-1.amazonaws.com


4. on the instance, look for and install ftp
yum list vsftpd
yum install vsftpd.i386

5. configure the ftp server (uncomment "#anon_upload_enable=YES") in
/etc/vsftpd/vsftpd.conf


6. start the ftp server
/etc/init.d/vsftpd start



7. prepare the destination for anonymous ftp (with total disregard for the security implications)

mkdir /var/ftp/pub/upload
chmod 777 /var/ftp/pub/upload



8. from your computer ftp the tarball to the server (ftp anonymous@ec2-184-73-124-245.compute-1.amazonaws.com/pub/upload)

9. after the ftp transfer completes, go back to the instance and unpack the tarball

10. install an awesome script from http://timkay.com/aws/
cd
curl timkay.com/aws/aws -o aws

11. configure the tool with your Amazon credentials, by creating/editing an .awssecret file and placing your Access Key ID on the first line, followed by your Secret Access Key on the second line

12. save the .awssecret file and set its permissions
chmod 600 .awssecret

13. install the tool
perl aws --install

14. give it a try, make a destination bucket to S3
s3mkdir tartordesign

15. go where your files are
cd /var/ftp/pub/upload

16. prepare an awk script to do the upload and, optionally, set the visibility of your files to public (I needed mine to be available on the web), edit a vi do.awk file with the following content:

{
printf "putting %s\n", $1
cmd = "aws put tartordesign/ " $1
system(cmd)
cmd = "aws put tartordesign/" $1 "?acl --set-acl=public-read"
system(cmd)
}

17. run the script that does the job
ls | grep .jpg | awk -f do.awk  -
note: sometime the piping construct above may fail because "ls | grep .jpg |" produces truncated names. A more robust approach is this:
ls | grep .jpg > list
awk -f do.awk list

18. go about your business until it's finished (you may choose to send the output of that script to a file and later check on the progress by tailing on that file, that way you may end your ssh connection established at step 3, so you're not tied up to anything, instead you reconnect only periodically to check the progress)

19. once the script is done terminate your running EC2 instance, the one you started at step 2
ec2-terminate-instances i-2b57bf41

That's it folks.

Friday, June 11, 2010

be mindful of possible glitches in Apple's Xcode tools

I really like Apple's development tools, including the SDK and frameworks, especially as a developer coming from different platforms for mobile development. Yet, nice as they are, they're still not infallible.

Today I was having issues running a project in the debug mode, in the emulator. In some instances the emulator would not recognize my touchy input. In other case, a UITextView, which although clearly marked as not editable in the IB, it would show me the text cursor. All these abnormal behaviours were sporadic, not always happening. And in both cases, launching the app directly from the springboard, in the emulator would cause it to work properly. It may be a debugger issue.

Also, for some reason the runtime would ignore some of my settings regarding some struts, springs and autoresizing for some elements as I specified them in IB, and would mess up the layout upon changing the orientation of the device. To fix that I had to manually enforce them in didRotateFromInterfaceOrientation:.

Thursday, May 27, 2010

How to fix: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'executeFetchRequest:error: A fetch request must have an entity.'

If you get this error in your code that uses Core Data, chances are you have a typo or are using wrong names for your entities when you're preparing your NSFetchRequest objects. That is, the names in your code (some of it which is autogenerated by Xcode) do not match the names in your model.

For instance, I was following some code snippets in the Pragmatic iPhone SDK book and I had somehow ended up with the following lines:


// Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];


Here the @"Event" name was wrong, as my .xcdatamodel file was actually using the name @"Track" for that entity. Changing that name in the code to match the model fixed the issue.

A similar naming mismatch was on this line:


NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];


The correct key for my model was @"name". There were other similar issues in the code.

One could argue that this is a shortcoming of the Xcode tool, as it fails to keep the names in the code generated by wizards in synch with changes in the model. As Core Data is a relatively new addition to the iPhone SDK, it's likely this will be improved in future versions.

Wednesday, May 19, 2010

free chapters from Dynamic HTML: The Definitive Reference, Third Edition

I've been using Danny Goodman's book as a reference material for my DHTML development work. Up until recently I had access to an HTML version of the book, provided by Safari. That format was pretty useful in looking up things, as they provided a hyperlinked index. Then they moved to a paper-like format which makes finding things much tougher. In the process they also dropped a few chapters. These chapters, unlike the bulk of the book, were not referenceware, but they were a very good coverage of the main topics in DHTML development. In fact, their coverage of events were the best I found in available literature. You can imagine my dismay when I discovered that exactly those chapters were dropped from this latest edition of the book.

The good thing though is that those chapters were made available online for free, as an online supplement reachable from the book's page in Oreilly's catalog.

memory leaks in open_handle_to_dylib_path and UIKeyboardInputManagerClassForInputMode

If you're developing an iPhone app that uses UITextField objects and you're rigorous enough to check for memory leaks using Instruments, chances are you'd discover some leaks in UIKit and CoreGraphics libraries, stemming from some allocations done in dyld::mkstringf, called from dyld::loadPhase5.

According to some reports found on the web, it seems that this is a bug in the tools from Apple, and it appears only on the simulator, not when testing on the actual device. So you could safely ignore it. In any case you couldn't do anything about it, as the traceback leading to the leak goes through code outside of your control, that is, unless you happen to work for Apple :).

Saturday, April 17, 2010

how to include PHP code in html files

As a scripting language, PHP offers the flexibility to be intermixed with HTML code, to enhance the functionality of web pages. To do this, you need to instruct the web server to pass the HTML pages trough the PHP interpreter, so that any snippets of code could get executed.

If you use Apache, one easy way to accomplish this is to use the .htaccess file in the folder of your app and add some clauses like this:

AddType application/x-httpd-php .html 
Addhandler x-httpd-php .html

You can place the .htaccess file in the parent folder that's closest to the html files containing PHP. Doing so will avoid any overhead in parsing files that wouldn't contain PHP code.

Wednesday, April 07, 2010

navigating the PayPal customer service maze

I use PayPal to process payments and implement the shopping cart on my website. Recently I got an order that went through with the sales tax incorrectly calculated. So I tried to contact them to find out the cause of this issue, as this would be having a major business impact if it continued on future transactions. 


My first attempt was via email, to which I got a reply saying that they have no access to my selling preferences, where the sales tax are set, so I should call a phone number to get better help. I called that number (long distance, no toll-free, FTW) jut to be placed on interminable holds and have suggested a ridiculous "solution", not applicable to the issue at hand. What pissed me off the most was the ease with which they brushed the whole thing aside, with no attempt to find the root cause of the problem.


I was pretty sure it was a bug on their side and what I needed was someone with some technical competence in investigating this. The good thing is that they have a developers' site, with a forum. Browsing through, I found a way to submit trouble tickets at https://www.paypal.com/mts. That's a very good way to reach the Merchant Technical Services. The nice thing was that within 5 minutes after my submission a reply came, apparently not automatic, acknowledging the issue and saying they are working on it. 

Wednesday, March 31, 2010

how to distribute trial (demo, beta) iPhone apps to your customers

This is more a note for myself, but in case other people are trying the same, here you can find some useful links.

After you enroll in the Developer Program offered by Apple, you get the chance to run your beta apps on real devices (iPhone, iPod, iPad). These can be your own development devices, used for testing, or can be devices owned by your customers, partners, etc. Apparently you can bypass the appstore and distribute your app to up to 100 different devices, through what's called "ad hoc distribution".

There seem to be quite a few resources on the web describing the process and any potential gotchas. One particularly useful link appears to be this.

Wednesday, March 17, 2010

be careful when deleting web content

Until recently, when I was updating the inventory for www.negustore.com I used to delete old product pages, that I wasn't carrying any longer. To be honest, I didn't realize I was doing that, instead I discovered it through analytics.

So here I was, yanking out pages that were already indexed by Google, and sending incoming traffic to my custom 404 handler. After the required head-smack I changed my code to keep the product pages and change the availability to "not available" and remove the add to cart button. That's the sensible thing to do. Lots of people may still be interested in the product specs, even if they are not on sales anymore. Better yet I could add some adsense pointing to places that sells them.

Interesting thought, it'd be nice if adsense would give us more control to what's included in each ad block, e.g. product for sale, instead of redundant product info, in my case.

I'm still wondering, how does removing of pages that were previously indexed affect the overall page rank of the site. Common sense it tells it can't be good. The last thing a search engine wants is to send people over to broken links.

Same thing goes for moving things around, if possible don't do it, if there's no choice, use 302 permanent redirects handlers that still listen to the old URLs until they are removed from the indexes.

is it worth pursuing search engine friendly URLs ?

As someone who's running a few e-commerce sites, I'm always on the look for ways to attract traffic to my sites. One of the best sources of traffic are search engines, and the key to attract traffic from them is to observe the best SEO, or search engine optimization, practices.

One of those practices widely touted was to use SEFU, or search engine friendly URLs. That means avoiding dynamic URLs, that contain a query segment with parameters (anything following the '?' sign, in the form 'name=value', maybe separated by '&') and instead use static URLs that contain targeted keywords, separated by '-'. There are many ways to translate a dynamic URL into a static one. I used url rewriting capabilities provides by the mod_rewrite module of Apache web server. Yet I'd been thinking, if it's so easy to make this translation, why would the search engines make such a big fuss about. After all, the content they get is the same, so it shouldn't make any difference.

Yet it makes all the difference in the world. You see, when you use a dynamic URL, usually with cryptic values as parameters, like product numbers, or session id, or whatever, you make no clear assertion about the content the URL is pointing too. That is, a subsequent fetching of the same URL may produce an entirely different content, since after all it's the result of a dynamic script, right ? The content may change based on internal state like the date or time, or based on the parameters passed. So understandably the search engines are reluctant to place too much weight on the content. Yes, you could use the title tag, or metadata to describe the content, but still, nothing guarantees that the mapping between the URL and the content will stay the same.

On the other hand, when you use a static URL, with embedded keywords, you add semantics to the URL, making its destination clear, giving it a sense of permanence. Now that's something that the search engines can bank on.

So I changed the product URLs on my www.greencirclestore.com site to be SEFU and the results were excellent. The amount of traffic from search engines doubled and the crawling activity kicked into high gear. All in all I'm pretty pleased with the results.

Thursday, February 25, 2010

"Unknown Error. Please reload the page." when using the File Manager part of Hosting Control Center from godaddy

I've been using the File Manager from godaddy to unzip some tarballs with updates to my web site. I had to rely on this somehow manual approach as any attempt to do the same programatically, through scripts launched by cron jobs would be cut short. That's because there seems to be a limit on how long a user-initiated process could run on godaddy.

In some cases I'd get an "Unknown Error message" after some unzipping finishes and I try to start a new one. That's presumably because the file manager tries to figure out all new files created as a result of unzipping. However beside showing that useless error message, for just a few seconds before hiding it (awful usability), the error condition seems to recover only after logging out and logging back in after at least 5 minutes.

I discovered one way to avoid the error in the first place. Don't start a new unzipping until the first one stops for good. When does that happen ? Not when the system tells you, but when you see that the checkbox for the archived being unzipped becomes unselected. Depending on the complexity of the archive, that may happen a few minutes after the unzipping finishes.

Tuesday, February 23, 2010

The "iron triangle" concept in Project Management

The PM literature refers to the triple constraint of scope, time and cost as the "iron triangle" to help visualize the interlocked dependencies between these constraints. Imagine a triangle made of iron, with each corner of the triangle corresponding to the scope, time and cost, respectively, while the iron core represents the quality of the result produced by a given project. If you try to stretch any corner, you're bound to break the quality at the core.

Im not sure I buy this metaphor. In my view both time and cost are resources, together with other, like people, skill-set, etc. Each of these have a bearing to the outcome of the project. You may be tackling an impossible problem, so whatever resources you throw at it you're still far from meeting the goals of the project, as defined by its scope. That is, until you come across the mix of resources that makes the impossible possible.

So sow about a silk string instead of the iron triangle ? At one end is the scope, at the other are the resources. The string itself is the quality. If you pull too hard at one end it's bound to break.

Saturday, February 20, 2010

Principles of defensive programming

I came about this topic while watching a course presentation. They mentioned that we should always validate the input provided by the user and the results returned by the code we didn't write (library calls).

Based on my experience I'd add using assertions to document and check for invariants within our code. Another use of assertions is when exposing an API to other parties. If there are preconditions that the calls to the API must satisfy, it's pretty effective to enforce them through assertions.

Another area to watch for is to always check the results (success status) of the function calls we make and act accordingly. Sometimes we tend to be too optimistic and assume that everything will work smoothly. This is somehow alleviated by the use of exceptions, which prevents continuing the processing under false assumptions, which usually yield unexpected results, hard to trace back to their root cause. Unless the exception is muted, that is, caught and ignored, (really bad practice) any problem surfaces quickly.

Tuesday, February 16, 2010

302 redirects and iframe

I was quite surprised to discover that the behavior of posting a form while targeting an iframe depends on whether the form handler performs an HTTP 302 redirect.

I have a web page, with an iframe embedded and a form that targets that iframe. If I post the form and the handler returns a normal 200 result, the iframe will end up with the content sent by the handler, while keeping the surrounding content intact. That's the behavior that I was intuitively expecting.

However if the form handler returns an 302 code, instructing the browser to do a redirect, the whole page gets redirected, so the iframe and surrounding content vanish, being replaced by whatever content is served by the redirection.

This is quite surprising to me, as I would have expected only the target iframe to be affected by the posting of the form. After all that's the semantic of the target, isn't it ? This odd behavior happens in both FireFox and Safari on Mac, so it may not be a bug, but by design. I'd be curious about the rationale behind this.

Monday, February 15, 2010

How to debug PHP scripts on your Mac

I use a MacBook as one of my development machines. For LAMP development I've been using the excellent setup provided by MAMP


Coming from a background in other languages that have readily available debuggers I've been longing for a debugger to help stepping through PHP code and inspecting the content of variables. I found out that some commercial IDEs come with such capabilities out-of the box, but I've been looking for a stand-alone solution, similar to GDB. I can highly recommend xdebug for that. 


Installing it on MAMP was a breeze, by following the excellent instructions from technosophos. The only changes from those instructions were that the latest versions of MAMP (I use version 1.8.4) come with an xdebug.so already present (i.e. /Applications/MAMP/bin/php5/lib/php/extensions/no-debug-non-zts-20060613/xdebug.so), so all you need is uncommenting the zend_extension entry in the php.ini. 


Coupled with the MacGDBp client, the xdebug provides exectly what I've been looking for. Just pay attention to the need to press the reset button in order to initiate a new debugging session when your web page loads.

Sunday, February 14, 2010

shoptoit sucks !

I've been using shoptoit.com for some PPC (pay-per-click) advertising campaigns for my online store, on and off, for some time. Although the ROI is pretty low, I've been thinking to start some new campaigns. 


It's quite amazing how poorly implemented that site is. For merchants they don't provide even such simple tools for updating the list of products they wish to be advertised, all at once, in batch mode. So if you have some products that are out-of date, you're out-of-luck. There's no apparent way to replace them, through a new feed. There's not even a way to delete a product listing, not even manually. Mind boggling. Hello, CRUD, anyone ?


Adding to this deplorable state, any requests to their customer service, via email, on 3 separate addresses, seem to fall on deaf ears. They're probably too busy spewing nonsense on social networks, as they appear to be overly active on twitter and facebook, instead of caring for paying customers. 


Given this, I can highly recommend avoiding them. I'll be trying to get my remaining balance that's in my account and move to better providers.