Wednesday, September 15, 2010

Thoughts on iPad Mini

There have been rumors swirling that Apple will release a new version of the iPad in time for the holidays. There have been other rumors that Apple will release an iPad in a smaller form-factor.

In general I subscribe to the philosophy that most rumor-mongers are full of shit.

However, I think these rumors do make sense, and I'll go into why exactly in a minute. But first, my guesses. Everyone likes to make guesses. Here's mine:

Apple will release an "iPad Mini" in November, running iOS 4.2, with a 6" screen at 1024x768 (213dpi), putting it's screen resolution and size on par with the Kindle 3. The smaller form factor (60% reduction in size) would lead to a lighter device. You've now eliminated 2 of the 3 advantages the Kindle has over iPad: higher resolution reading, lighter weight, leaving only one: viewing in direct sunlight.
Will Apple also re-design the screen to work better in sunlight (or at least eliminate the polarity issue that causes the screen to look completely off when wearing sunglasses)? Maybe. I doubt we'll see many advances along that line until next year's release. (I'm lumping "overheating" issues into that third Kindle advantage of viewing in direct sunlight, by the way.)

I think it goes without saying that any new release of iPad will come with a front-facing camera for FaceTime support.

How I came up with the precise specs for my guess above is by looking at what Apple did already with iPhone 4, and how they are trying to inflict minimal pain on iOS developers. iPhone 4 doubled the resolution and kept the screen size the same. This makes it fairly easy for iOS developers to adapt their applications -- double your graphics sizes, and you're done.

What would be even easier? If the resolution increased but the pixel count remained exactly the same. Then developers don't need to do anything! Obviously the screen size is going to have to come down if the resolution increases, which is no surprise if one of the goals is to compete against the Kindle form-factor at six inches diagonal. The 213 dpi I've posited is not "retina" level, per se, though it's still in the range of Kindle 3 DPI. And I think that's where this device is squarely aimed. (Alas, I was not able to find the actual Kindle 3 DPI documented anywhere officially, but it's said to be in the 200s.)

I've read rumors of a 7" iPad Mini, but I would be surprised if Apple went with that size, since it would mean a sub-200 DPI resolution at 183 DPI, and if you think about it, not a whole lot more than the resolution of the iPhone 3, which was 163 DPI. It also would not allow Apple to cut the weight as much as they can with a smaller screen.

Apple wants to have their iPad cake and eat Kindle's, too. What's that, you want a full-sized mobile computing device? Here's the iPad. Oh, you're mainly interested in reading, but wouldn't mind getting these hundreds of thousands of apps that Kindle doesn't offer? Here's iPad Mini.

Apple could release this product in November for the holidays, and developers would have to do nothing at all -- all of their software would run perfectly on this new device because nothing has changed in terms of the pixel count or aspect ratio.

Food for thought... Next Spring... will Apple release iPad 2 with a full retina display increase to ~326dpi, and a doubling of the pixels for the large form-factor (original) iPad line? If so, how long until Apple finally eliminates pixels entirely? Why are developers still using PNGs sprinkled with pixel fairy dust, rather than vector graphics? Will iOS 5 and Mac OS XI eliminate these relics once and for all?

Full disclosure: I am a long-term investor in both Apple and Amazon stock.

Monday, September 13, 2010

Geo::IP built for ActivePerl 5.12

You can find it here.

MSDeploy vs. xcopy network bandwidth throughput

MSDeploy (aka Microsoft Web Deploy) is great for syncing up all kinds of things between two machines. One issue I've noticed recently is, for whatever reason, it doesn't always do well at maxing out your network bandwidth.

We were recently syncing up large SQL Server backups between two boxes connected through a gigabit ethernet switch. I initially decided to use msdeploy.exe, because I wanted it to not only bring over the latest files, but delete the ones on the destination server that no longer exist on the source server. Using -verb=sync and an xml -source:manifest and -dest:manifest file, I ran the test sync from the destination server, and watched the network usage with task manager.

The average throughput was in the 5-15% range on our gigabit connection.

As a test, I ran xcopy /S /D for the same directory tree, and was getting over 90% throughput most of the time, often at 99% throughput!

Unfortunately, xcopy will not truly sync, it's only copying the files over. So now what we do in our .bat file is run the xcopy command first to copy over all the newest data at a high rate of speed, and then we call the same msdeploy command as before, and it deletes any files on destination not found on source. Since all the copying of new data has been done by xcopy, it finishes very quickly and now we're synced up.

I am aware of robocopy's ability to do a lot of this stuff, but it's clear that msdeploy is where Microsoft is putting it's eggs for a lot of the newer syncing technology, so we default to using that first, and now just augment with xcopy when pure throughput is needed.

If anyone knows why msdeploy is so much slower, please comment and I will update this article with any tips to gain performance. My guess is it's due to using the HTTP agent? It just seems weird, because I'm talking about copying of really huge files, so the slowdown is not with hash checking.

Monday, August 16, 2010

Notifying Major Search Engines with sitemap_gen.py

If you're using sitemaps on your website, you can notify the major search engines whenever your sitemap is updated. They usually offer a "ping" URL that you can hit. The ping URLs for the major search engines are below. You would substitute the full URL to your sitemap.xml (or .gz) file, encoded, wherever you see sitemap_url below. And read the note at the bottom of this post for more info on the YahooDemo appid used below:

  • http://www.google.com/webmasters/tools/ping?sitemap=sitemap_url

  • http://search.yahooapis.com/SiteExplorerService/V1/updateNotification?appid=YahooDemo&url=sitemap_url

  • http://www.bing.com/webmaster/ping.aspx?siteMap=sitemap_url

  • http://submissions.ask.com/ping?sitemap=sitemap_url


In addition, if you're using Google's sitemap_gen.py python script for generating your sitemap, they have a hash of tuples for each site you want to notify. Only Google's is included by default. Here is a version of the NOTIFICATION_SITES hash that has Google, Bing, Yahoo, and Ask.com:

NOTIFICATION_SITES = [
('http', 'www.google.com', 'webmasters/tools/ping', {}, '', 'sitemap'),
('http', 'search.yahooapis.com', 'SiteExplorerService/V1/updateNotification', {'appid' : 'YahooDemo'}, '', 'url'),
('http', 'submissions.ask.com', 'ping', {}, '', 'sitemap'),
('http', 'www.bing.com', 'webmaster/ping.aspx', {}, '', 'siteMap')
]


This should work as-is, but if the Yahoo one fails for you, or if you want to follow Yahoo's rules more closely, you should sign up for an official Yahoo Developer appid, and replace "YahooDemo" in the code above with your appid.

Friday, July 23, 2010

Session State not working even though you have enabled it?!

This was a doozie... I was working on a local dev box running Windows Vista and .NET 2.0. I pulled down another developer's web project that uses Session State variables, and when I went to test it, I received this error:

"System.Web.HttpException: Session state can only be used when enableSessionState is set to true, either in a configuration file or in the Page directive..."
I did some sleuthing, and find different recommendations:
  1. Add to your web.config file, within the area.
  2. Add to the same area.
  3. Make sure is in the httpModules area of your root level web.config file (some people said machine.config, not sure which, but I tried both).
  4. Add EnableSessionState="true" to the .aspx @Page directive.
Well, I tried all of these. Yet I still received this error. I opened up IIS Manager and looked at the root level of the site. There's even a configuration panel for "Session State," and "InProc" was already selected. EVERYTHING was turned on, why wasn't it working???

I just figured it out, although I have no idea how or why it was required:
  • In IIS Manager (in IIS7), go to the top level of the website in question.
  • Instead of clicking on the Session State panel, double-click the "Modules" area.
  • Scan that list and see if you have a module for Session State configured (I did not).
  • If not, click the Add Managed Module... button.
  • Type "Session" in the first box (no quotes).
  • In the second box, type "System.Web.SessionState.SessionStateModule" (no quotes)
  • Click the checkbox "invoke only requests to asp.net" (at least, that's what I did)
Now try your application again. If you're lucky like me, it just worked!

Saturday, May 1, 2010

Information on 3G iPad GPS and International Roaming

UPDATE: I am back from my trip in Italy, and everything worked great. I used only about 100MB of 3G data on the iPad, although keep in mind I was also using an iPhone some of the time. It worked perfectly for our trip. Being able to consult maps, the web, and related information was very handy.

I can also highly recommend the TomTom for Italy iPhone app (with the hardware phone holder that amplifies the GPS and charges the phone). We drove all over Italy using this device, and rarely made mistakes in getting to our destinations!




First, let's talk GPS in the iPad

The GPS in the iPad works with or without a 3G plan.

It's called "Assisted GPS," but don't let the name fool you, it's true GPS. The "assist" you get from the cell towers is that you get an immediate approximate location, and more importantly, the tower information tells the GPS chip in the iPad which GPS satellites to lock onto. This speeds up the process of acquiring a true GPS lock.

However, if you are in an area with zero 3G cell coverage, your iPad will still obtain a GPS lock, it's just going to be a bit slower initially.

In addition, if you're near any WiFi routers, the iPad will acquire an approximate location based on data from services like Skyhook, automatically. (Assuming you're able to connect to at least one of those WiFi routers to obtain an internet connection that the iPad can use to query the remote Skyhook data!)

Based on my testing yesterday, the GPS in my iPad (without any 3G plan enabled, mind you) was following me pretty damn precisely. I walked the sidewalk around my office complex, with the map program open, and it was dead accurate and very smooth updating, more so than my iPhone.

Of course, if you haven't enabled the 3G plan, and if you have no WiFi connection, you won't be able to use many GPS programs anyway, since they typically are downloading maps and other stuff from the net.

3G Data Plans

Most people know AT&T is offering two plans, $15 for 250MB and $30 for unlimited. If you get low on the 250MB plan, they provide warnings so you'll know. You then have the option of paying another $15 for another 250MB, or paying $30 for 30 days of unlimited, from that point in time. (No, you can't just pay an extra $15 to 'upgrade' to unlimited!) These plans auto-renew, until you cancel, but there's no lock in or contract.

AT&T also has international data roaming plans. These are priced the same as adding data roaming on iPhone or any other device, with several tiers, and the top end capping out at $200 for 200MB of data (in a 30-day window, just like the domestic plans). Unlike the iPhone plans, there are no overages or overage fees -- you simply run out of your allotment, and to continue, you must add another international roaming plan. (Keep in mind you'll need WiFi access to enable this plan, since your 3G coverage will have run out!)

Contrast this with the iPhone roaming plans, where if you go over, you're not warned initially, and you're paying $5 per MB over!

The international plans are a one-time fee, they do not auto-renew. You can also pick which day they start on, up to a year from your purchase date. So you can time it perfectly for your departure date.

Note: You must have an existing 3G data plan on the iPad to add international roaming.

It is simple to add both the 3G data plan and the international data add-on directly from the iPad settings app, look for "Cellular Data."

$200! $200! Anything Cheaper?

The only thing that would be cheaper is if you were to just get a pre-paid micro-sim card in the country you're traveling to. Instead of the high rates you're paying AT&T, you'll be paying a fraction of that. The problem is the micro-sim format is still really new (as of May 2010), and you may have trouble locating a provider in your travel destination that carries them. But the iPad is unlocked and it will work if you can find one. (Some people suggest cutting down a regular SIM card to fit the micro-sim slot, which may work.)

Personally, I did not want to wander around on my vacation looking for a foreign cell provider with a micro-sim, so I bit the bullet and ordered an international plan from AT&T. I'll be traveling May 7 - 23 in Italy, and will post an update when I return if I have any trouble. (I'm traveling with an iPhone 3GS with 100MB data plan, the iPad with 200MB, and a blackberry with unlimited email data... yeah, work is fun!)

Tuesday, March 2, 2010

MSDeploy Bug: Archives Directories Referenced in HTTP Redirect Virtual Directories


Alternate title: MSDeploy Recursively Copying Data Files During Sync (Infinite Loop)


We were testing msdeploy recently to migrate an IIS 6 web server to IIS 7, and discovered something that took a while to track down.

When you run the -verb:sync option (aka -verb:migrate), and you are trying to archive one or more of your IIS 6 websites to an archive directory, you may discover that msdeploy goes into an infinite loop recursively copying directories into each other. In our case, it eventually bombed, but only after creating a directory structure so deep that Windows itself could not delete it.

(Sidebar: to fix that issue, we had to write a little script that would dig down dozens of directories at a time, then move the remaining directory tree to the root level, then continue digging another dozen directories deep, move the next tree to the root level, and so on until it finished. Then we were able to delete each of these dozen-directory-deep trees from the root level! This idea was adapted from Microsoft's article.)
Anyway, back to the problem at hand...

It turns out, long-forgotten, were virtual directories in IIS that were created for the purpose of creating HTTP Redirects. IIS 6 forces you to first create a virtual directory, give it a real directory that it points to, and only THEN can you change its properties so that it acts like an HTTP Redirect to another resource entirely.

You may not have realized, but IIS 6 is still storing your original directory location in the metainfo for that virtual directory. If you, like someone here (OK, me), just filled in "D:\" or some other root level directory temporarily, then msdeploy will try to archive that directory when it's doing its sync function. YES, I realized long ago that it wasn't wise to use a root level directory, for security reasons alone, but it only takes one of these slipping past you to cause this problem.....

And if you, like us, decided to tell msdeploy to archive to the same drive that you referenced in that virtual directory, you will discover that msdeploy will happily attempt to recursively archive your folder, archive your folder, archive your folder, archive your folder, archive your folder, archive your folder..........

I feel this is a bug in msdeploy. Why does it need to archive these 'old' directory references in virtual directories that are being used as redirects?

The fix is to go back through all of your HTTP Redirect virtual directories, switch the radio button over to the primary directory setting, change the directory to something harmless (e.g. c:\temp\my-special-directory), and then change the setting back to your HTTP Redirect. I actually did this editing the MetaBase.xml file directly, but that's outside the scope of this article!

Good luck and back up your MetaBase and IIS sites before screwing with this...

Thursday, February 25, 2010

iPhone ActiveSync on Gmail, with Custom From: Address

I finally figured out how to get my iPhone to use ActiveSync for Gmail, while still allowing me to use a custom reply-to address. Your mileage may vary, but here you go.

NOTE: This procedure worked for me, but may not work for you. Backup your iPhone before trying it!

(Outside the scope of this document, you must already have 2 accounts setup on your iPhone: (1) An IMAP account that is downloading email from gmail.com, and (2) an ActiveSync account that you're using to sync up Contacts and Calendars. And you must have your vanity reply-to address already registered within your Gmail account. For the purpose of this article, I'll say my vanity address is me@mydomain.com.)

So, with the above as our starting point.

  1. Go into iPhone Settings, then click "Mail/Contacts/Calendars."

  2. Click on the "Fetch New Data" option.

  3. Scroll down and click on "Advanced."

  4. Set your IMAP account to "Manual."

  5. Set your ActiveSync account to "Push."

  6. Back out 2 screens so that you're on the "Mail/Contacts/Calendars" settings area.

  7. Click on your ActiveSync account, and then turn Mail ON. (Calendar and Contacts are probably already ON.)

  8. Click the "Account Info" button at the top.

  9. Change the "Email" field to be your vanity reply-to address, e.g. me@mydomain.com.

  10. Back out 2 screens, to the "Mail/Contacts/Calendars" screen.

  11. Click on your IMAP account.

  12. Underneath "IMAP Account Information," there should be a field named "Address." Edit that field to use that same vanity address, e.g. me@mydomain.com.

  13. Below that are 3 fields for "Incoming Mail Server." Erase the text in each of those 3 fields. (We do this so that your phone won't ever try downloading mail via IMAP.)

  14. Now back out to the main screen (the home screen).

  15. Start the Mail app, and once you're in the inbox, click the back button, and then once more until you see your 2 accounts shown.

  16. Click the ActiveSync account, and then click "Inbox."
Now you should be in your ActiveSync inbox, and it will download your email.

If you start a new message, or reply to an existing message, it should use your me@mydomain.com vanity address as the From: address. The gmail.com address is still exposed in the "hidden" headers, like Return-Path, but there's not much you can do about that.

NOTE: This worked for me, but may not work for you. Backup your iPhone before trying!

Friday, February 5, 2010

iPhone Video Orientation (Tallscreen/Vertical Video)

We have been working with Encoding.com recently to get "tallscreen" (vertically-oriented viewing mode) support working on incoming iPhone videos. Encoding.com now finally supports these videos, but you will need to recognize things correctly on your end, or you won't like the results.

In short, you need to recognize that the video is vertically oriented, and if it is, you want to swap your output WIDTH and HEIGHT numbers in your encoding.com request. If you do that, encoding.com will do the rest.

To understand why, here is what I've learned about how iPhone video works...

The iPhone records video to disk the same way each time: as if you've turned the phone 90 degrees to the left, and put it in landscape mode. This is considered "0 degrees," and the video is recorded in this landscape mode, at 640 x 480 (4:3), no matter which way you have the phone oriented.

If you turn the phone to any of the other positions, it doesn't change the way it writes the bits on disk, it just records the "Rotation" flag according to the orientation the phone was in when the recording process started.

  • 0 degrees: landscape, turned on the phone's left side
  • 90 degrees: vertical/normal, with home button on bottom
  • 180 degrees: landscape, but turned on the phone's right side instead of left
  • 270 degrees: vertical/upside-down, with home button on top
All of Apple's recent video players (i.e. Quicktime) are aware of this rotation flag, and so you might never realize your video is being recorded the way it is until you try to view it on a player that doesn't support it, or encode the video with an encoder that doesn't recognize it. In one of these players or encoders, the video would look to be turned on it's side or upside down.

Encoding.com now supports this flag, and I have confirmed it recognizes it correctly in all 4 positions.

So the only thing you need to do is to recognize that if the rotation is 90 or 270, you need to flip the Width and Height numbers, that's it. Encoding.com does the rest.

So, for example, a user uploads a vertically-oriented video to you (either 90 or 270 degree rotation), recorded at the usual iPhone 640 x 480. You see that it's rotated, and your encoding.com request specifies that the output you want is now flipped, 480 x 640 (W x H). Encoding.com gets your source video, sees the rotation flag, and flips it properly while encoding -- and since you specified the proper output size, the video comes out as expected!

(If the video rotation is 180 degrees, you don't need to do anything. The W x H does not change, since it's still in landscape, and encoding.com will correctly flip the video 180 degrees when encoding it.)

Currently we are using the open source "MediaInfo" program to easily obtain information about an incoming video, and to find whether or not the "Rotation" flag has been set, and to what.