Archive for the ‘code’ Category.
July 4, 2012, 12:52
I figured I would try out developing on Mac Os making an iPhone app. My first experience on the Hackintosh building an application ( my first blog post from it as well ). Anyway, I downloaded the SDK got xCode going and followed some Hello world tutorial. I feel Hello world is just too simple to get a feel for the environment and Objective-C. So I decided to port my HandiCap Android sample to the iPhone, should give me enough time to play with xCode and get a feel for it.
As I started up xCode and started coding first I noticed was the keyboard shortcuts which are strange when using PC keyboard on the Mac, I run the Mac in a VM. I understand I can map that anyway I want so that shouldn’t be a problem if I decide to do some more development. As I knew this sample was going to be short I didn’t bother changing it. When using xCode it doesn’t really feel like an IDE rather a collection of different tools. I had a hard time finding out how to set controls on a view in the beginning once I got the appropriate tools open it was pretty much straight forward. One thing that I don’t really understand is when you link controls to the File owner, why does that link your controls to your code view ? why not link that to the view itself as that is where the code resides ? I guess I will figure that out later as time goes on.
So let’s take a look at the code, first you need to reference the controls in the header file that you already setup in the Interface builder. Yes you need to do that by hand, it is not taken care of by the IDE, more integration is needed on the IDE’s behalf if you ask me. Note the UITextFieldDelegate tag on the controller, this one is needed to hide the keyboard when Return is pressed along with code in the class file.
#import <UIKit/UIKit.h>
@interface HandiCapViewController : UIViewController <UITextFieldDelegate>
{
// First half
IBOutlet UILabel *lbPlayer1;
IBOutlet UITextField *txPlayer1;
IBOutlet UILabel *lbPlayer2;
IBOutlet UITextField *txPlayer2;
// Second half
IBOutlet UILabel *lbWinPlayer1;
IBOutlet UITextField *txWinPlayer1;
IBOutlet UILabel *lbWinPlayer2;
IBOutlet UITextField *txWinPlayer2;
}
- (IBAction) btCalculate_Clicked:(id)sender;
@end
Then we start coding in the class ( .m ) file
#import "HandiCapViewController.h"
#include <tgmath.h>
@implementation HandiCapViewController
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
// Disable the two result fields
txWinPlayer1.userInteractionEnabled = FALSE;
txWinPlayer2.userInteractionEnabled = FALSE;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn’t have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren’t in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
// Shut down the keyboard
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
NSLog( @“textFieldShouldReturn start”);
// This code should be made dynamic instead of ugly if / else
if( textField == txPlayer1 )
{
[txPlayer1 resignFirstResponder];
}
else if( textField == txPlayer2 )
{
[txPlayer2 resignFirstResponder];
}
return TRUE;
}
// Calculates handicap
-(void) calculate:( double *) pdaPlayers;
{
// STRONGER is lower handicap
// See who is better rated coming in,
Boolean bStrongerFirst = pdaPlayers[0] < pdaPlayers[1];
// Holds results
double strong_race, weak_race;
if( bStrongerFirst )
{
// What’s the race
weak_race = MAX(2, 6 – floor( pdaPlayers[1] ));
strong_race = weak_race + round( pdaPlayers[1] – pdaPlayers[0] );
// set the slots before returning
pdaPlayers[0] = strong_race;
pdaPlayers[1] = weak_race;
}
else
{
// What’s the race
weak_race = MAX(2, 6 – floor( pdaPlayers[0] ));
strong_race = weak_race + round( pdaPlayers[0] – pdaPlayers[1] );
// Set the slots before returning
pdaPlayers[0] = weak_race;
pdaPlayers[1] = strong_race;
}
}
- (IBAction) btCalculate_Clicked:(id)sender
{
NSLog( @“Button clicked start”);
double dPlayerOne = [txPlayer1.text doubleValue];
double dPlayerTwo = [txPlayer2.text doubleValue];
// What is the race
double players[2] = { dPlayerOne, dPlayerTwo };
// call the function to calculate
[ self calculate: players ];
// Display it
txWinPlayer1.text = [NSString stringWithFormat:@“%.0f”, players[0]];
txWinPlayer2.text = [NSString stringWithFormat:@“%.0f”, players[1]];
NSLog( @“Button clicked end”);
}
- (void)dealloc
{
// First half
[lbPlayer1 release];
[txPlayer1 release];
[lbPlayer2 release];
[txPlayer2 release];
// Second half
[lbWinPlayer1 release];
[txWinPlayer1 release];
[lbWinPlayer2 release];
[txWinPlayer2 release];
[super dealloc];
}
@end
I disabled the two result fields in code in the viewDidLoad function as it did not work to set Accessibility Enabled = false from the Interface builder, I don’t know why.
The textFieldShouldReturn function implements the functionality that goes with UITextFieldDelegate in the header file. Simply when the user is done with input in the two text fields he can hit return on the keyboard and the keyboard gets hidden again.
The calculate function is a straight port from the Android code, I only had to include tgmath.h and use the math functions from there.
The btCalculate_Clicked is where all the functionality happens, simply convert the text input from string to double then call calculate and display in the result fields. There is no error checking on the input as I was feeling lazy.
I’m using NSLog to log out to the console, if you want to create a program for production you should maybe write your own logging or use third party library to be able to control the logging level both debug and runtime.
Lastly we have dealloc function where we release the resources the code has been referencing. As pointed out by my friend Mick they are introducing automatic dellocations by the compiler called ARC ( Automatic Reference Counting ) in the near future. That should be welcomed by objective-c developers as they don’t have to keep track of and releasing resources, fewer bugs and more productivity. Some changes discussed on Stack Overflow This experience reminded me of other c / c++ coding with a twist I find the [ class function:param ] syntax strange, but I’m sure I can get used to that.
Below is the app in action and here is the code if anybody is interested HandiCap xCode project

October 27, 2011, 17:32
In order to release your app in the Android market place you need to digitally sign it. The instructions are here. But in short I will show you what you need from the command line, you won’t have to read all the instructions. First off make your app .apk name something different then what your going to use in the end. As the process requires the input and output to have different file names.
Lets take a look, this example is from DOS command line
Create the signature key
C:\Temp> keytool -genkey -v -keystore c:\temp\release-key.keystore -alias MyAlias -keyalg RSA -keysize 2048 -validity 10000
Sign using the key
C:\Temp> jarsigner -verbose -keystore release-key.keystore release.MyApp.apk MyAlias
Verify that it took
C:\Temp> jarsigner -verify -verbose release.MyApp.apk
Run the align tool as recommended
C:\Temp> zipalign -v 4 release.MyApp.apk MyApp.apk
And your all done, now publish it and start watching the downloads.
August 29, 2011, 10:13
I found out that I had not played with Text to speech in .net yet. So naturally I went to take a look how easy or hard it is to use TTS in C#. It turns out the hardest part is to find the download link for the TTS install. Its hard to understand how Microsoft sometimes seems to hide download links. Once you find the SAPI SDK page, you would think they would have download links, but not so. However you do not need the whole SDK just to do Text to speech. You only need the TTS download which has a much smaller footprint. But again, where is the download link… ? I found one Microsoft page that doesn’t make it clear, and another third party page that I used to download the TTS install.
And now for the code it self, it’s very straight forward. After installing TTS add reference to your project, choose the COM “Microsoft Speech Object Library” that will create interop dll for your project. Add a reference to the speech library in code and the Hello world sample is only two lines of code.
using System;
//
using SpeechLib;
namespace tester
{
class Program
{
static void Main(string[] args)
{
SpVoice myVoice = new SpVoice();
myVoice.Speak(“Hello world”);
}
}
}
Another choice is to do the same without using the COM object, as COM is heavy. In that case add reference to System.Speech .net library and the code will look like this.
using System;
//
using System.
Speech.
Synthesis;
namespace tester
{
class Program
{
static void Main(string[] args)
{
SpeechSynthesizer synth = new SpeechSynthesizer();
synth.Speak(“Hello World”);
}
}
}
June 4, 2011, 13:32
I had to fix an old plugin I made some time back, I did actually post about it here Java Authenticated POST. So why bring it up again, a good question I say. As Twitter changed their authentication sometime late last year ( Nov 2010 ? ). All programs using the old authentication stopped working. I hadn’t had / given myself time to look at the broken plugin. What the TeamCity twitter plugin does it to tweet when the TeamCity server starts and ends builds. If you follow that account you get notified on Twitter without having to open up your email box to see how your builds are doing.
I went googling about the new authentication and found a nice snippet on StackOverflow The snippet uses Twitter4J library to make the task really simple, check them out. The best part is that Twitter4J only needs Java 1.4 to run. That’s great as my TeamCity server only has Java 1.5 and not the newer 1.6, further as an added bonus their core jar is only 280k, that’s all I needed. Below is my code modified from the StackOverflow sample. It works fine if you are only posting to one account. The tokens and keys can be found on your Twitter app page. If you need to post for different users from your application then your code needs to take that into account. If you want the source of the plugin or all 3 plugins I have created, you can run over to GitHub and pick it up. I made it public domain, open source, whatever you want to call it.
import twitter4j.Twitter;
import twitter4j.TwitterFactory;
import twitter4j.conf.*;;
// Updates the twitter account
public static void sendTweet( String psText )
{
try
{
// Configuration
ConfigurationBuilder confbuilder = new ConfigurationBuilder();
confbuilder.setOAuthAccessToken(CxGlobal.ACCESS_TOKEN_KEY)
.setOAuthAccessTokenSecret(CxGlobal.ACCESS_TOKEN_SECRET)
.setOAuthConsumerKey(CxGlobal.CONSUMER_KEY)
.setOAuthConsumerSecret(CxGlobal.CONSUMER_SECRET);
// get the interaction object
Twitter twitter = new TwitterFactory(confbuilder.build()).getInstance();
// send
twitter4j.Status status = twitter.updateStatus( psText );
//
//System.out.println("*** Response=" + status.getText() );
}
catch( Exception ex )
{
System.out.println( “***ERROR=” + stack2string( ex ));
LOG.info( “***ERROR=” + stack2string( ex ) );
}
}
Edit, the 3 plugins have now been added to the official TeamCity PlugIn page
January 26, 2011, 20:42
I had a need to store some configuration data that is non XML compliant in my .net configuration file. As the configuration file is XML file I settled on storing the data in Base64 and then converting it back after it’s read from the configuration file. First we take the string and convert it to bytes then we convert the bytes to Base64 string that will be written to the configuration file. Reverse when you want to read the string from the configuration file.
And now for the code, as a UnitTest
// C#
string original =
“&at;=@|”=’_EMPTY_’”;
// base64 value = JmF0Oz1AfCcnPSdfRU1QVFlfJw==
// to bytes and back test
byte[] dBytes = new System.Text.UTF8Encoding().GetBytes( original );
System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
string str = enc.GetString(dBytes);
// compare
Assert.AreEqual( original, str);
// This is the string to put in the configuration file now Base64 formatted
string base64String = Convert.ToBase64String( dBytes );
// config string base64 value=JmF0Oz1AfCcnPSdfRU1QVFlfJw==
Console.WriteLine( “config string base64 value=”+ base64String );
// Convert Base64 back to a normal string, this needs to be done after reading
// the base 64 string from the config file
byte[] nonBase64bytes = Convert.FromBase64String( base64String );
// string from bytes
string fromBytes = new System.Text.UTF8Encoding().GetString(nonBase64bytes);
// Make sure it still adds up with the original
Assert.AreEqual(original, fromBytes );
October 12, 2010, 08:27
I wanted to play short sound bites in a Android application, when playing sounds on the Media player there is a lag as the Media player needs to allocate memory, load the resource etc. If you need to play short sounds in response to button click or when shooting a gun in your game you need it to play instantly in response to what the user just did. In that respect SoundPool is the way to go, it allows preloading the soundbites and gives instant access to the sounds as needed. I created a simple convenience class for it as seen below.
//
package us.
kristjansson.
android.
util;
//
import android.media.AudioManager;
import android.media.SoundPool;
import android.app.Activity;
//
import java.util.HashMap;
//
import us.kristjansson.android.R;
public class CxMediaPlayer
{
private SoundPool mShortPlayer= null;
private HashMap mSounds = new HashMap();
// Constructor
public CxMediaPlayer( Activity pContext )
{
// setup Soundpool
this.mShortPlayer = new SoundPool(4, AudioManager.STREAM_MUSIC, 0);
// 0-9 Buttons
mSounds.put( R.raw.button_1, this.mShortPlayer.load(pContext, R.raw.button_1, 1) );
mSounds.put( R.raw.button_2, this.mShortPlayer.load(pContext, R.raw.button_2, 1) );
mSounds.put( R.raw.button_3, this.mShortPlayer.load(pContext, R.raw.button_3, 1) );
mSounds.put( R.raw.button_4, this.mShortPlayer.load(pContext, R.raw.button_4, 1) );
mSounds.put( R.raw.button_5, this.mShortPlayer.load(pContext, R.raw.button_5, 1) );
mSounds.put( R.raw.button_6, this.mShortPlayer.load(pContext, R.raw.button_6, 1) );
mSounds.put( R.raw.button_7, this.mShortPlayer.load(pContext, R.raw.button_7, 1) );
// Others
mSounds.put( R.raw.delete_5, this.mShortPlayer.load(pContext, R.raw.correct_answer, 1) );
mSounds.put( R.raw.delete_5, this.mShortPlayer.load(pContext, R.raw.wrong_answer, 1) );
}
// Plays the passed preloaded resource
public void playShortResource( int piResource )
{
int iSoundId = mSounds.get( piResource );
this.mShortPlayer.play( iSoundId, 0.99f, 0.99f, 0, 0, 1 );
}
// Cleanup
public void Release()
{
// Cleanup
this.mShortPlayer.release();
this.mShortPlayer = null;
}
}
Then all you need in your Activity is to initiate the player class and call playShortResource when you need a sound played. Your resources should be available in the res/raw directory.
// The media player – OnCreate
mxMediaPlayer = new CxMediaPlayer( this );
// Play the desired sound – OnClick
mxMediaPlayer.playShortResource( R.raw.button_1 );
// Make sure to release resources when done – OnDestroy
mxMediaPlayer.Release();