iPhone users able to build a shinier world, one turd at a time

This blog usually focuses on software development, but I can’t resist sharing this with all of you out there.  Have a good laugh!

MaxPowerSoft Puts a New Polish on an Old Adage: You Actually Can Polish a Turd

This video was embedded using the YouTuber plugin by Roy Tanck. Adobe Flash Player is required to view the video.

Polish It now available at the iPhone App Store

SAN DIEGO, CA (May 24, 2010) – MaxPowerSoft (www.maxpowersoft.com) today announced the release of Polish It, an iPhone application designed to facilitate “a shinier world, one turd at a time”. Available for $0.99 at Apple’s iPhone App Store, ‘Polish It’ is both a literal and cute/comedic take on the old and well-known phrase “You can’t polish a turd”. Your goal is simple: Choose a turd you like, and polish it! Utilize the touchscreen and your finger for polishing, tilt the phone to maneuver, and snap a photo at anytime to share.

“We wanted to reach out and give frustrated workers, students, and really all curious people in general, the powerful ability to truly polish a turd,” says Nic Danielson, Director of Marketing. “MaxPowerSoft has created an innovative new technology that allows one to therapeutically accomplish the task of polishing turds in the palm of your hand, no matter where you are, and on a whim to boot – most importantly, it can be done without the need for any sanitization processes.  There really is nothing else like it in the market, or the world for that matter.”

Features of Polish It include:

  • Objects rendered in full 3D.
  • Choose from over 10 objects to polish.
  • Simple controls: Touch to polish, Tilt phone to maneuver.
  • Snap a photo and send to your friends.
  • More features to come.

Pricing and Availability:

Polish It is available for $0.99 at the iPhone App Store:

http://itunes.apple.com/us/app/polish-it/id345199287?mt=8

, , , , , , ,

1 Comment

Android WebView and the Indeterminant Progress Solution

I’ve seen a multitude of posts on how to embed the Android WebView object and how to use the built-in feature request PROGRESS, but I’ve yet to come across a demonstration on just how simple it is to integrate a ProgressDialog object. I specifically needed this for one of my projects because I did not want the title bar to render in my application. If the title is not rendered, then the Window Feature Request progress bar and indeterminant functions will not render at all.

So here is how to do it! Trust me it’s absolutely simple!

Code snippet basics:

import android.app.ProgressDialog;
//in the class...
private ProgressDialog progressBar;
 
//when you want the dialog to show the first time.
progressBar = ProgressDialog.show(Main.this, "MaxPowerSoft Example", "Loading...");
 
//when you want the progressbar to disappear
if (progressBar.isShowing()) {
   progressBar.dismiss();
}

Here is how it is done in your project.

/res/values/strings.xml

?Download strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
   <string name="app_name">MaxPowerSoft Example</string>
   <string name="webview">webview</string> 
</resources>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.maxpowersoft.example"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".Main"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-sdk android:minSdkVersion="4"
              android:targetSdkVersion="4" />
</manifest>

/res/layout/main.xml

?Download main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <WebView android:id="@string/webview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1" />
</LinearLayout>

Main.java

?Download Main.java
package com.maxpowersoft.example;
 
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
 
public class Main extends Activity {
    private WebView webview;
    private static final String TAG = "Main";
    private ProgressDialog progressBar;  
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        requestWindowFeature(Window.FEATURE_NO_TITLE);
 
        setContentView(R.layout.main);
 
        this.webview = (WebView)findViewById(R.string.webview);
 
        WebSettings settings = webview.getSettings();
        settings.setJavaScriptEnabled(true);
        webview.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
 
        final AlertDialog alertDialog = new AlertDialog.Builder(this).create();
 
        progressBar = ProgressDialog.show(Main.this, "MaxPowerSoft Example", "Loading...");
 
        webview.setWebViewClient(new WebViewClient() {
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                Log.i(TAG, "Processing webview url click...");
                view.loadUrl(url);
                return true;
            }
 
            public void onPageFinished(WebView view, String url) {
                Log.i(TAG, "Finished loading URL: " +url);
                if (progressBar.isShowing()) {
                    progressBar.dismiss();
                }
            }
 
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                Log.e(TAG, "Error: " + description);
                Toast.makeText(activity, "Oh no! " + description, Toast.LENGTH_SHORT).show();
                alertDialog.setTitle("Error");
                alertDialog.setMessage(description);
                alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        return;
                    }
                });
                alertDialog.show();
            }
        });
        webview.loadUrl("http://www.google.com");
    }
}

, , ,

3 Comments

Could not send unregistration request to daemon

During a debug process have you seen any of the following lines in your debugger/console logs?

void CLClientInvalidate(__CLClient*)",could not send unregistration request to daemon

or…

CLClientRegister: could not send registration request to daemon

If so, you’ve probably already seen this Apple support link:  http://discussions.apple.com/message.jspa?messageID=8408930

Well, I’m just going to validate a few things here for you.  (Before continuing this… check your code after briefly reading this blog.

  1. You will have to restore your iPhone.  (This is the solution that worked for me).  Please post a comment if you find a better solution.
  2. If you are coding using CLLocationManager you will more than likely notice that you only get 1 set of GPS values before the message starts appearing.  Also, the CLLocationManager startUpdatingLocation method will only call your delegate once.  (That is what was happening on my iPhone).
  3. If you dig through your iPhones “crash logs” via the Organizer application, you’ll more than likely witness that many applications are crashing.

I tried a multitude of workarounds and the only thing that sadly worked was a “restore” which took over 1 hour to complete.  I will say this, my iPhone runs a lot faster now!

, , , , ,

4 Comments

Apple iPhone Web Kit with Activity Indicator

Welcome to the club of searching for an overly simple UIWebView a.k.a. WebKit example! In this example, I’ll show you simply how to hand code a quick UIWebView into your program as well as to add a UIActivityIndicatorView a.k.a. an activity indicator. Without jabbing Apple too hard here, the documentation is pretty bad and that is why it’s nice to have an example just shown to you as-is. I hope this example helps shine a light on the situation for anyone wanting to implement a nice and quick Apple iPhone WebKit solution.

 
#import <UIKit/UIKit.h>
 
@interface FirstViewController : UIViewController <UIWebViewDelegate>
{
	UIWebView *myWebView;
	UIActivityIndicatorView *activityIndicator;	
}
/*
Inside the @implementation FirstViewController ... 
*/
- (void)viewDidLoad { //We have a NIB file in play here, so I dropped the loadView here.  Just make sure that your loadView is not getting called twice!
    [super viewDidLoad];
    [self loadView];
}
 
- (void)loadView {
	UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
	self.view = contentView;	
 
	CGRect webFrame = [[UIScreen mainScreen] applicationFrame];
	webFrame.origin.y = 0.0f;
	myWebView = [[UIWebView alloc] initWithFrame:webFrame];
	myWebView.backgroundColor = [UIColor blueColor];
	myWebView.scalesPageToFit = YES;
	myWebView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
	myWebView.delegate = self;
	[self.view addSubview: myWebView];
	[myWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.maxpowersoft.com/"]]];
 
	activityIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
	activityIndicator.frame = CGRectMake(0.0, 0.0, 40.0, 40.0);
	activityIndicator.center = self.view.center;
	[self.view addSubview: activityIndicator];
}
 
- (void)dealloc {
	[activityIndicator release];
	[myWebView release];
        [super dealloc];
}
 
#pragma mark WEBVIEW Methods
 
- (void)webViewDidStartLoad:(UIWebView *)webView
{
	// starting the load, show the activity indicator in the status bar
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	[activityIndicator startAnimating];
}
 
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
	// finished loading, hide the activity indicator in the status bar
	[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
	[activityIndicator stopAnimating];
}
 
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
	// load error, hide the activity indicator in the status bar
	[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
 
	// report the error inside the webview
	NSString* errorString = [NSString stringWithFormat:
							 @"<html><center><br /><br /><font size=+5 color='red'>Error<br /><br />Your request %@</font></center></html>",
							 error.localizedDescription];
	[myWebView loadHTMLString:errorString baseURL:nil];
}

That is all there is to it. It’s really simple as you can see. Feel free to copy and paste accordingly.

, , , , ,

7 Comments

Zend RESTful XML Generic Functions

It has been argued that the Zend RESTful API should not only automate the JSON data returned (which it does a fine job of), but automate the XML data. Unfortunately, the Zend engine doesn’t do this for REST. The solution is left to the developer to implement their own strategy. In my opinion, there is no better place for a simple recursive function that will dynamically crawl the returned objects and arrays and generate XML in a way that just makes sense. As was promised in a comment from one of my previous blogs, here is a set of functions that works well for dynamically generating XML from your PHP objects and arrays. It’s been pointed out that this process should have been included in the Zend framework. As of this writing, I believe that it still has not been implemented. Anyways, here it is. Take note that you really only need two functions from this post getXML(…) and _xmlHelper(…)

abstract class BaseController extends Zend_Rest_Controller
{
//Please know that the init() method has been snipped out.	
 
	public static function getXML($obj)
    {
    	$doc = new DOMDocument();
		$doc->formatOutput = true;
		$root_element = $doc->createElement("response");
		$doc->appendChild($root_element);
 
    	foreach($obj as $var => $value) {
        	$statusElement = $doc->createElement($var);
			if (!is_array($value)) {
				$statusElement->appendChild($doc->createTextNode($value));
				$root_element->appendChild($statusElement);
			} else {
				BaseController::_xmlHelper(&$doc, &$root_element, &$statusElement, &$value);
			}
		}
		print $doc->saveXML();
    }
	public static function _xmlHelper(&$doc, &$root_element, &$statusElement, &$value) {
		if (is_array($value)) {
			foreach ($value as $key => $val) {
				if (is_array($val)) {
					BaseController::_xmlHelper(&$doc, &$root_element, &$statusElement, $val);
				} else if (is_object($val)) {
					$se = $doc->createElement(str_replace('object','',get_class($val)));
					$arr = get_object_vars($val);
					BaseController::_xmlHelper(&$doc, &$root_element, &$se, $arr);
					$root_element->appendChild($se);
 
				} else {
					//print $key . " => " . $val . "\n";
					$se = $doc->createElement($key);
					$se->appendChild($doc->createTextNode($val));
					$statusElement->appendChild($se);
				}
			}
			//print_r($value);
		} else {
			$statusElement->appendChild($doc->createTextNode($value));
			$root_element->appendChild($statusElement);
		}
	}
}

Now the only thing left to do is show an example implementation.

class VersionController extends BaseController 
{ 
/*  implement the methods as show in the blog referenced at the top of this blog post */
public function init()
    {
       $this->view->hello = array('a'=>'1', 'b'=>'2');
    }
}

Now, the last thing to do is edit the view for the XML document which would be in this case:

/application/views/scripts/version/index.xml.phtml

The index.xml.phtml should then only contain:

<?php
BaseController::getXML($this);
?>

This will automate the process of generating the XML data you want returned. It’s an easy way to quickly and effectively get XML without having to rebuild the entire wheel. Feel free to modify and distribute.

, , ,

2 Comments