Saturday, April 13, 2019

Key West, Biking the Florida Keys part 4

I'm ready to get moving. Kendall was feeling too tired to bike today, so we are taking our rest day today and will go back to Marathon tomorrow.
The sun is intense. Sitting in the shade neat the pool today and just the reflection of the sun off the water felt like it was sunburning me.
So we are going to get going in the morning as soon as it is light enough to see and hope to skip out on the hot afternoon.

Forecast for the night calls for rain, so I guess I better put up the rain fly. Might still be raining when we start in the morning.

Friday, April 12, 2019

It's a scam. Biking the Florida Keys part 3

We made it to Key Largo. Before heading out on
this trip I did a quick search to see what others said about biking the overseas heritage path from Key Largo to Key West. Most of what I read was that it was mostly doable except they didn't recommend biking over some of the bridges. Never did figure which bridges. But if you are a confident cyclist then there really isn't anything that isn't just fine to bike. If you have the mistaken idea that bikes should be on paths or sidewalks then this is not a good fit for you.

A few weeks ago we were babysitting my grandson while his parents went to the temple. We decided to take him to Disney world. But he was upset that he was getting babysat and not going with Mom and Dad. We tried to sell him on Disney but he is two and was having none of that.

However a couple days before that as we were driving we were thinking of going to Hobby Lobby, but I just wanted to get home, so we passed the Hobby Lobby. Hobby Lobby is a fun word for two year olds. So he spent the next few hours repeating phrases like "passed the Hobby Lobby'

So when he started saying, "no Disney" I asked if he wanted to go to Hobby Lobby. His answer, "don't pass the Hobby Lobby"

So we convinced him that Disney was hobby lobby. All day we asked him how he was enjoying hobby lobby. He loved it. But to get into the magic kingdom you have to ride the ferry boat or the monorail. The Disney employees will try and convince you that they are both the same fast. False. The ferry boat is a scam. So we spent all the day trying to teach my grandson to say the ferry boat is a scam. Tried to get him to tell all the ride opporators but he would never do it. But when we got back home and in the arms of mom we again asked, what is the ferry boat?" And he tells mom, "a scam."

So the overseas heritage trail is a scam. All these bike paths are a disaster. Larger sections are torn up and a lot of the bike path bridges are closed. I guess the hurricane a couple years ago did a lot of damage. Anyway for a lot of it it is just better to ride in the bike lane on the road.

Had a great time riding down, with beautiful views. But it kind of smells like Yellowstone here, and the beaches are a bust.

Kendall is too tired so we decided to take our rest day tomorrow instead of Sunday. And then it will be two days of head winds to get back.

I guess having him use my cheap Trek mountain bike that I bought to pull the baby trailer with was a mistake. 

Thursday, April 11, 2019

Key Largo to Marathon, Biking the Florida Keys part 2

 
Yesterday we got a cheap motel in Homestead. For 50 some odd dollars it wasn't bad, and the breakfast in the morning was great. Then drive to Key Largo for our starting point.

OK, what is the deal with the drivers here! Every time one lane was dropping out some idiot would think they need to sneak around at the last second. And when it is a big truck that means they are going to push you off into the mangroves. I guess it just fits in with the Florida thing of thinking they are stock car drivers and need to draft a few inches off your bumper.

But even though I'm going to leave a reasonable amount of space between me and the car in front of me, I'm aware of what is going on and I'm not going to let you force me off the road.

See we got to the chamber of commerce building a bit before it opens. Fortunately the lady running it also got there early. She says she has to leave early because frequently there is an accident from people getting forced off the road when the lanes merge.

In Key Largo the bike route is a nice path along the side of the road. But there are a lot of places south of Key Largo where the trail is all broken up and not ridable on a road bike. And if you are dumb to ride it anyway then you'll be fixing a flat. :-) 

Anyway it was a fun ride with amazing scenery and more iguanas than I've ever seen. OK, I'm not sure I've ever seen iguanas in the wild before, but I promise there are a lot and some of them are practically the size of an alligator. OK, OK, I yet to see an alligator in Florida, but they are big iguanas.

So tonight we are staying with some hosts we arranged through couch surfing. They have been the best. They even claim they like the vegetation version if Thai curry I made for them.

So get some sleep tonight and head out to Key West tomorrow.

Wednesday, April 10, 2019

Homestead Florida, Bike the Florida Keys part 1


So, my friend Kendall, flew into Orlando this morning. His flight was delayed, probably die to all the issues with the 737 Max planes being grounded. So by the time we hit home it was about 4 am.
Today we did our final packing and then drove down to Homestead Florida. Key Largo is just a few miles from here. The plan is to bike from Key Largo to Marathon tomorrow, and then stay with some people we found through couch surfing. This is our first time trying out couch surfing. We tried getting other hosts in Key West and in Marathon for the return trip but so far have not been successful.
This is a trip that Kendall suggested way back before I decided I want to move to Florida. Before this trip my biking in Florida has consisted of the local bike paths and roads near Clermont.
Video of biking most prominent point in Florida: https://youtu.be/UN4D0T6bTdo

Monday, April 08, 2019

SeaWorld doing the rides

We went back to SeaWorld again today. My grandson just had such a blast at Sesame Street last time, we had to come back and do it again with his mom and dad. So we spent about half a day doing Sesame Street and the Orca show, and then spent the last half of the day doing the roller coasters, and water rides.

We got drenched watching the Orcas and so then went to the splash pad and rinsed off the salt water. And then went and rode the Infinity Falls. It is a pretty good water rapids fall, not too long and the last drop that seems like it will be pretty intense, isn't as bad as it looks.

I'm not a big roller coaster guy, but we had a blast doing the coasters at SeaWorld. The Mako coaster was the biggest coaster I've been on. I think half the time I was floating out of my seat. Then we did the Manta coaster. My daughter did NOT want to do that a second time. You are essentially riding the whole thing laying on your stomach. The first drop was terrifying and they take your picture at the bottom, but then as you head back up and around the next loop... yeah well it just gets even more terrifying. Finally we did the Kraken which is more rickety than the others and has a lot of loops. It really is a good set of roller coasters, and the lines were only like 5 to 10 minute waits. After Kraken we did the Atlantis ride which is something of a combo water ride and boat ride. Kinda cool.

We tried out the all day dining plan for one of us. It worked out good, and was enough food to share with the rest of us. I also bought their refillable drink cup. Usually I count on these park trips as a way to get some exercise in while not eating much because I don't want to pay the prices they charge for the food, but I think today I ate more calories than I burned.

Saturday, April 06, 2019

Can you tell me how to get

Today we decided to check out SeaWorld. Dieter F. Uchtdorf tells a parable of a man that goes on a cruise and spends most of his time in his cabin eating crackers he brought with him because he was unaware that all the food and entertainment on the ship was included with the cost of his ticket.

Today I felt like that man. When I bought my annual pass for Sea World a couple of months ago it included a coupon for a free PhotoKey. I had no idea what a PhotoKey was and when I asked they told me how and where I could go and get it, but nobody explained what it was.

So today we decided to check out the new Sesame Street area of SeaWorld. It was actually pretty cool. Kind of like stepping into the Sesame Street from the TV show. The rumors I have been hearing is that the crowds at Disney the last week or so have been really bad. So I expected Sesame Street to be crowded, after all it has only been open for one week. But actually it wasn't crowded at all. In fact we were frequently able to ride the same ride multiple times in a row because there was no line.

Also the lines to meet Cookie Monster, Elmo, and Big Bird were very short, or at times no line at all. Each time we would go see Cookie and Elmo my grandson, Cayman, would run past Cookie and over to Elmo. He has an Elmo toy that he loves but really doesn't know who any of the Sesame Street characters are. Anyway, after were are done with the character greets they would give me a little card for getting the pictures they take. And I'm thinking I'm not going to buy those pictures. But then I look at the card and it says PhotoKey on it. So I take it to the counter and ask if my free photo key deal is good for the pictures they took. I'm thinking it is some kind of keychain with a picture on it. They tell me yeah but you have to go to the place by the entrance to get it.

So after we were done with Sesame Street Cayman was getting tired and I decided to head home for the day. After being at the beach all day yesterday I had a slight sunburn and figured it would be best not to spend another full day in the sun.

So we stop by the KeyPass place on our way out and I ask if I can use the free PhotoKey with the pictures they took today. I'm still thinking this is some kind of keychain. She says no problem and scans the cards I had collected and my coupon, and then tells me how the PhotoKey works. For the next year anytime I visit any of the SeaWorld family of parks I can give the PhotoKey card they give me to the photographer and then all the pictures they take will be available for me to download. For FREE.

The sad thing is, when I got the annual pass I also got a free animal encounter. I let my son Stephan, and my grandson Vincent use the animal encounter to go and see and pet the dolphins. And of course they took pictures, and I could have had those pictures, also we could have taken other pictures with Vincent. But like they guy in the parable I was figuratively sitting in my stateroom eating the crackers instead of enjoying the free benefits that came with my pass.

And one passing thought, I think they want you to go around the park asking, "Can you tell me how to get, how to get to Sesame Street?" because they didn't have any signs showing how to get there.

Wednesday, April 03, 2019

Florida Beaches





Over the last few months we have visited several Florida beaches. First we went to Daytona Beach on the Atlantic coast, and loved it. It was the middle of November, yet the water temperatures were fine and I was surprised how nice it was for being so late in the year. Then we tried Clearwater Beach on the Gulf coast. We were surprised at how nice the sand was, but near the water it was more broken shells than sand and so not quite as nice as Daytona Beach. Also the waves at Daytona Beach were a lot more fun to play. At least so far, and it makes sense, the waves on the Atlantic beaches are much bigger than on the Gulf beaches.


Then in January we tried out Cocoa Beach. My son in law gave me some pointers on body surfing and we had a blast surfing the waves. By the end of the day I actually got to where I could ride the waves pretty well. 

A few weeks ago I decided to get up early in the morning and bike from Clermont Florida to Pine Island Park beach and then meet my daughter and family would drive out and we could have a fun day at the beach. 

The problem is there isn't enough parking at the park so if you don't get there early you can't park. So after stopping to get a picture I headed north for Crystal River, and my daughter picked me up somewhere along the highway between Pine Island and Crystal River. Anyway we ended up going to Fort Island beach.

Fort Island beach was a great little beach for kids. It is well protected so there isn't much in the way of waves. Also while we were there a pod of dolphins came near the beach and played around for awhile. We stayed for sunset and I just had to get some pictures. 

And then today we headed out to go to Fort De Soto Park beach. But we didn't bring any cash with us so we couldn't go over the toll bridges to get to the park and decided to go to St. Pete beach instead. We had a blast there. The sand was super soft and fine. And while the water felt a bit cold when you first step into it, after you get used to it, it is just fine.

So out of the beaches we visited so far, which is the best? Hmm, hard to say. I guess so far every Florida beach we've been to so far has been great.



Wednesday, September 13, 2017

Can you ski coast to coast across Antarctica solo?


A friend sent me a link to this expedition: https://soloacrossantarctica.com/expedition

After a quick glance my first reaction was, this is basically an attempt at completing the expedition that killed Henry Worsley. This morning I took a more in depth look at the website, and yup, that is what it is.

So, some thoughts on the expedition:

My bike in the endless sea of Antarctica Ice
I've never skied in Antarctica, so I really don't know how hard it is compared to biking. When Juan passed me while I was pushing my bike and he was skiing,  skiing with a bike in a sled was a lot easier than pushing it. But there were other times where it seemed that my riding the bike was making a better progress then his skiing. My guess is that overall skiing is easier than biking in Antartica, but still extremely physically demanding.

Charlie is planning on leaving in early November and taking 80 to 100 days to complete the expedition. Henry Worsley took about 71 days before he had to be picked up and was some 120 miles from finishing. That would mean he probably would have taken another 10 days to finish. So, the 80 to 100 days to complete seems reasonable. Given that you have to finish by the end of January when the last flight leaves, you would have to leave in early November to be able to finish.

The problem is the earlier you leave the softer the snow is, and the colder and worse the weather conditions are. This means the first month and a half or so will be in soft difficult snow conditions, and then when he gets to the polar plateau, near the South Pole, the snow becomes a bit like sand and again difficult to ski on. In other words this is an extremely physically challenging task.

On his website he says he plans on consuming 9,000 calories per day, while skiing 12  hours a day. Looking at Henry's expedition and from my own experience I would say 12 hours a day is probably a minimum amount of time needed. Eating 9,000 calories a day and having your body absorb those calories while doing a 12 hour a day physical workout is very difficult.

He is expecting to expend 12,000 calories a day. So that is about 1,000 calories per hour of skiing. My guess is this is about right. Now the problem; he is expecting to lose 40-50 pounds on his expedition. The general rule of thumb is that 3,500 calories is about 1 pound of fat. If he is expending 12,000 calories and consuming 9,000 calories that is a 3,000 calorie deficit per day. If it takes 85 days that is about 73 pounds of fat. To only lose 40-50 pounds he would either need to consume more calories or expend less. The thing is, I don't know if either of those options is possible. So it looks like he would lose about 73 pounds on the expedition. Looking at his pictures I doubt there is 75 pounds of fat on his body.

If he can't get the needed calories from fat then it has to come from something else -- muscle and organs. Once the body starts cannibalizing itself you are in trouble. I figure on my expedition I depleted my fat store and was burning muscle and who knows what else to complete my expedition. Fortunately for me my expedition ended after 51 days. I'm not sure I could have lasted the 71 days that Henry Worsley went, and I am sure I would not last 80+ days.

So, knowing what I think I know, this is not an expedition I would want to attempt. I don't know if I could find the right balance between not giving up and not killing myself. I am afraid this expedition would kill me.

Is it possible to do? In spite of my calculations above I think it probably is possible. I will be sure to follow Charlie's progress and hope and pray that he successfully completes what is sure to be an amazing expedition.

Wednesday, August 16, 2017

Mr. Blue Bird is on My Shoulder

Crossing the Jordan River
This morning was just one of those mornings...

I went out to get ready to ride and you could feel the crispness in the air that says Autumn is just around the corner. Actually as I started riding I wondered if I would get too cold as I head down the hill to Saratoga Springs. However after getting going it turned out to be that perfect temperature.

Really it was just a perfect morning to be riding a bike. The skies were a beautiful azure blue. It was one of those days you wish the bike ride would never end.

It is the truth, it's actual, everything is satisfactual!

Wednesday, June 14, 2017

Yeah, but I had a penny...

One day, when I was just a little kid, my brother had a dime. Back then we could buy two pieces of candy for 1 cent. So three or four of us decided to head out to the store. I'm not sure our parents would have approved having us little kids walk the mile to the store crossing the busiest street in the city, but I don't think we asked anyone for permission.

Along the way to the store I found a penny on the ground. More candy! However there was a problem. On 10 cents there is no sales tax, but if you spend 11 cents then you also have to spend one cent for tax. So as we walked to the store we devised what we thought was a clever plan. Each of us would pick out our candy and one by one pay for the candy and then pass the change on to the next person.

We thought we were so smart. I picked out a couple of Swedish fish and was the last to buy our goods. But before we left, the sales lady asked us why we hadn't just payed for everything at once. So my brother tells her that we didn't want to pay sales tax. "There is not tax on a dime." she said. And I proudly replied back, "yeah, but I had a penny!"

They teased me about that the whole way home. Actually they teased me about that for years afterwards. I still remember how great we thought it was that we out smarted the system.

At the intersection where I cross Redwood Road on my way to work, there is what I thought was a dime amongst the debris that piles up at the intersection. A few days ago I stopped and picked it up. It actually is a penny that has had all of the copper worn off of it. I've actually noticed a lot of coins amongst the road debris as I bike to and from work. As a kid I was so excited when I found that penny, now I simply ride past quarters, nickels, dimes, and pennies every day. Surely other people see them too but nobody cares enough to even stop and pick them up.

Friday, June 09, 2017

Sorry Dude...

... but let me explain. Ever since that lady intentionally tried to kill me because, in her words, "he was riding his bike on the road," I have suffered from a real bad paranoia.

I still have not been able to ride my bike down that road. When I think about it I get a vision of the lazy lady putting the pedal to the floor and swerving at me, and this time successfully turning me into roadkill. When the Sheriff's department arrives to clean up, the deputy gives the lady a high five for doing her part to rid the roads of non motorized vehicles.

Hmm, blog posts need pictures: our bike ride in Prague a few weeks ago.

So to deal with this paranoia, instead of riding my bike on the 30 mph road I ride down the highway where the speed limit is 55 mph. Of course this means the average speed is something like 70 mph. OK, yeah, this doesn't make sense.

Anyway, as I head down this road I need to make a left hand turn. I like to turn one intersection before the main one so I can get off the highway and on to the pathway. But the problem with this is, it requires me to ride on the left side of the highway for a block or so.

...and that is my excuse, after making that left and heading to the pathway my brain shifted into riding on the left. So that confusing moment when you were riding your bike off the pathway, and you couldn't figure out which way I was going, was just a strange way of me trying to stay alive as I go to work.

Thursday, April 27, 2017

Don't Give Up

We all have those days. As soon as you arrive at work, you wonder if it is time to go home yet. Days like that remind me of Tuesday Jan 14, 2014.

It was one week before I would arrive at the South Pole. I had got into the routine of taking Sundays as rest days. Every day I was putting in 13+ hours a day of intense work. So it got to the point that I looked forward to Sunday more than a little kid looks forward to Christmas.

On Sunday the 12th I took a nice rest from the weeks work. Then on Tuesday I got another bad whiteout. There was a lot of new soft snow. I could not see where I was going. I had been biking across Antarctica for almost two months, and I had gotten good at just accepting the conditions and continuing on in much worse conditions than this. But this day broke me. After a couple of hours of whiteout conditions I just quit. I wanted it to be Sunday so bad, but it was only Tuesday!

What is the point? I don't know, but yeah Xamarin studio has been getting worse and worse with each new update, and today I just didn't want to deal with it anymore. Oh well, back to work!

Thursday, March 16, 2017

When we were kids we used to like digging big holes in the orchard. The joke was that if you dug deep enough you would come out in China. Of course we never thought we could dig all the way to China. Besides this was during the Cold War so we knew that Americans were not allowed to go to China.

Calvin had his Hobbes, and my son Stephan had Top. Top was a stuffed penguin I bought as a gift for my wife, but when Stephan was just a baby he decided Top was his. Stephan loved Top and thus all penguins. The Pittsburgh Penguins became his favorite sports team.

For some reason my kid’s schools thought the kids should decide what their career will be before they were even teenagers. Stephan was a smart kid and it seemed very likely he could become a scientist. So I pondered the idea of him becoming some kind of researcher going to Antarctica to study penguins. He however went a different direction. Stephan will be getting his PhD in mathematics this spring.

My father was a scientist and was invited to go on a sabbatical to Antarctica with Dr. Wolf Vishniac to do research on detecting life on Mars. However he decided to go on a sabbatical to New England instead.

So the point of all this, I never dreamt of going to Antarctica. It was something someone else might do, but wasn't something I considered doing myself. Fat bikes and the amazing Eric Larsen changes that.

I also never thought I would go to China. My South Pole expedition has changed that also. I have been invited to go to Shanghai to help someone plan for his Antarctic expedition. So I'll see if I can figure out how to add some blog posts while I'm there.

Hmmm, before Antarctica visiting all the continents was not on my list, after China I will only have two more to go.

Thursday, September 01, 2016

Why do you think I want this boat

I love Joe vs the Volcano. It is one of my all time favorite movies. I think the part on the boat expresses a lot of what I like.
J: Are you used to this?
P: What?
J: The ocean, the stars.
P: You never get used to it.  Why do you think I want this boat? All I want to do is sail away.
J: Where would you go
P: Away from the things of man.
...
J:  up till now I've lived on a tiny island called Staten Island, and I've commuted to a job in a shut up room with pumped in air, no sunshine, despicable people, and now that I've got some distance from that situation, that seems pretty unbelievable. Your life seems unbelievable to me.  All this like life, seems unbelievable to me.

I'm in Barcelona. This is about as close to the boat as I have been so far.

Friday, June 17, 2016

Biking to Work is Dangerous

I think biking to work is dangerous, but not for the reasons that just popped into your head.

I was a bit lazy this morning and took a little longer to do those things I do every morning before going to work, like feeding the chickens and the raven (yes. I have a friendly raven). So, after finally getting going on the bike you would think I would choose the fastest, easiest way to get to work to make up for leaving late, but no. You see, it was a perfect morning, cool temperatures, a blue sky, and no wind. So of course I decided to take the river route to work.

Of course I started Strava before heading out, but I'm not a typical Strava user. I really don't care about KOM, PR, or other achievements, sometimes I just like to keep a record of my rides. And like I said, I was feeling lazy this morning so I was just riding and enjoying being out on the bike, and that is where the danger comes in.

I started when my son was in scouts, well that is probably not true as there is no real beginning, but it works for this story. So, it started when my son was in scouts and they were getting ready to do a White Rim biking trip, and I volunteered to go along.


The next year I went on a trip with the scouts doing the Kokopelli trail. The White Rim and the Kokopelli were great multi day trips, but somehow I jumped from that to biking across Antarctica to the South Pole, and that was followed by a couple of bike tours, one from Utah to Oregon, and a second one going down the Oregon coast.


And that is the real danger of biking to work. I start by thinking how nice it would be to just skip going to work and spend the day out on the bike. Then the idea that it would be awesome to just forget everything else and go on a bike tour with no real destination, just each day ride to somewhere new.

Now that wouldn't be so bad, but this leads to fantasies of selling everything and buying a yacht and heading out on an around the world cruise. I imagine starting in California and sailing south along the coast of South America and through the straits of Magellan, and of course stopping in Punta Arenas to visit my friends there. Then continuing up the Atlantic coast to the Caribbean, the Bahamas, maybe up to Greenland, Iceland, Scandinavia, England, through the strait of Gibraltar and into the Mediterranean. Africa scares me, but still I would have to stop somewhere in Africa just to make sure that I get all seven continents marked off the bucket list. (I'm not a bucket list kind of guy, but since I have been to Antarctica now I feel the obligation to visit Africa, Asia, and Australia).

So somewhere I'd visit Africa, and then through the Suez Canal and into the Indian Ocean, India, Indonesia and down to Australia, up along China, Japan Russia and over to Alaska, and back down to the start.

The thing is I have already proven that I am likely to do crazy trips, and so that is why biking to work is dangerous.

Hmm, I think I need to go read Call of the Wild.

Saturday, May 21, 2016

Serving Pages and Mustache with Perfect

Ryan Collins has some great videos on how to use Perfect  to serve web pages and how to use Mustache. These were great for helping me get things going, but I prefer a written format to video, so I am going to repeat a bit of what Ryan has done. Chris Manahan has a good writes up on getting a Perfect project running on how to use MySQL with Perfect so I won't repeat that.

So here we go:

My previous blog post shows how I created classes to serve my MySQL tables as JSON. Here is my
PerfectServerModuleInit Where I  add one route to return JSON from my auto_make table.

public func PerfectServerModuleInit() {
    Routing.Handler.registerGlobally() 
   
    // Create Routes
    Routing.Routes["/auto_make"] = { _ in return AutoMakeRecord() }
}


I'm creating a web service for my app, but I also want to have a web interface that allows me to administer content for the app. So I need to serve some static pages like my stylesheet to give the look and feel of my service and then of course some dynamic pages.

To get static pages I add a route and connect it to the StaticFileHandler that is part of the PerfectLib.

public func PerfectServerModuleInit() {
    Routing.Handler.registerGlobally() 
   
    // Create Routes
    Routing.Routes["/*"] = { _ in return StaticFileHandler() }
    Routing.Routes["/auto_make"] = { _ in return AutoMakeRecord() }
}

Now I need to have a file in the webroot. So in my Xcode project I create a group called webroot and add my .css file and background image:



This is great, but to get the server to find these files we need to have them copied into the webroot in the Products Directory. So I select my CarHealthServer project and the Build Phase. Then click on the "+" and add a "New Copy Files Phase"



Then I will click on the "+" in the copy files phase and add the files that are in my webroot group. Here I have added a couple of extra files, a vehicles.html and a shop messages.mustache. I'll talk about the .mustache file later.


So now when we run our server and go to http://localhost:8181/BackView.css in my browser I get the contents of my .css file.

I want a page that will let me create an html document that will get saved in a MySQL table. So I create a file call shopmessage.mustache:

(Sorry blogger is having problems with this, and I am feeling lazy so you get a picture or this file)
   

The important things here are "{{% handler:ShopMessageHandler}}" which specifies the class that will handle the dynamic content for the mustache file, and "{{doc}}" which is supplied by the handler. Here is my ShopMessageHandler.swift class:

import PerfectLib

class ShopMessageHandler: PageHandler {

    func valuesForResponse(context: MustacheEvaluationContext, collector: MustacheEvaluationOutputCollector) throws -> MustacheEvaluationContext.MapType {
    
        var values = MustacheEvaluationContext.MapType()
        
        values["doc"] = "my shop message" 
        return values
    }
    
}

Now I need to modify the  PerfectServerModuleInit to register the ShopMessageHandler.

public func PerfectServerModuleInit() {
    
    PageHandlerRegistry.addPageHandler("ShopMessageHandler") { (r: WebResponse) -> PageHandler in return ShopMessageHandler() }
    
    Routing.Handler.registerGlobally()
    
    // Create Routes
    Routing.Routes["/*"] = { _ in return StaticFileHandler() }
    Routing.Routes["auto_make"] = { _ in return AutoMakeRecord() }
}

In the valuesForRespose I create a dictionary of the values to be used in the .mustache file. In this case there is just one value and it is hard coded to a static string. But this now gives me the framework to develop my service.

Now when I go to http://localhost:8181/shopmessage.mustache I get this:

Friday, May 20, 2016

Working with Swift subclasses

I decided to build the web service for my iOS and Android app using Perfect which is a Swift server implementation. I am using MySQL to host a database and wanted to a nice way to get the database tables written out as JSON. I had some problems but here is what I came up with:

My first attempt was to create a base class that I could subclass for each table type and do the read/write database operations and the JSON operations in the base class. But I ran into a lot of problems getting the base class to access the overridden properties and methods of the subclasses. Then I discovered this. Fist I create a simple protocol that all the record classes will use:

protocol DatabaseRecord : RequestHandler {
    var sqlTableName: String {get}
    var loaded: Bool {get set}
    func loadRow(row: [String])
    func getDictionary() -> [String : String]
    func load(forName:String)
    func load(forID:Int)
    func getAll() -> [AnyObject]
    init()
}

Then I create an extension to the protocol so all of this will get added to all of the classes that implement the DatabaseRecord protocol.

extension DatabaseRecord {

The methods here to load from the database don't seem like a big deal, but this just didn't work as a super class because despite all my google searching and efforts I couldn't get the base class to call the subclass methods or get the sqlTableName from the sub classes. But as an extension this jus works without any strange code.

    func loadFromDatabase(query:String) {
        var mysql = MySQLConnection.mysql;
        MySQLConnection.connectToMySQL()
        defer {
            mysql.close()
        }
        if mysql.query(query) {
            if let results = mysql.storeResults() {
                if results.numRows() >= 1 {
                    if let row = results.next() {
                        loadRow(row)
                        return
                    }
                }
            }
        }
    }
    func load(forName:String) {
        self.loadFromDatabase("SELECT * FROM \(sqlTableName) WHERE name = \"\(forName)\"")
    }
    func load(forID:Int) {
        self.loadFromDatabase("SELECT * FROM \(sqlTableName) WHERE id = \"\(forID)\"")
    }

This next method was where I had the most problems. I tried using Self, dynamicType, and everything else I could think of to get the sqlTableName from the subclasses and got it going but the creating objects of my subclasses and adding them to an array that I would return seemed impossible. Now as an extension the sqlTableName just works, and I can create a new object of the correct class using self.dynamicType.init() and add it to the array. 

    func getAll() -> [AnyObject] {
        var records = [AnyObject]()
        var mysql = MySQLConnection.mysql;
        
        MySQLConnection.connectToMySQL()
        defer {
            mysql.close()
        }
        if mysql.query("SELECT * FROM \(sqlTableName)") {
            if let results = mysql.storeResults() {
                results.forEachRow { row in
                    let obj = self.dynamicType.init()
                    obj.loadRow(row)
                    if let o = obj as? AnyObject {
                        records.append(o)
                  }
                }
            }
        }
        return records
    }

PerfectLib has a JSON encoder but when I tried to use it, it would crash. It was late and the JSON that I need to generate was simple so I just quickly wrote this to create the JSON for my table:

    func encodeAsJSON(dicts:Array<[String:String]>) -> String {
        var str: String = "["
        for dict in dicts {
            var first = true
            for (key, value) in dict {
                if !first {
                    str.appendContentsOf(",")
                } else {
                    first = false
                }
                str.appendContentsOf("{\"\(key)\":\"\(value)\"}")
            }
        }
        str.appendContentsOf("]")
        return str
    }

Now I can add a request handler to the extension and now all my database record classes have a easy way to take a http get request and turn it into JSON array.

    func handleRequest(request: WebRequest, response: WebResponse) {
        let records = getAll()
        var dicts = Array<[String:String]>()
    
        for rec in records {
            if let r = rec as? DatabaseRecord {
                let dict = r.getDictionary()
                dicts.append(dict)
            }
        }
        response.appendBodyString(encodeAsJSON(dicts))
        response.requestCompletedCallback()
    }
}

So then I have a simple Swift class representing a SQL database record. For example:

/*
auto_make SQL table
 +-------------+------------------+------+-----+---------+----------------+
 | Field       | Type             | Null | Key | Default | Extra          |
 +-------------+------------------+------+-----+---------+----------------+
 | id          | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
 | name        | varchar(255)     | YES  |     | NULL    |                |
 +-------------+------------------+------+-----+---------+----------------+
 */
class AutoMakeRecord: DatabaseRecord {
    var id: Int?
    var name: String = ""
    var loaded: Bool
    var sqlTableName: String {
        return "auto_make"
    }
    
    func loadRow(row: [String])
    {
        id = Int(row[0]) ?? -1
        name = row[1]
        loaded = true
    }
  
    func getDictionary() -> [String : String] {
        var dict = [String: String]()
        dict["id"] = String(id!)
        dict["name"] = name
        return dict
    }
    
    required init() {
        loaded = false
    }
}

Now a public method that registers the routes.  

public func PerfectServerModuleInit() {
    Routing.Handler.registerGlobally() 
   
    // Create Routes
    Routing.Routes["/auto_make"] = { _ in return AutoMakeRecord() }
}

And it is easy to create additional classes for database tables and add them to the routes.  Of course I will want to create http handlers that will allow to more than just dump out tables to JSON, but this now gives me the base I need to create the rest of my web service.

My Bicycle Store