Wednesday, September 12, 2012

Spring Async and Future

I had a pesky reporting job that was going to be slow no matter what sql-fu I was going to come up with.  I knew that Spring had asynchronous tasks which I had used before but they kinda sucked.  Lots of manual bean building and xml config nasties.  But behold, I came across a nice annotation I was not aware of:

@Async


And I was off to the races.

I'll update with my example later.  For now, I give you the best blog entry to be found as of yet:

http://blog.inflinx.com/2012/09/09/spring-async-and-future-report-generation-example/

Thanks, Random Thoughts.


Tuesday, April 10, 2012

AVPlayer audio problems?

I'm finally working on an iphone app.  Yes, welcome to 2008!  And this one goes out to anyone who can't get their audio to play on their device, but it will work on simulators!  Fun!

Grrrrrr.

So here's the magic line of objective c that will get your video to play sound on a device.  Are you ready?  Here goes:

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:NULL];

I'm staring at this line of code.  It appears to say that any errors with audio, ignore them.  So now your audio will work.  Yay, Apple.  This is the future of app developement?

Sunday, January 29, 2012

ReCaptcha without plugins

So I'm not that fantastic at reading documentation.  But let's face it.  Coders are not that great at spelling things out.  Exhibit A:

http://code.google.com/apis/recaptcha/docs/verify.html

There is nothing on this API explanation that explains that you can't make this call from javascript.  Although I should have known that putting both public and private keys in JS seems a little insecure.

Ulitimately, you gotta make the reCaptcha verification call from the server-side.  Since I'm a java/spring guy I made a controller that does that.  This is the step that would have been obvious if I just looked more carefully at the example plugins.  But still.

@Controller
public class RecaptchaController {

    public static final String PUBLIC_KEY = "XXX";
    private static final String PRIVATE_KEY = "YYY";
    private static final String RECAPTCHA_URL = "http://www.google.com/recaptcha/api/verify";
   
    @RequestMapping(value="/recaptcha", method=RequestMethod.POST)
    public void checkServer(@RequestParam("remoteip") String remoteip, @RequestParam("challenge") String challenge,
                            @RequestParam("response") String response, HttpServletResponse httpResp){
           
        HttpClient httpClient = new HttpClient();
        PostMethod post = new PostMethod( RECAPTCHA_URL );

        post.addParameter("privatekey", PRIVATE_KEY);
        post.addParameter("remoteip", remoteip);
        post.addParameter("challenge", challenge);
        post.addParameter("response", response);
       
        String resp = "false";
        try {
            httpClient.executeMethod(post);
            resp = getResponseAsString(post);
        } catch (Exception e) {
            resp = "false";
        }
       
        if(resp.startsWith("false")){
            resp = "ERROR";
        }else{
            resp = "SUCCESS";
        }
       
        try {
            OutputStreamWriter writer = new OutputStreamWriter( httpResp.getOutputStream() );
            writer.write(resp);
            writer.close();
        } catch (IOException e) {
            // do nothing
        }
       
    }
   
    private String getResponseAsString(HttpMethod hm) throws IOException {
        InputStream inputStream = hm.getResponseBodyAsStream();

        StringWriter writer = new StringWriter();
        IOUtils.copy(inputStream, writer, "UTF-8");

        return writer.toString();
    }  
}

Thursday, November 10, 2011

Mobile Javascript Links

Before I forget, I wanted to pass on some helpful bookmarks
for mobile javascript:



Here's how you do that mini-scroll on page load to hide the address bar:

   setTimeout(function(){
       // Hide the address bar!
       window.scrollTo(0, 1);
   }, 0);


Here's a very fancy network detector:

/**
 * Original idea:
 * http://stackoverflow.com/questions/4697470/detecting-wifi-connectivity-in-mobile-safari
 *
 * but more importantly here:
 * http://www.thefutureoftheweb.com/blog/image-onload-isnt-being-called
 *
 */
metai.checkNetwork = function( contentId ){

       var imageEl=document.
       createElement('img');
       var imageurl=hostURI+contextRoot+'/image/mobile/login/caution.png';
       imageEl.style.visibility='hidden';
       //imageEl.onload=metai.networkLoad;
       //var imagetook=0;
       var startDate=new Date();
       imageEl.onload=function(){
           var endDate=new Date();
           var latency=endDate.getTime()-startDate.getTime();
           //alert(latency);

           if( latency < 200 ){
               playFast( contentId );
           }else{
               playSlow( contentId );
           }
       }

       imageEl.src=imageurl+'?r='+Math.round(Math.random()*1000);
       document.body.appendChild(imageEl);

}

Tuesday, November 1, 2011

List of Helpful Mac Apps

I'm starting this post to collect the most useful OSX utilities as I run across them.
  1. WMA converter:  http://www.nch.com.au/switch/index.html

Friday, October 28, 2011

Smell My Awesomeness

This week I launched my first mobile product.  It's a simple html/javascript product optimized for mobile devices.  I'm pretty proud of it, but the content is NSFW so I'm not forwarding a direct link yet.  But here's some customer feedback that makes me proud:

"Only dissapointment is that it works infinitely better and more fluidly than the actual site itself – and my 3G connection is poor in comparison too!"

Yes, I am one proud papa this week.

Wednesday, October 26, 2011

Why Mobile Safari is the IE6 of Today

I just completed my first mobile app.  Yes, I'm at least two years behind the curve.  What else is new?  Here's what I learned:
  1. JQuery Mobile is a waste of time.
  2. Everything works as expected on Android Mobile and Tablets.
  3. Safari Mobile will not respond to javascript "focus" events.
Let me explain in more detail.

Regarding #1:

I really wanted to like JQuery Mobile because I'm a big believer in JQuery.  But like JQuery UI, the code is very heavy and their CSS is very restrictive.  But the mobile product takes it one step further by adding animations that are SLOW.  It desperately tries to mimic native application behaviors like sweeping screen transitions that users ultimately don't care about especially if they hurt performance.

Regarding #2:

That's just it.  On Android Mobile browsers, everything just works.

Regarding #3:

This quora post explains the problem well:

http://www.quora.com/Mobile-Safari-iPhone-or-iPad-with-JavaScript-how-can-I-launch-the-on-screen-keyboard

And the money answer by Allen Pike says it all:  "focus() doesn't bring up the on-screen keyboard in Mobile Safari by design. A lot of sites would do focus() unnecessarily and bringing up the keyboard is slow/intrusive."

Intellectually, I understand this point of view.  But it's an attitude that onlyt a company with 90% market share gets to have.  And it sucks for the rest of us.