Objective C ASynchronous Http Request Wrapper

 Development, Ios  Comments Off on Objective C ASynchronous Http Request Wrapper
Oct 232011
 

So having worked on two apps now that required many requests to web servers to be made in the background, I decided to write a simple to use wrapper around the more complex parts which exposes what I hope is a clear api.

The basic concept is an extension to NSOperation overriding the methods:

- (void)start;
- (BOOL)isConcurrent;
- (BOOL)isFinished;
- (BOOL)isExecuting;

I aslo made some simple Http Request and response wrappers and a protocol for receiving the responses called HttpResponseDelegate


@protocol HttpResponseDelegate

@required
- (void)requestResponseRecieved:(HttpResponse *)res;

@optional
- (void)requestResponseError:(HttpResponse *)res;
- (void)requestFailed:(NSError *)err;
- (void)request:(HttpRequest *)req AndOpCancelled:(HttpOperation *)op;
@end

The wrapper will let you send both post and Get requests which are cancelable and will be performed on background threads; although it doesn’t yet allow for the posting of multipart data such as images, but I plan to add that in time. I know there are other libraries out there for this kind of thing, but I wanted to do it for myself as a personal experiment and project. I have put the code up on git hub. Feel free to use it as you wish Git Hub Repo

Basic Usage

Just to give a quick usage example:

in a viewController implementing the HttpResponseDelegate protocol you would do something along the lines of :

- (void)someMethod{
//this is a singleton class that manages adding ops to a single operation que
HttpSync * httpFactory = [HttpSync getSharedInstance];
HttpRequest * req = [[HttpRequest alloc]initWithUrl:@"http://apple.com"];
HttpRequest * req2 = [[HttpRequest alloc]initWithUrl:@"http://google.com"];

//send some params
[req2 setParamWithKey:@"someparam" AndValue:@"somevalue"];

//change to POST req.method = HTTP_METHOD_POST;
//default method is GET

req.method = HTTP_METHOD_GET;
//make the operations possibly could add this functionality to the HttpSync class in future
HttpOperation * httpOp = [[HttpOperation alloc] initWithRequest:req AndResponseDelegate:self];
HttpOperation * httpOp2 = [[HttpOperation alloc] initWithRequest:req2 AndResponseDelegate:self];
[httpFactory sendOperation:httpOp];
[httpFactory sendOperation:httpOp2];
[req2 release];
[req release];
[httpOp release];
[httpOp2 release];

}

#pragma mark HttpResponseDelegate methods

- (void)requestResponseRecieved:(HttpResponse *)res{
if(res.responseCode == HTTP_RESPONSE_CODE_OK){
//do your thing get the content by using
NSData * resData = res.rawResponse;
NSString * resString = res.responseAsUTF8DecodedString;
//see the headers
NSDictionary * headers = res.responseHeaders;

}else{
//check the response code and respond accordingly
}
}

Gah objective c does not come out well on the blog. Hopefully you can follow it. Will be adding some improvements as I hope to use this library in some of my future projects.

 

I wanted to add a quick post about this as it was something which took me a while to figure out and so I hope it will be helpful to others.

Sometimes in an app. you want a UIButton to be pressed and remain selected. Now you can set the selected property to YES
, but this doesn’t keep the appearance of a selected button.

Now you could make a custom image for your button and use :

[button setBackgroundImage:[UIImage imageNamed:@”someimage.png”] forState:UIControlStateSelected];

However I found this way of doing it to be better, particularly, as with most coders, if you’re not a great fan on photoshop.

first add #import <UIKit/UIKit.h>

We can then use the graphics layer to alter the buttons appearance. My thanks to http://cocoawithlove.com/ for pointing me in the right direction for this one:

- (void)controlButton:(UIButton *)sender
{

[[sender layer] setCornerRadius:8.0f];
[[sender layer] setMasksToBounds:YES];
[[sender layer] setBorderWidth:1.0f];

if (sender.selected == YES) {

[[sender layer] setBackgroundColor:[[UIColor lightGrayColor] CGColor]];

}else{
[[sender layer] setBackgroundColor:[UIColor whiteColor].CGColor];
}

}

 

Just wanted to add a quick tutorial on setting up PHPUnit on your mac.

First step:
Mac osX no longer comes with PEAR (PHP Extenstion Aplication Repository) installed and this is the easiest way, in my opinion to install and set up PHPUnit. So the the first step is to install PEAR

Open terminal and run:

curl http://pear.php.net/go-pear.phar > go-pear.php

next run the script

sudo php -q go-pear.php

You will next be given a list of options. The only one that needs to be changed is the install dir
set it to /usr/local

Press enter and it will finish installing PEAR. Next you will need to alter the php.ini file used by the default install of php on the mac. Run the following:

sudo cp /etc/php.ini.default /etc/php.ini

next we need to add the pear repo to the include path.


sudo nano /etc/php.ini
press ctrl w and type in include_path
change this from ;include_path = ".:/php/includes"
to include_path = ".:/php/includes:/usr/share/pear"
//restart apache
sudo apachectl restart

Now pear should be installed. So onto the PHPUnit.
Run:

sudo pear channel-discover pear.phpunit.de
//then
sudo pear install phpunit/PHPUnit

And that should be PHPUnit installed. So now onto netbeans. Fire up netbeans and then open prefrences -> php-> general and set the php interpretor to /usr/bin/php then go to unit testing and add /usr/local/bin/phpunit as your phpunit script. You may also want to add to your include path in netbeans /usr/local/share/pear/PHPUnit this will enable netbeans to read the class files and prompt you with auto completes.

Hope this helped.

The Power of Zend_Validate and Zend_Filter

 Development, Zend Framework  Comments Off on The Power of Zend_Validate and Zend_Filter
Sep 062011
 

I don’t know about you, but I find that sometimes coding html forms and the corresponding backend validation to be the typical type of “Boiler Plate” code that once you’ve done it and understand the principles, that you never really want to have to do it again.

Into the breach steps Zend_Frameworks’ Zend_Validate and also Zend_Filter. This set of classes can be used in conjunction with the Zend_Form_Element Classes and Zend_Form Class and makes validating forms almost a pleasure. Let me show you an example.

Often with a web form we need to validate that an email address is valid. So you might use a function such as:

filter_var($email, FILTER_VALIDATE_EMAIL)

And then redirect back with an error stored in the user’s session if it fails. However it gets a little more tricky when you also need to validate that the email address is unique to your database table.

public function validateUsersEmail(){
if(filter_var($this->email, FILTER_VALIDATE_EMAIL)){
//do query to check email address not already entered
//if no return true
}
return false;
}

However Zend Framework offers a set of very powerful filters. which means you can create a form email like so from within a class extending Zend_Form:


$handleElement = new Zend_Form_Element_Text("handle");
//Here is where the validator kicks in
$handDbValidator = new Zend_Validate_Db_NoRecordExists('siteusers','handle');
$handDbValidator->setMessage("That username already exists");
$handleElement->setLabel("Username")
->setRequired(TRUE)
->addValidator("NotEmpty",TRUE)
->addFilter(new Zend_Filter_Alnum(false))
->addFilter(new Zend_Filter_StripTags())
->addValidator($handDbValidator)
->addFilter(new Zend_Filter_StringTrim());
->setOptions(array("size"=>"35","maxlength"=>"10","class"=>"textinput",
"placeholder"=>"Username"))

Now that looks like a lot of code. However there are several validators and also filters being applied to this element.

Here is the code for checking if a record exists and also to set the error message to report to the user

$handDbValidator = new Zend_Validate_Db_NoRecordExists('siteusers','handle');
$handDbValidator->setMessage("That username already exists");

Here we specify the table name and the field name to check and then add an error message if it fails.

Now the filters

So how often have you gone searching for the right regular expression to strip out all none alpha numeric characters from a string? Well I know I often forget the exact syntax and go searching. Zend Framework offers you a great set of Filters to apply to your form elements. In the above code you can see them at work in the following way:

->addFilter(new Zend_Filter_Alnum(false))
->addFilter(new Zend_Filter_StripTags())

These are fairly self explanatory but show what is possible using the Zend_Form Class along with filters and validators.

You can find out more on validators and also Filters by following the links.

creating a request filter – allowing for /username

 Development, Zend Framework  Comments Off on creating a request filter – allowing for /username
Aug 302011
 

Often in modern websites, particularly social websites, the urls are in the format of http://somesite.com/username. This presents something of a problem for web apps that follow the MVC pattern and direct all requests through a single front controller that then dispatches the request to the correct controller based on the url or on a route set up in the app. Recently I have begun work on a website, groups.ie and I wanted to implement a url pattern of http://groups.ie/the-group-name . So how so we achieve this when we cannot properly map this using a route as the group name could be almost anything?
I achieve this by using a simple Zend plugin. Here is the code:

/**
* Description of GroupFilter
* allows for urls to follow the format of
* sitename/group-name
*
* @author craigbrookes
*/
class Application_Plugin_GroupFilter extends Zend_Controller_Plugin_Abstract {

public function preDispatch(Zend_Controller_Request_Abstract $request) {
$controller = $request->getControllerName();
$groupMapper = new Application_Model_GroupsMapper();
$group = $groupMapper->findRowByFieldsAndValues(array("url"=>$controller));

if(!$group->isEmpty()){

$request->setControllerName("group");
}
}

}

So in this code, I extend the Zend_Controller_Plugin_Abstract which provides several hook functions (functions which the parent or a controller will call on all plugins at certain times during execution)

The hook functions provided are:

  • routeStartup(): prior to routing the request
  • routeShutdown(): after routing the request
  • dispatchLoopStartup(): prior to entering the dispatch loop
  • preDispatch(): prior to dispatching an individual action
  • postDispatch(): after dispatching an individual action
  • dispatchLoopShutdown(): after completing the dispatch loop

In the above code I choose only to implement the preDispatch() which is past the instance of
Zend_Controller_Request_Abstract. From this request object I get the current controller which my be set to the name of a group. I then use my Mapper class and check if there is a group that responds to the controller name. Finally, if there is a group object found, then I set the controller to the Groups controller which can then take over. Other wise the request continues along its merry way. Got any other solutions or can see potential problems with my solution, please leave a comment and let me know.

For more information on plugins, I found this article to be quite useful.

Abstract Zend Data Mapper Class for Zend Framework

 Development, Zend Framework  Comments Off on Abstract Zend Data Mapper Class for Zend Framework
Aug 232011
 

I have started a new project with a fellow programmer, Peter Fortune @pfortune. The project is a group organising tool, aimed at the Irish market and will be hosted under the domain http://groups.ie.

So when discussing this project, we decided to use Zend Framework as we both are very comfortable with PHP and I have used Zend Framework in the past. After working on the design of the database schema, it came to laying the ground work for the project. Building the models fell under my todo list and so I set to work.

So I spent a little time coming up with what I think is a reasonable Abstract class for the Applications data mapping classes to extend. I know quite a few developers prefer to use doctrine with Zend Framework, and when the project progresses, this may be something we will consider using also, but for the time being, I went with the inbuilt tools Zend_Db_Table_Abstract etc. So here is the class I ended up with. Please give me your thoughts and criticisms and point out any gaping errors.


setDbTable($tableName);
$this->_model = $model;

}

public function setDbTable($dbTable)
{
if (is_string($dbTable)) {
$dbTable = new $dbTable();
}
if (!$dbTable instanceof Zend_Db_Table_Abstract) {
throw new Exception('you must pass a class that extends Zend_Db_Table_Abstract');
}
$this->_dbTable = $dbTable;
return $this;
}

/**
*
* @return Zend_Db_Table_Abstract
* return concrete child
*/
public function getDbTable()
{
if (null === $this->_dbTable) {
throw new Exception("no dbtable set");
}

return $this->_dbTable;
}

/**
*
* @param Application_Model_RowAbstract $row
* @return array
* returns an array of concrete children extending Application_Model_RowAbstract
*/
public function findAllByExample(Application_Model_RowAbstract $row)
{
//returns all public properties and their values in assoc array
$props = get_object_vars($row);
$sql = $this->getDbTable()->select();
foreach($props as $property=>$value){
if(!NULL == $value)
$sql->where(''.$property.' = ?',$value);
}

$rows = $sql->query()->fetchAll();
$ret = array();
foreach($rows as $row){
$ret[]= new $this->_model($row);
}
return $ret;

}

/**
*
* @param Application_Model_RowAbstract $row
* @return Application_Model_RowAbstract
* returns a concrete child
*/
public function findRowByExample(Application_Model_RowAbstract $row){
$props = get_object_vars($row);
$sql = $this->getDbTable()->select();
foreach($props as $property=>$value){
if(! NULL == $value)
$sql->where(''.$property.' = ?',$value);
}

$sql->limit(1);
$rows = $sql->query()->fetchObject($this->_model);
return $rows;
}

/**
*
* @param Application_Model_RowAbstract $row
*
* chooses to save or update based on whether the primary key is set or not
*/
public function saveUpdate(Application_Model_RowAbstract $row)
{
//get pri key from get_primary() public method added
//to concrete implimentation of Zend_Db_Table_Abstract
$prikey = $this->getDbTable()->get_primary();
$prikey = $prikey[1];
$data = get_object_vars($row);
if(isset($row->$prikey)){
//update
$updateData = array();
foreach($data as $property=>$value){
if(!NULL == $value)
$updateData[$property]=$value;
}
print_r($updateData);
//$this->getDbTable()->update($updateData, ''.$prikey.'='.$row->$prikey.'');
}else{
//insert
$this->getDbTable()->insert($data);
}

}

/**
*
* @param mixed $value
* @return Application_Model_RowAbstract
* the value is the value of the primary key set for the row
*/
public function findWherePriKeyEquals($value){

$row = $this->getDbTable()->find($value);
$ret = $row->current();
return new $this->_model($ret->toArray());

}

}

so that’s it. As you can see you have most functionality there. You can create a dummy object and find all that match its values in the database. You can update and save an objects values
and you can find based on simple rules. All of this means that the concrete sub classes have a lot less work to do. Hope this is helpful.

 

If you have’t heard Mozilla identity labs has introduced a new way to login into sites called browserid. We have all become familiar with the “sign in with twitter” and “connect with Facebook” buttons on sites that enable us to have a centralised login to many of our favourite web services.

These centralised logins are very useful, but are ultimately controlled by a company. So into the breach steps Mozilla offering an openid type login service. Browserid is open source and you can choose to use mozilla as an authentication service or you can set up your own. I’m going to show you how to setup this service as a login and using Mozilla as the authenticator.

So assuming you have a login image with an Id attribute of “login” the following code should work in most modern browsers. I’m using jquery as the javascript framework.



$('document').ready(function (){

$('img.login').click(function(){
navigator.id.getVerifiedEmail(gotVerifiedEmail);
});

});
//this function is called in the above function
function gotVerifiedEmail(assertionObj){
If(assertionObj){
//Ajax to a login controller
$.ajax({
url:"/yourcontroller/youraction",
data:{assertion:assertionObj},
dataType:"json",
type:"post",
success:function(data,textStatus,jqXHR){
// do your thing
},
error:function(){
// something went wrong with ajax call
}
});
}else{
// something went wrong
}
}

So that’s the JavaScript part however we still need to verify the assertion with Mozilla. You can do this with JavaScript too. In the above code you would replace the call to your controller with
The following URL:
“https://browserid.org/verify?assertion=”+window.encodeURIComponent(assertionObj)+”&audience=”+window.encodeURIComponent(window.location.host);

In my controller class I do the following in a grails app:

def browserIdLogin ={

If(params.assertion){
def url = new URL(
"https://browserid.org/verify?assertion=${URLEncoder.encode(params.assertion)}&audience=
${URLEncoder.encode(request.getHeader('HOST'))}");

def jsonResponse= JSON.parse(url.text)

Println jsonResponse
}

}

// this will output something like [audience:localhost:8080, issuer:browserid.org:443, email:[email protected], status:okay, valid-until:1310908947530]

So you now you are dealing with an authentic user with authenic email address. Now you can do as you please. if this user already has an account you can load up their account details and set the session parameters etc or if they have no account you can send them to complete an account creation (if you need more details than the email address). After they complete this they can then sign in without needing to remember a password etc.

In php you could use the CURL library or open a socket etc or you could even just use


email;
?>

Anyway hope this is helpful. There is plenty of info on browserid and they also have example code.

 

I have been toying with some new ideas lately and trying to focus on how I can make tech and the web do more good, thats not to say it doesn’t already do good of course. So an idea that I struck upon while thinking about the power of location, socially connected networks and the saturation of smart devices, was helpfinding.me.
what is helpfinding.me? Well, as i hope the title suggests, this will be a tool to leverage the connected nature of our society in order to try and help find missing people within the bounds of your location.
I often hear that the first 24 hours of someone going missing are the most important. This smartphone app will try to leverage that.
so here is the scenario, a family are out on the beach or at a park or at a large public event when they suddenly notice one of their children has not come back from playing. They start to look around but do not find the child. The park/beach is large, they get worried and start asking people have they seen such and such and show them a picture. This is where I envisage helpfinding.me coming in. In the simpelist way possible, a picture would be added to the app plus a brief description of clothes etc, the app would pick up location and post it to the server which in turn would post a notification to every registered device within the area. Any people with the app would recieve the notification and be able to view that someone had gone missing near them and so become more vigilant and aware, and hopefully someone would spot the child/person.
I think there are two difficult problems. The first is gaining app saturation, but this is more a marketing problem as i feel people will be open to downloading the app and and have it sit largely silent on their phone. The second problem is handling discovery. You don’t want a situation where you are sending parents/Concerned parties on wild goose chases. I envisage this problem will become easier to solve as saturation increases. A potential solution could be leveraging existing connections between people to create levels of trust. Also of course there is a group effect too; if several people report sighting the missing person in a location, the likelyhood of it being a hoax is relatively small. Also the device saturation level could be used: if there are only six devices in the area and one of them reports a sighting, then this is highly relevant. There are more things which will come to light, I’m sure. Got any thoughts on this? Please leave a comment or get in touch via @maleck13. I think its important to remember that the average person is good and is unlikely to want to cause a person extra distress by posting a false sighting.

Has The Web “pivoted”

 Development, Ideas  Comments Off on Has The Web “pivoted”
Jun 212011
 

According to recent study done see here -> source we are now spending more time on mobile applications than on the web. While I don’t claim that this is a definitive study, it does show what I believe is a trend that will only continue to grow. We like our data in nice neat, “app” size, packages. Has anyone ever really enjoyed the alternative: searching through ad filled pages, with different and often irritating ways of presenting their information to you?
However some are pointing to this as a sign that “the web is dying or dead”. Wired magazine did a good piece on this web is dead article and I think they highlight some very good points. However I feel that web is far from dead.

A large majority of these apps that we use, are powered, at least to some extent, by web services/apis (application, program interface). Many point to these as not being indexable and so not helpful to the web because the data can’t be linked to. This is true, to a certain extent. However, if you are anything like me, some of the apps that I use most, I use to discover links being shared with me in a social context. I can safely say, that I have visited and discovered more websites and articles of actual worth via these service consuming apps than through any other medium, and yes that includes google. The web evolves quickly, maybe more quickly than any other medium, and we as its consumers, creators and curators, are constantly try to gain the most from it.

I would also point out, that there is no reason why if we use the RESTful model more on REST in building web services, that these Apis/ services can’t be used for front end consumption as well as empowering 3rd party apps. Putting it in a simple way, when I use the GET method why not let the default be to render a HTML version of the content, but if I add a parameter to that GET request of ?type=json , then it renders the content as a json document for consumption by apps and so on.

So perhaps the web has pivoted and has become a web service provider, but I would argue it was never anything more than that . The browser after all is a data consuming app. And along as we hold dear the http protocol in order to help us share our data, the web will remain our most important invention.

No, it is not the native apps that pose any threat to the web, but there is a monster out there lurking and parading a being a part of the web, but keeping everything behind locked doors. I am of course talking about Facebook. It makes me immensely sad when I see a link in a tweet etc pertaining to something that I may find very interesting, only to find that when I follow the link, I am met with a Facebook login page. It is my hope that we will find ways to liberate this information and replace Facebook, with a more open and web friendly alternative.

Substance & context: a problem facing the web

 Development, Ideas  Comments Off on Substance & context: a problem facing the web
May 282011
 

Substance and context. There is something of a contradiction in the web. It is well known that once you put something on the web, it is essentially there forever; in one form or another. And yet I find that while the web offers me a huge number of resources, and new information, it sometimes feels very shallow, transient and without context. often I find myself agreeing with a blog post or tweet without really understanding the motivation, history and persuasions of the information and the provider of the information.
It also very difficult to retrace information. Have you ever found yourself trawling google in order to try and find a page that you had come across in the past, that now seemed very relevant to something currently in your focus. the web is fragmented by nature, and this makes it hard to connect the dots, as it were, that link lots of information together and provide a full picture.
so how can we address this? Well right now I’m not sure, but it is a problem that is occupying my mind and perhaps soon, I will have an idea on how to solve it.

© 2012 Craig Brookes Suffusion theme by Sayontan Sinha