Feb 21

Quick notes on my first book scanner

I’ve been working on my first scanner. I decided to build the “new standard scanner”. The step by step guide to building it can be found here, but as it is fresh in my mind I want to throw out a couple of notes.

First, you only have to be pretty accurate in your measurements and cuts. For the most part the tolerance is quite large… which is good for me. ūüôā

Second, this is a 90 degree scanner. That is, the book is held open at 90 degrees. Between 100 and 110 degrees is going to be a little better. The thing is that at 90 you are very close to ideal partly because your book bindings won’t get messed up from being opened too far. However, if you make it closer to 100 degrees you will get most of the same ¬† benefit while also removing a small amount of “reflection” where the camera picks up the page across from what it’s shooting. It’s just a suggestion, but I’ll be building my second version to 100 degrees or maybe even up to ¬†110 degrees. What would be awesome is if you angle was adjustable. And now that I think about it that might not be that hard and would be worth looking in to.

Third, do pre-drill holes before you screw them, especially on pieces of wood that you just spent a long time cutting! The screw can split your wood if you’re not careful.

references:

http://www.diybookscanner.org/

http://www.diybookscanner.org/forum/viewtopic.php?f=1&t=333

As a super final last note I have to mention that while writing this post I went to the ¬†main diybookscanner.org page and then clicked on forum. When I did I was ¬†redirected to some other site… I think it ¬†was either an “ru” or an “nu” and had ff in it somewhere, I think. I was unable to reproduce it, and nothing ever loaded on the page, ¬†but it somehow caused me to be logged out of most sites. ¬†I’ve never had any problems visiting the diy site before, but I thought I’d mention it just in case.

 

Feb 05

Hashing library for iOS and how it can be used in conjunction with .Net hashing

I’m working on an iPhone / iPad app that needs to be able to authenticate itself to the server from which it requests data. The users of the app will have an account with the website so they will already have a username / password. There is no SSL functionality, so I needed a way to authenticate over plaintext without giving away the password or even the hash of it.

Let’s talk about what the webserver does in relation to storing the password. It doesn’t actually store the password. ¬†It stores a hashed value where the actual password was combined with a salt (random string of a descent length) and that combined string was hashed using SHA256. The result is stored as the “password” for the user and the salt used to compute the hash is also stored for that user. When the user logs in the password they send (using ssl, so it is encrypted between the user and server) is combined with the stored salt and hashed. If the result is the same as the stored hash then the user is authenticated, otherwise they are not.

Here’s a little helper class written in C# for doing the Hash. It’s server side and .net specific.


#region HashingLogic
public class Hash
 {
 public Hash() { }
public enum HashType : int
 {
 MD5,
 SHA1,
 SHA256,
 SHA512
 }
public static string GetHash(string text, HashType hashType)
 {
 HashAlgorithm _algorithm;
 switch (hashType)
 {
 case HashType.MD5:
 _algorithm = MD5.Create();
 break;
 case HashType.SHA1:
 _algorithm = SHA1.Create();
 break;
 case HashType.SHA256:
 _algorithm = SHA256.Create();
 break;
 case HashType.SHA512:
 _algorithm = SHA512.Create();
 break;
 default:
 throw new ArgumentException("Invalid hash type", "hashType");
 }
byte[] bytes = Encoding.Unicode.GetBytes(text);
 byte[] hash = _algorithm.ComputeHash(bytes);
string hashString = string.Empty;
 foreach (byte x in hash)
 {
 hashString += String.Format("{0:x2}", x);
 }
 return hashString;
 }
public static bool CheckHash(string original, string hashString, HashType hashType)
 {
 string originalHash = GetHash(original, hashType);
 return (originalHash == hashString);
 }
}
 #endregion

And here’s the webserver checking the Hash. It should be pretty easy to see how to store it as well when a user sets their password in the first place.

 // ran a query that returned the hashed password and salt for the user in question
 // note: password is the value sent by the user trying to log in
 string the_hashed_password = dt.Rows[0]["vcHashedPass"].ToString().Trim();
 string the_salt = dt.Rows[0]["vcPassSalt"].ToString().Trim();
 string the_salted_password = password.Trim() + the_salt;
 string hashedvalue = Hash.GetHash(the_salted_password, Hash.HashType.SHA256);
     if (hashedvalue == the_hashed_password)
         loginSuccessful = true;

 

Now that we have the background, I can talk about what really screwed with me. I was trying to implement part of this on the iOS side. , but I was getting a different value back for my hash. I used a Hash library for iOS from this site. It was easy to use. Just copy the files to your project and import the .h into whatever file you need to do hashing.  Before hashing an NSString you must first convert it to an NSData. But this conversion requires you to specify the encoding. To use it in conjunction with the .Net helper class above you have to choose the right encoding or it will has to the wrong value. Code first, then discussion.

NSString *usernameex = [keychainwrapper objectForKey:(id)kSecAttrAccount];
 NSString *passwordex = [keychainwrapper objectForKey:(id)kSecValueData];
 // I'm hardcoding the salt for this example, now we need to talk to the server  to see if it will let us log in with it
NSString *retrievedSalt = [NSString stringWithFormat:@"b3b5c979-3438-4f56-aa1a-1d85bda78b7e"];
 NSString *saltedpassword =  [NSString stringWithFormat:@"%@%@", passwordex, retrievedSalt];
// Webserver thinks that hashed(password+salt)  =
 // 14083e601f136a42bb17f37a6dedfd03c1f53f2c93f2cc886de5b44ed4a452c1 -- looking for
// but this library was returning various results... here's one
 // ed87d50a50937361f17f9b3c32c6db04e6b7779e5f3c42dfa20e44cac7bf112e -- getting
 // there are lots of example of how the "encoding" can be done and what the hashed value that results is
 // I included them in this sample code because I had to try a ton to finally find the one that matched the .net
HashValue *hashvalue;
//NSUTF16StringEncoding 762ce0d893b64032f11562e4ee0be3f4ed08ca6b801ab892d319af3942ca788c
 NSData* datasaltedpassword0a=[saltedpassword dataUsingEncoding:NSUTF16StringEncoding];
 hashvalue = [HashValue sha256HashWithData:datasaltedpassword0a];
 ASLog(@"hashedvalue0a - %@", hashvalue.description); // password - whatever you entered
NSData* datasaltedpassword0b=[saltedpassword dataUsingEncoding:NSUTF16BigEndianStringEncoding];
hashvalue = [HashValue sha256HashWithData:datasaltedpassword0b];
ASLog(@"hashedvalue0b - %@", hashvalue.description); // password - whatever you entered
NSData* datasaltedpassword0c=[saltedpassword dataUsingEncoding:NSUTF16LittleEndianStringEncoding];
hashvalue = [HashValue sha256HashWithData:datasaltedpassword0c];
ASLog(@"hashedvalue0c - %@", hashvalue.description); // password - whatever you entered
NSData* datasaltedpassword0d=[saltedpassword dataUsingEncoding:NSUTF32StringEncoding];
hashvalue = [HashValue sha256HashWithData:datasaltedpassword0d];
ASLog(@"hashedvalue0d - %@", hashvalue.description); // password - whatever you entered
NSData* datasaltedpassword0e=[saltedpassword dataUsingEncoding:NSUTF32BigEndianStringEncoding];
hashvalue = [HashValue sha256HashWithData:datasaltedpassword0e];
ASLog(@"hashedvalue0e - %@", hashvalue.description); // password - whatever you entered
NSData* datasaltedpassword0f=[saltedpassword dataUsingEncoding:NSUTF32LittleEndianStringEncoding];
hashvalue = [HashValue sha256HashWithData:datasaltedpassword0f];
ASLog(@"hashedvalue0f - %@", hashvalue.description); // password - whatever you entered
//NSUTF8StringEncoding
NSData* datasaltedpassword1=[saltedpassword dataUsingEncoding:NSUTF8StringEncoding];
hashvalue = [HashValue sha256HashWithData:datasaltedpassword1];
ASLog(@"hashedvalue1 - %@", hashvalue.description); // password - whatever you entered
//[NSString defaultCStringEncoding]
NSData* datasaltedpassword2=[saltedpassword dataUsingEncoding:[NSString defaultCStringEncoding]];
hashvalue = [HashValue sha256HashWithData:datasaltedpassword2];
ASLog(@"hashedvalue2 - %@", hashvalue.description); // password - whatever you entered
//NSUnicodeStringEncoding allowLossyConversion:NO
NSData* datasaltedpassword3=[saltedpassword dataUsingEncoding:NSUnicodeStringEncoding allowLossyConversion:NO];
hashvalue = [HashValue sha256HashWithData:datasaltedpassword3];
ASLog(@"hashedvalue3 - %@", hashvalue.description); // password - whatever you entered
//NSWindowsCP1252StringEncoding
NSData* datasaltedpassword4=[saltedpassword dataUsingEncoding:NSWindowsCP1252StringEncoding];
hashvalue = [HashValue sha256HashWithData:datasaltedpassword4];
ASLog(@"hashedvalue4 - %@", hashvalue.description); // password - whatever you entered
//NSMacOSRomanStringEncoding
NSData* datasaltedpassword5=[saltedpassword dataUsingEncoding:NSMacOSRomanStringEncoding];
hashvalue = [HashValue sha256HashWithData:datasaltedpassword5];
ASLog(@"hashedvalue5 - %@", hashvalue.description); // password - whatever you entered
ASLog(@"targetvalue - 14083e601f136a42bb17f37a6dedfd03c1f53f2c93f2cc886de5b44ed4a452c1", hashvalue.description); // password - whatever you entered

And the output:

2012-02-05 16:13:38.077 [11082:560f] LoginViewController.m:121 -[LoginViewController workOfDoLogin] password – ocelot

2012-02-05 16:13:38.078 [11082:560f] LoginViewController.m:140 -[LoginViewController workOfDoLogin] salt – b3b5c979-3438-4f56-aa1a-1d85bda78b7e

2012-02-05 16:13:38.078 [11082:560f] LoginViewController.m:144 -[LoginViewController workOfDoLogin] saltedpassword – ocelotb3b5c979-3438-4f56-aa1a-1d85bda78b7e

2012-02-05 16:13:38.080 [11082:560f] LoginViewController.m:152 -[LoginViewController workOfDoLogin] hashedvalue0a – 762ce0d893b64032f11562e4ee0be3f4ed08ca6b801ab892d319af3942ca788c

2012-02-05 16:13:38.080 [11082:560f] LoginViewController.m:156 -[LoginViewController workOfDoLogin] hashedvalue0b – df7e828a1df0664ff42756960ab7f63e83f0504437c59286e217df32147d8815

2012-02-05 16:13:38.081 [11082:560f] LoginViewController.m:160 -[LoginViewController workOfDoLogin] hashedvalue0c – 14083e601f136a42bb17f37a6dedfd03c1f53f2c93f2cc886de5b44ed4a452c1

2012-02-05 16:13:38.082 [11082:560f] LoginViewController.m:164 -[LoginViewController workOfDoLogin] hashedvalue0d – 4276b8d7ff791492f537379bf7353095d8ce40c717f15dc242f2847b376b88de

2012-02-05 16:13:38.083 [11082:560f] LoginViewController.m:168 -[LoginViewController workOfDoLogin] hashedvalue0e – 45838174fdf6cb95b7ed6bdbd7409f065c75f12958e58ae84ec5d28235b6cf0e

2012-02-05 16:13:38.083 [11082:560f] LoginViewController.m:172 -[LoginViewController workOfDoLogin] hashedvalue0f – 492adfab98090cf9319684aa707d368a2689495480a59ffd7a9b2a514ea9362d

2012-02-05 16:13:38.084 [11082:560f] LoginViewController.m:178 -[LoginViewController workOfDoLogin] hashedvalue1 – ed87d50a50937361f17f9b3c32c6db04e6b7779e5f3c42dfa20e44cac7bf112e

2012-02-05 16:13:38.085 [11082:560f] LoginViewController.m:183 -[LoginViewController workOfDoLogin] hashedvalue2 – ed87d50a50937361f17f9b3c32c6db04e6b7779e5f3c42dfa20e44cac7bf112e

2012-02-05 16:13:38.086 [11082:560f] LoginViewController.m:188 -[LoginViewController workOfDoLogin] hashedvalue3 – 762ce0d893b64032f11562e4ee0be3f4ed08ca6b801ab892d319af3942ca788c

2012-02-05 16:13:38.086 [11082:560f] LoginViewController.m:193 -[LoginViewController workOfDoLogin] hashedvalue4 – ed87d50a50937361f17f9b3c32c6db04e6b7779e5f3c42dfa20e44cac7bf112e

2012-02-05 16:13:38.087 [11082:560f] LoginViewController.m:198 -[LoginViewController workOfDoLogin] hashedvalue5 – ed87d50a50937361f17f9b3c32c6db04e6b7779e5f3c42dfa20e44cac7bf112e

2012-02-05 16:13:38.088 [11082:560f] LoginViewController.m:201 -[LoginViewController workOfDoLogin] targetvalue – 14083e601f136a42bb17f37a6dedfd03c1f53f2c93f2cc886de5b44ed4a452c1

 

The right Encoding to use on the iOS side was “NSUTF16LittleEndianStringEncoding”. I had to do all of those tests to finally find which one matched the values being produced on the web side (.Net)… so just keep in mind that if your getting two different hashes then you might need to use a different Encoding during the conversion from String to Byte / Data in order to make them sync up.

 

Feb 04

Hiding the Keyboard when touching background

If you are working on an iOS app and have the need for the user the enter input then you usually use a textfield or textview. I was working on a login screen and had a very annoying experience where the keyboard wouldn’t go away after I had finished entering my text. What was especially annoying was that I had encountered it before and had simply forgotten how to resolve it. So I’m writing this up for myself or anyone else who needs the info.

All you have to do is make sure that your view has ‘User Interaction Enabled’ checked under the ‘Attributes Inspector’. Then add the following block of code to your view’s implementation. You can see that I have two textFields called txtUsername and txtPassword. You’ll want to change them to match the names of all the text fields on your form (you don’t know which one is actually the first responder at the time, but from what I’ve read it doesn’t hurt to resign if you are not it anyway). So that’s it.

– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

UITouch * touch = [touches anyObject];

if(touch.phase == UITouchPhaseBegan) {

[self.txtPassword resignFirstResponder];

[self.txtUserName resignFirstResponder];

}

}

Here’s another place that discusses it in a bit more detail.

I’ll also mention that some people use a hidden button the size of the view. Then they tie that button to a “hideKeyboard” method. That solution is also discussed in that thread. I found a better explanation of it a Sams Publishing teach yourself Iphone Development book, but the discussion on that thread will suffice. For my own reference it is on page 179-182. It also discusses how to release the keyboard when the “Done” button is pressed. You will probably want to implement BOTH.

Dec 28

Prolog Language References

I’m currently reviewing an existing system written in vb6 that management at the company I work for has finally decided to get behind porting it. Their plan is to port it to Visual Studio (VB.net) as that is what they are comfortable with. I understand this desire, but I’m also hesitant to jump right in and do so because they are also looking for “better ways to do things” during the transition. This particular system is very “rules driven” and we have a massive amount of code dedicated to supporting these rules. In my opinion this is just screaming for Prolog to be a part of the solution, and since I have some say in the matter I’ll be as neck deep in prolog over the next couple of months.¬†I’ll¬†be trying to get a proof of concept in place before the conversion gets underway so I can prove its value. Either that, or I might just prove that it won’t do the job I want it to and I will be able to dive into the rewrite as previously planned without hesitation or hinderance.

While I can’t tell you what the project is I can tell you that in just one of my fact databases I expect to have well over 1/2 million facts. The facts are relatively static so that’s good. The facts will be queried upon often over 1million times per day and it should¬†be able to¬†handle that without breaking a sweat as this is only about 5% of the total volume we expect to see.

So, that being said, I’m working on compiling a list of Prolog references (websites mainly)¬†that will help me¬†progress as quickly and painlessly as possible.¬†If you have any suggestions for books I’d also¬†love to hear them and will likely be adding them to the post¬†or as seperate posts as¬†I go.

So, here come my links on into topics:

http://boklm.eu/prolog/page_0.html

SWI-Prolog
A short Introduction to Prolog
A Short Tutorial On Prolog
Introduction to Prolog for Mathematicians
iProlog Programmer’s Manual
Prolog Tutorials
A Concise Introduction to Prolog

 

Dec 04

IF (by Rudyard Kipling)

True in sports, business, and life in general:

IF you can keep your head when all about you
Are losing theirs and blaming it on you,
If you can trust yourself when all men doubt you,
But make allowance for their doubting too;
If you can wait and not be tired by waiting,
Or being lied about, don’t deal in lies,
Or being hated, don’t give way to hating,
And yet don’t look too good, nor talk too wise:

If you can dream – and not make dreams your master;
If you can think – and not make thoughts your aim;
If you can meet with Triumph and Disaster
And treat those two impostors just the same;
If you can bear to hear the truth you’ve spoken
Twisted by knaves to make a trap for fools,
Or watch the things you gave your life to, broken,
And stoop and build ’em up with worn-out tools:

If you can make one heap of all your winnings
And risk it on one turn of pitch-and-toss,
And lose, and start again at your beginnings
And never breathe a word about your loss;
If you can force your heart and nerve and sinew
To serve your turn long after they are gone,
And so hold on when there is nothing in you
Except the Will which says to them: ‘Hold on!’

If you can talk with crowds and keep your virtue,
‘ Or walk with Kings – nor lose the common touch,
if neither foes nor loving friends can hurt you,
If all men count with you, but none too much;
If you can fill the unforgiving minute
With sixty seconds’ worth of distance run,
Yours is the Earth and everything that’s in it,
And – which is more – you’ll be a Man, my son!

Oct 26

My iRobot Looj (gutter robot) experience

I got my iRobot looj “gutter robot” yesterday. I’ve been really looking forward to getting one for a while now and finally got it ordered late last week. Not bad for a delivery time! I think I ordered it on Thursday and received it tuesday with free shipping.

Include in the box were two batteries, a charging device, the robot itself including the remote, a beltclip, and two augers. It came in a nice tool case (like you might get with a cordless drill or other cordless power tools) that will allow me to store it neatly out of the way when I’m not using it so I’m liking that too.

I’m writing this because I read various reviews and some were good while others were not so much. I wanted to write it while it was fresh in my head (I just used it about 2 hours ago) because I remember thinking while I was using it that “man, I didn’t realize…” so I figured I’d give a heads up to anyone else looking to spend their money.

First, I want to say that I think this will make cleaning my gutters much safer. I hate getting up and down off the ladder. The way my house was built leaves me with what amounts to second story gutters and I just hate climbing up and down over and over again to clean them. The other option I had was to climb up on the roof and just crawl along the entire roof line on my hands and knees scraping out the gutters by hand. This required me to be way to close the edge contantl and made me really nervous on the steeper graded parts of the roof (which
also happened to be over the highest part of the roof directly over my stone patio). With this looj I was able to find one place that I could climb up, place the looj, and then let it do its thing to clean pretty much the entire gutter area on the back of my house.

It worked pretty well. The gutters got clean enough. I can honestly say that if I was paying a person to clean my gutters. I would require them to have done a better job as there was still some debris left when all was said and done, but probably 95% of it was able to be cleared by the looj. Keep in mind this is a rookie “driver” and I was in a bit of a hurry as I had to get back to work so it might have done even better if I knew what to do, but it worked pretty well regardless.

You do have to pay attention while you use it. You can’t just set it and forget it. For example, I did encounter a couple of times where the looj rolled over. Basically the auger got stuck in some mess that it wasn’t able to break up and so the robot itself just started spinning. It was amusing in a way, but not so much in that I had to go rescue it. It seemed that several times it just quit responding for a few seconds, but then it when right back to working. I don’t know if it got to the edge of the range of the remote or what… in any case it did not make the device unusable, just a little quirky.

I did have one downspout for which the auger never was able to clear out the opening. I had to climb up and clear that one downspout myself. This is still significantly less work than I normally have to do.

This first use was in gutters full of dry leaves, some acorns, and very few pine needles. It hadn’t rained for a couple of weeks so the leaves weren’t wet and the gutters weren’t wet. It took a few passes to get everything out. I plan to use it again soon after a rain (it will rain tonight and I don’t have time to do the front before the rain will be here) so I’ll be able to see which way works best. The second test will includes lots of pine needles so we’ll see how it actually handles them!

I do not think that this device will make my gutter cleaning faster. Working the looj back and forth to get it through heavier jams may actually make it take longer, but I do think it will make it much safer and require less physical exhertion on my behalf.

Cleaning the device for storage was super easy. I just turned on hose and rinsed the looj off. It was pretty “cruddy”, but nothing major and cleaned up quickly and easily.

If they make another model then I would recommend making it a little heavier (maybe 50%) and make the tread motors a little tougher.

I plan to do another review once I get a chance to try this on my gutter that has a pineneedle problem just to report on how that goes. For now though, I’m pretty darn satisfied with the value I received for the money I spent.

Oct 02

iPhone and iPad naming conventions, icon descriptions, and icon sizes

The below table is a description of iphone icons and ipad icons, what they’re sizes and should be, and what their standardized names are. This information is all over, but the a thorough and yet concise version (and what i based the below on) can be found here.

Name Size (pixels) Platform
Icon.png 57 x 57 Universial application icon
Icon-settings.png 29 x 29 Universial application icon for settings area. Alternative name: Icon-Small.png
Icon~ipad.png 72 x 72 iPad application icon. Alternative name: Icon-72.png Add some smaller (iPad doc: 64×64, other optional 32×32, 24×24, 16×16) custom icons to your project. See comments.
Icon-spot~ipad.png 50 x 50 iPad icon for spotlight search. Alternative name: Icon-Small-50.png iPhone OS trims 1 pixel from each side and adds a drop shadow. The actual size is 48×48 pixels.
iTunesArtwork.png 512 x 512 Universial application icon for iTunes App Store. Uploaded separately to iTunes. It’s included in the app bundle too, file name: iTunesArtwork. In an iPad application iPhone OS uses this image to generate the large (320×320) document icon if it is not supplied otherwise.
Default.png 320 (w) x 480 (h) iPhone/iPod 2, 3 portrait launch image
Default@2x.png 640 (w) x 960 (h) iPhone 4 hi-res portrait launch image
Default~ipad.png 768 (w) x 1004 (h) iPad. Specifies the default portrait launch image. This image is used if a more specific image is not available. Use full size template (768×1024) to design this launch image. The 20 pixels height statusbar is on by default and occupies the top of the screen, aka the 1004 rows vs. 1024.
Optional icons and images:
Icon@2x.png 114 x 114 iPhone 4 hi-res application icon
Icon-settings@2x.png 58 x 58 iPhone 4 hi-res application icon for settings/search area
Icon-doc.png 22 (w) x 29 (h) Universial document icon
Icon-doc@2x.png 44 (w) x 58 (h) iPhone 4 hi-res document icon
Icon-doc~ipad.png 64 x 64 iPad document icon (small)
Icon-doc320~ipad.png 320 x 320 iPad document icon (large)
Background-xxx.png 320 (w) x 480 (h)
640 (w) x 960 (h)
768 (w) x 1024 (h)
iPhone/iPod Touch 2, 3 background image,
iPhone 4 background image, full size
iPad background image, full size. For most projects the status bar is hidden, so use full screen size by default.
Default-PortraitUpsideDown~ipad.png 768 (w) x 1004 (h) iPad. Specifies an upside-down portrait version of the launch image. The height of this image should be 1004 pixels and the width should be 768. This file takes precedence over the Default-Portrait.png image file for this specific orientation.
Default-LandscapeLeft~ipad.png 1024 (w) x 748 (h) iPad. Specifies a left-oriented landscape version of the launch image. The height of this image should be 748 pixels and the width should be 1024. This file takes precedence over the Default-Landscape.png image file for this specific orientation.
Default-LandscapeRight~ipad.png 1024 (w) x 748 (h) iPad. Specifies a right-oriented landscape version of the launch image. The height of this image should be 748 pixels and the width should be 1024. This file takes precedence over the Default-Landscape.png image file for this specific orientation.
Default-Portrait~ipad.png 768 (w) x 1004 (h) iPad. Specifies the generic portrait version of the launch image. The height of this image should be 1004 pixels and the width should be 768. This image is used for right side-up portrait orientations and takes precedence over the Default~ipad.png image file. If a Default-PortraitUpsideDown.png image file is not specified, this file is also used for upside-down portrait orientations as well.
Default-Landscape~ipad.png 1024 (w) x 748 (h) iPad. Specifies the generic landscape version of the launch image. The height of this image should be 748 pixels and the width should be 1024. If a Default-LandscapeLet.png or Default-LandscapeRight.png image file is not specified, this image is used instead. This image takes precedence over the Default.png image file.
Sep 29

How to let your iphone or ipad apps check for network access – reachability

I have recently been working on a new iOS app for the iPhone and I ran into a couple of issues. I don’t really have time to go over them all in this post, but I did want to document one of them because I hear it can be a big deal as far as getting your app approved by Apple. The issue is that of making sure you handle things gracefully if the user’s phone is unable to connect to the internet and they try to do something that does require a connection.

The way I decided to handle it was to use the reachability collection provided by apple. I downloaded the reachability sample from Apple¬†and then copied and imported the 4 files from the “classes” directory into my project.

Then I added the “SystemConfiguration.framework” to my project.

Now I have all of the prereqs for my solution. The next thing I did was I created a NetworkReachabilityTest class with NSObject as its base class. I added a single method called “isNetworkReachableWithAlert” that returned a bool and included one parameter. The parameter specified whether it should automatically pop up an alert box in case of a lack of network connectivity.

I chose to do it this way (as a dumb small class) so I didn’t have to copy the code for this method into every page. Plus it gives me the flexibility to easily reuse it in future projects. So now, before I do something that requires network connectivity I instantiate an instance of this class, I do the check, and if the connection is there I do the work. If the connection is not there I can bail out instead.

Here’s the code (some of this code was included in the example and some was found here around post 29 or 30:

-(BOOL) isNetworkReachableWithAlert:(BOOL)bshowalert

{

Reachability *r = [Reachability reachabilityWithHostName:@”www.signandtrade.com”];

NetworkStatus internetStatus = [r currentReachabilityStatus];

if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN))

{

if (bshowalert)

{

UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:@”No Internet Connection” message:@”An internet connection via WiFi or cellular network is required for this portion of the app to work.” delegate:self cancelButtonTitle:@”Ok” ¬† otherButtonTitles:nil];

[myAlert show];

[myAlert release];

}

return NO;

}

return YES;

}

That’s in the implementation file ¬†of my simple class and it is basically the only thing there! And it does everything we need.

And here it is in use:

NetworkReachabilityTest *nrt = [[NetworkReachabilityTest alloc] init];

if ([nrt isNetworkReachableWithAlert:YES])

{

// logic that requires or includes web activity here

}

[nrt release];

Hope that helps. Hope it makes sense. Better ideas or improvements on it are welcome, I just wanted to give someone a simple example of something that I know works  along with the steps I took to make it work.

Sep 25

Printing from within a WinXP Virtualbox client with a Mac OSx host

I have an Mac OSx machine on which I have virtualbox installed. My most often used virtual client machine runs Windows XP. Almost everything works great, but I was having a lot of issues getting printing to work. I finally got everything figured out though and figured I’d write it up real quick. So here’s what I did.

The first thing I would recommend doing if you have a setup like mine is to find the driver for the printer that you need to print to. Why? Because the apple software that I point you to below will install a driver by default that technically works, but it makes everything you print come out super small. [Actually, as I’m writing this is occurs to me that it may be doing this when I print because Apple assumes an HP printer in their tool, but mine is an Epson. ¬†So maybe the default installed by the program provided by Apple will work “out of the box” for an HP printer… But I would still go ahead and get the correct driver for your printer first.]

Then once you have the driver on the client do the following (found this at virtualbox.org forum and quoted from here):

1) Shutdown the VirtualBox machine
2) Under Mac OS X

  1. System Preferences, Print & Fax, Check “Share this printer on the network”
  2. System Preferences, Sharing, Check “Printer Sharing” and Check the printer

3) VirtualBox machine, Network:

  1. if only one adapter selected and it is attached as NAT [this is the default], then add Second adapter. Make it attached as Host-only Adapter and choose the name: vboxnet0 (see note B at the bottom if you can’t find this).
  2. if the adapter is attached as Bridged Adapter, then do nothing (you have a reason to be Bridged?)

4) Start up the Vbox machine – let it adjust to added Network Adapter
5) Download and install from Apple “Bonjour Print Services for Windows”¬†http://support.apple.com/kb/DL999
6) start Bonjour Printer Wizard and follow the menus

Note A: That wizard will allow you to print from the client using the printer on the host MacOSx machine. But that wasn’t it for me because Apple defaulted to an HP driver which caused the pages to print all tiny on my Epson. It was an easy fix though. I just had to go back and run the brand specific printer driver install (or manually change the printer driver for the printer added by the apple wizard) so that it would use the brand specific driver instead of the Apple default.

Note B: I did a fresh vbox install to test this because some people weren’t seeing the vboxnet0 at this stage. I was able to reproduce the problem and fix it based on another reader’s suggestion. All I had to do to get it fixed was go to ‘VirtualBox’->’Preferences’->’Network’. It’s probably completely blank for you if you’re reading this note. What you want to do is just click the little green plus to add a new hostonly network and it’ll add ‘vboxnet0’. Now go back and finish the tutorial where you left off and you should be printing in no time. Hope that helps.

Note C: In the comments below you’ll see a couple of readers (Jeffrey Weber and Leigh Warren) that were only able to get things working by using Bridged instead of HostOnly (see step 3 above for where this matters). The “method” I defined in the main part of the post seems to work in most cases, but there is obviously some type of setup that requires bridged rather than host-only. I recommend that you try it the original way first and then double check everything if it doesn’t work. After that if the original way still doesn’t work you might try tweaking this setting going bridged instead. Keep in mind that if you’re already bridged and everything is working then, as the original write up says, do NOT add the host-only.

Aug 28

Some thoughts on Software Patents

I have read a lot of what I consider to be fairly convincing arguments relating to software patents and whether the courts should “allow them” or “ban them”. Before I had the insight I’m going to share below I was definitely a fence hopper, but I think I have finally satisfied myself with an answer. It takes a wee bit of imagination and a willingness to be somewhat philosophical to get there, but I think the thought process will get you there.

 

If you’ve seen “The Matrix” you know that almost the entire movie involves real people living and acting in a virtual world. If you’ve seen “The Matrix Reloaded” you’ll remember a scene where a ship is returning to realworld city of Zion and they are getting ready to enter the gates to the city. The city is very mechanical and computers are utilized to control everything, but do the people of Zion who operate the computers sit behind a keyboard? No they don’t. Instead they “plug in” in the real world transferring they minds into the virtual world in which someone (presumably other humans) has programmed all of these controls. The controls cool thing about these controls is that not only can they be laid out like a keyboard, but they can also be like a lever. It’s their own virtual world so they can build it however they want. They just need to be presented with an environment that they can manipulate to get “the job” done.

 

Now imagine current earth humans being able to allow their mind to live or work inside of a virtual world. Everything in that virtual world is actually software! Nothing is physical though it could be designed to look it and feel it. It may be designed such that your physical actions (ie grabbing a lever and pulling / pushing it) causethe software to behave in different ways, but it’s still not actually physical. How you interact with that software simply causes some state change in the outside world, but what you are interacting with IS software. Yes, the changes you introduce by manipulating the controls made available to you will cause some other software to cause changes in the outside world which will in turn cause a change to the view of the world presented to the those in the virtual world (and in the physical world). But it’s still software making it all work. The tools are software. The connections are software. The actor could even be software.

 

Once these types of systems are possible, and especially once they are common place, there could be a rush of what, in the physical world of today, we would call innovative people coming up with new widgets that can be used inside of this virtual world. These innovations will almost surely come with a price that would be paid by the programmer. In that case there would be a need for protection under some type of law in order to encourage people to create, test, and perfect them. Do we have a system that provides this sort of protection today? Yes, we do, and it is the patent system. It would also be applicable to this sort of situation considering the new types of “tools” that people would “physically” interact with inside the virtual world. All manner of things are possible in the real world today that we just knew wasn’t possible before (until someone innovated a way to do it), and the same will be true in the virtual world. Ways of doing things never even thought of will be, given the right motivation, not only thought of but implemented and improved upon. Different ways of looking at problems will cause unique solutions to become apparent. The solutions would be “obvious” once pointed out, but would be nonobvious prior. Why would someone dedicate their time to looking for alternate solutions if the answer will net them no reward? History shows us that they won’t… not to the same degree anyway.

 

Q: What about a hammer vs a “virtual hammer”? Would you really allow a patent on a virtual hammer that does the same thing in software world that it does in the real world? That seems like everything would get repatented with the only difference being that it is “in software”.

 

A: This question stems from one of the common errors untrained people make when judging patent validity. You can’t just look at the title, or the summary. Think about it. A software hammer wouldn’t be the same thing as a hardware hammer would it? Software doesn’t have physical nails to drive. But maybe a software hammer can be made such that it easy automates the binding of two or more components using a single connective module. Something that used to take 10 virtual actions can be easily rolled¬† up into the action of hitting the objects with a hammer. The hammer basically just does all of those steps that “physically” had to be done before and elminates them through some ingenious “piece of code”. Testing this peice of code and finding just the right tweaks for it came with a cost of thousands of lost operations (cpu cycles), mangled data, and even memory leaks that had to be dealt with before it became stable to be used in the virtual world. Why would someone give up these precious resources if it would not gain them some advantage? Now that it is done it is a easily copyable solution so what’s to stop another from copying it and using it without having put their own butts on the line? Copyright doesn’t do the trick as code can be rewritten (hell, translate it to another language and you’ll have to modify it to do so). You’re still using the same algorithm, but it obviously not the same code. Yes it is and you shouldn’t be allowed to steal the code, change the language, and call it new.

 

It is my belief that as things become more virtualized and as virtual reality starts to become both more real and more immersive that we will see more need for patents on things in the virtual world. These things are no doubt software. But they are also no doubt in need of protection.

 

To be continued… or is this one step too far?

 

And if we know that software should be patentable in the case of said eventual world, then software should be patentable now due to the simple fact that the simulation argument leads there.