How to add a post to a WordPress blog from an iPhone App

It often happens that I need to create some form of web content from my iPhone applications.

wordpress-logo

For example, it can happen that some user interaction has to be recorded and, then, published to other users. I often choose to do this using a WordPress CMS basically because it is very easy and quick to do: you can benefit from a full set of already implemented features, including the possibility to create multimedia content using categories, tags, plugins etc, using a very simple and featured open API, including authentication, content validators, image and media handling facilities and all the other things we have learned to love in the WordPress CMS, using a few lines of PHP code.

But: how can we create a WordPress post from inside an iPhone application?

We’ll break down this in a few steps:

  • install WordPress
  • create the skeleton of your iPhone App
  • download and configure all the required iPhone libraries
  • create some objective-c code in the App
  • create some PHP code on the server

Install WordPress

You will need to install your own WordPress: the task we are about to perform requires you to create some custom PHP code and so the WordPress instances that are freely available on the wordpress.com website are no good for this, as they don’t allow you to create your custom PHP scripts.

For this you will need:

  • some web space (provided by your web hosting provider)
  • a database and a login/password to access it (you will be able to create both using the administration interfaces provided by your web hosting provider)
  • the WordPress software

So, once you have your web space ready, go to your provider’s administration panel and create a new database. Once the database is created you will need to create a user/password for it. You will probably be able to use a web-based tool to do this, and most of the time it will be a PhpMyAdmin tool. If this is the case, select your database (the one you just created)  among the list of available databases, and click the “Priviledges” tab in the top menu, to create your user (fill in all required information, select “local access” to acquire a degree of security, and check all permissions for your user). Keep the login/password for your user, the database name, and the database host (this is usually provided by your hosting provider) at hand. You will need it soon.

Download the WordPress software on the WordPress.org website. Unzip the ZIP archive and upload it to a directory on your server using FTP. (let’s say that you uploaded it to the “/wordpress” directory just off the root directory of your web hosting space)

Open your browser and go to http://www.yourdomain.com/wordpress . You will be presented with some information to fill in (you have all your logins, passwords, hostnames and database names ready, don’t you?). Submit the info and, voilà, your WordPress instance is configured. (If you have some problems in doing the install, check out this tutorial which explains the process in some more detail).

Last step of this part. Login to your newly-created WordPress administration interface (use the admin login and password you just entered in the install process) at http://www.yourdomain.com/wordpress/wp-admin and go to the Settings/Writing options page (on the left bar menu). Check both checkboxes named “Atom Publishing Protocol” “XML-RPC”, and save using the button at the end of the page.

Create the skeleton of your iPhone App

Open the XCODE development environment.

Create a new project: among the available application templates choose “Window based Application”, creating basically an empty application; give it a name and a directory, and do NEXT->NEXT->CREATE and your application will be prepared.

Download and configure some libraries for iPhone

For this task we will be using the ASIHttpRequest API. Download the ZIP package from the project’s GITHub’s page, and unzip it.

Create a group in your XCode project, call it ASIHTTP, and use the “Add Files to ProjectName” function in the context menu to add the following files to your project (just CTRL+click on the Group you created, choose the option, and a file browser will show up: select the following files by CMD-clicking on each of them and then “ADD”):

  • ASIHTTPRequestConfig.h
  • ASIHTTPRequestDelegate.h
  • ASIProgressDelegate.h
  • ASICacheDelegate.h
  • ASIHTTPRequest.h
  • ASIHTTPRequest.m
  • ASIDataCompressor.h
  • ASIDataCompressor.m
  • ASIDataDecompressor.h
  • ASIDataDecompressor.m
  • ASIFormDataRequest.h
  • ASIInputStream.h
  • ASIInputStream.m
  • ASIFormDataRequest.m
  • ASINetworkQueue.h
  • ASINetworkQueue.m
  • ASIDownloadCache.h
  • ASIDownloadCache.m
  • ASIAuthenticationDialog.h
  • ASIAuthenticationDialog.m
  • Reachability.h (in the External/Reachability folder)
  • Reachability.m (in the External/Reachability folder)

You will need to link your App to several libraries, to gain network access and other system functions. Link your App to these frameworks and libs:

  • CFNetwork
  • SystemConfiguration
  • MobileCoreServices
  • CoreGraphics
  • zlib(libz.1.2.3.dylib)

(to link these, there’s a different process if you use earlier or later versions of XCode. In the older ones, just CTRL-click on the “Frameworks” element in your project tree, select “Add Framework” from the available menu entries and CMD-select all the required frameworks from the list. On newer versions of XCode, click on the top element of your Project tree, click on a target, choose the “Build phases” tab on the right, open the “Link Binary with Libraries” element of the list and use the “+” sign to add all the required frameworks)

Create some objective-c code in your App

We will create a UIViewController to perform our tasks. (all the code is in the ZIP at the end of this tutorial).

On your Project tree, click the “NewFile..” option from the contextual menu, choose “UIViewController subclass” from the available options, do NEXT->NEXT, give it a name (WPPosterViewController) and Save.

In your ApplicationDelegate import the “.h” of the ViewController:

#import "WPPosterViewController.h"

create a field in your ApplicationDelegate Interface

WPPosterViewController *theViewController;

and create a property for it

@property (nonatomic,retain WPPosterViewController *theViewController;

In the “.m” file of your ApplicationDelegate, synthesize the property:

@synthesize theViewController;

and add it to the dealloc method, so that its memory gets released when the application shuts off. So in the dealloc method add the line:

[theViewController release];

Now we can add the ViewController to our application, by adding these few lines to the didFinishLaunchingWithOptions method in our ApplicationDelegate:

theViewController = [[WPPosterViewController alloc] init];
[self.window addSubview:theViewController.view];

Now we can build a simple interface using the functions in our ViewController. We will keep this simple, and we will make a simple-simple interface for the user to create the title and content of a post, and a button to submit it. We can use the loadView method to create our interface programmatically.

First let’s create 1 view, 2 labels and 2 textfields for our title and content body. Let’s add them to the interface if our ViewController:

UILabel *titleLabel;
UILabel *bodyLabel;
UITextField *titleTextField;
UITextField *bodyTextField;
UIView *mainView;

and let’s create some properties for them:

@property (nonatomic,retain) UILabel *titleLabel;
@property (nonatomic,retain) UILabel *bodyLabel;
@property (nonatomic,retain) UITextField *titleTextField;
@property (nonatomic,retain) UITextField *bodyTextField;

In the implementation of our ViewController, let’s synthesize the properties:

@synthesize titleLabel,titleTextField, bodyLabel,bodyTextField;

and let’s add their release statements in our dealloc method:

[titleTextField release];
[titleLabel release];
[bodyLabel release];
[bodyTextField release];
[mainView release];

Now we can put some code in our ViewController’s loadView method to create our user interface programmatically. (Note: we won’t put any emphasis in the aesthetics of the interface, you can refer, for example, to this tutorial to make nicer UI elements for your APPS).

In our loadView method, let’s add the initialization of our view and input elements.

First of all we will need to know the size of our screen:

CGRect scrsize = [[UIScreen mainScreen] applicationFrame];

And we will use it to initialize and size our view:

mainView = [[UIView alloc] initWithFrame:scrsize];

Then we will initialize our labels and inputs. This is an example label initialization:

titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, scrsize.size.width, 20)];
titleLabel.text = @"Title";

and this is how we initialize one of the input fields:

titleTextField = [[UITextField alloc] initWithFrame:CGRectMake(0, 25, scrsize.size.width, 20)];

Then we will add all our UI elements as sub-views of our main view. This is how we add one of the labels as sub-view:

[mainView addSubview:titleLabel];

and then we will set our view as our ViewController’s base view:

[self setView:mainView];

We will need another UI element: a button to save our post. Let’s add it among our fields in our ViewController’s interface:

UIButton *saveButton;

let’s add it among the properties

@property (nonatomic,retain) UIButton *saveButton;

and let’s move to the implementation file to synthesize it

@synthesize saveButton;

to add its release statement to the dealloc method

[saveButton release];

and to initialize and display it, in the loadView method:

saveButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
saveButton.frame = CGRectMake(0, 125, scrsize.size.width, 25);
[saveButton setTitle:@"Save!" forState:UIControlStateNormal];
[mainView addSubview:saveButton];

We now need to activate out button. We will use the addTarget method to do this, implementing a call to a custom method we will build below to execute our intended task:

[saveButton addTarget:self
	action:@selector(doSave:)
	forControlEvents:UIControlEventTouchUpInside];

this method essentially informs the iPhone that when someone completes a touch inside this button (UIControlEventTouchUpInside), a certain method (a selector, the method doSave) should be executed, found in this same objective-c class (self).

This method, the selector, is where all the work will happen (including the input validation and checking which we’ll not cover in this tutorial), and it will be something like this:

-(void) doSave:(id)sender
{
}

Now let’s put some code inside it.

The idea is that the code will get the info found in the fields (we won’t check if there is actually any: you should check it for correctness and security in real applications) and send it to a PHP script on the server which will take care of turning it into a WordPress post.

We will write the PHP script in a minute: for now, let’s say that it will be called “savePost.php” and that it will be placed in the directory which contains your WordPress installation directory (the directory on your web server which contains the “wordpress” directory in which we copied the WordPress files earlier on). Let’s also say that it will accept its parameters using the POST method.

We will use the ASIHttpRequest to achieve this functionality.

The ASI classes allow to easily create HTTP calls, including submitting values to other pages using GET and POST methods. One of the most interesting advantages of the ASI classes, is that they can perform the requests asynchronously, meaning that once the request is places, control is immediately given back to the application and the execution of the call is performed in background. Once the call is completely executed one of two methods is invoked, to notify success or failure of the request.

Let’s configure our request in our doSave method.

We will need to define the URL (internet address) of the call we wish to make. According to what we said before this address will be:

http://www.yourdomain.com/savePost.php

(we will write the script in the next section)

So we can prepare this URL for our iPhone like this:

NSURL *url = [NSURL URLWithString:@"http://www.yourdomain.com/savePost.php"];

And we can feed it to an ASI http request like this:

ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];

(remember to add the statement

#import "ASIFormDataRequest.h"

in your ViewController’s header file, otherwise your class will not know what the ASI class is)

Now we need to add the info written in the textfields to our request, as POST fields:

[request setPostValue:[titleTextField text] forKey:@"post-title"];
[request setPostValue:[bodyTextField text] forKey:@"post-body"];

These two statements take the text written in each of the two fields (e.g.: with [titleTextField text]) and set it as a POST field with a certain name, with the forKey directive.

Now we can start our asynchronous request:

[request startAsynchronous];

When the request will be completed, one of two methods will be automatically called:

  • requestFinished if the result was successful or
  • requestFailed if there was an error

In the source code you will find  the two calls, each printing their result to the log (using NSLog statements) to allow you debugging the execution of the code.

 

Now We have everything we need and we can move to the server.

Create a PHP script to handle the call and to create the WordPress Post

This part is actually very easy.

Our script (remember to call it exactly like you wrote it in the iPhone code, including capitals, and to place it in the exact directory where you pointed it to when you created the URL at the steps above) will basically:

  • connect to the WordPress system
  • create a post with the relevant fields
  • save it to the wordpress database using wordpress built in functions

To connect to the WordPress system our script will need to include a part of WordPress’ code: the wp-config.php file. We start our PHP script like this:

<?php

require_once("wordpress/wp-config.php");

?>

Now we will check to see if the post-title and post-body POST fields are set, and if they are set, we will get their values:

if(isset($_POST["post-title"])&&isset($_POST["post-body"])){
	
	$post_title = $_POST["post-title"];
	$post_body = $_POST["post-body"];
	
	// ... and then we continue here
	
}

Now we will prepare our post:

$new_post = array(
	'post_title' => $post_title,
	'post_content' => $post_body,
	'post_excerpt' => $post_body,
	'post_status' => 'publish',
	'post_date' => date('Y-m-d H:i:s'),
	'post_author' => 1,
	'post_type' => 'post',
	'post_category' => array(0)
	);

To do this we will prepare this array which contains relevant post fields. Some are self-explanatory, and we assign them obvious variables and values.

The post_status value contains the status of the post which you wish to create. Set it to draft if you want to automatically create draft posts (so that an administrator has to validate them to be published).

The post_type field can also be set to page, to create pages instead of posts.

The post_author field is the ID of the author of the post. We set it to 1 which is the ID of the administrator, but it really should come from an authentication process for security reasons.

The post_category field contains the ID of the category in which you want to insert the post. We use 0 for the Uncategorized standard category, but you might wish to use something else. The array can contain more than one element, and, thus, the post can be inserted into a number of different categories at the same time.

Now we invoke a WordPress function to save the post:

$post_id = wp_insert_post($new_post);

This function does just what it says: it saves the post described by the array, and it returns the ID of the newly created post.

What can you use this ID for? For a whole range of things, including, for example, adding a set of tags to the post, like this:

$post_tags = array(
    'ID' => $post_id,
    'tags_input' => 'this, is, a, series, of, comma, separated, tags');     

// Update the post
wp_update_post($post_tags);

In this statement you define a comma separated set of tags, and associate to a post ID, and then use the update command to apply the changes.

In this ZIP file:

SendPostToWordpress

You will find an XCode project that can be compiled to see the whole process working and to browse and personalize the source code.

The savePost.php script is also included for placement on your server.

Remember to customize the paths and parameters according to  your system configuration and to apply all the security, consistency and correctness controls suggested throughout the article before using these codes on a “real” application.

MACME on WordPress

MACME logo

MACME logo

 

the MACME plugin is now available as a standard WordPress plugin.

Click HERE to go to the WordPress site and download MACME.

This means that you can now go to your WordPress blog and search for “MACME” directly in the plugin search box, and install it from there, and get updates as soon as they come out.

Please give us feedback if you’re using it. :)

more info on MACME:

MACME info downloads and tutorials on Art is Open Source

MACME on FakePress

MACME on WordPress.org

MACME on GITHub

REFF – workshop at Writtle College, Feb. 21th 2011

REFF in London with Furtherfield

on Feb. 21th 2011 REFF (with AOS, Art is Open Source, and FakePress) held a workshop in Essex at Writtle College.
The theme of the workshop was the reinvention of reality through critical practices and ubiquitous technologies.
During the workshop a short history of the REFF project was narrtes, quickly followed by a hands-on session in which the cross-media publishing tools released by FakePress under a GPL3 license have been installed and tested out:

MACME: a cross media publishing plugin for the WordPress platform allowing to transform any blog into an ubiquitous tool for publishing creating PDFs, ePub ebooks, QRCodes, location based media and augmented reality content.

KNOWNERS: a knowledge sharing ecosystem built on the wordpress platform

CoS, CONSCIOUSNESS OF STREAMS: a ubiquitous narrative first shown at the transmediale festival on 2011, through which FakePress created a global publication in which more than 35000 authors have created a realtime emotional map of the world

REFF at Writtle College

REFF at Writtle College

more info on REFF and the specific projects on:

http://www.artisopensource.net
http://www.fakepress.it
http://furtherfield.org

the global vision of REFF project can be seen here:

http://reff.romaeuropa.org

during these days:

on the 25th of February 2011 REFF will be opening up an exhibit at Furtherfield gallery in London

more info here:

http://www.furtherfield.org/exhibitio…

REFF – workshop at Westminster College, Feb. 22th 2011 (

REFF in London with Furtherfield

on Feb. 22th 2011 REFF (with AOS, Art is Open Source, and FakePress) held a workshop in London at Westminster College
The theme of the workshop was the reinvention of reality through critical practices and ubiquitous technologies.
During the workshop a short history of the REFF project was narrtes, quickly followed by a hands-on session in which the cross-media publishing tools released by FakePress under a GPL3 license have been installed and tested out:

MACME: a cross media publishing plugin for the WordPress platform allowing to transform any blog into an ubiquitous tool for publishing creating PDFs, ePub ebooks, QRCodes, location based media and augmented reality content.

KNOWNERS: a knowledge sharing ecosystem built on the wordpress platform

CoS, CONSCIOUSNESS OF STREAMS: a ubiquitous narrative first shown at the transmediale festival on 2011, through which FakePress created a global publication in which more than 35000 authors have created a realtime emotional map of the world

REFF at Westminster College

REFF at Westminster College

more info on REFF and the specific projects on:

http://www.artisopensource.net
http://www.fakepress.it
http://furtherfield.org

the global vision of REFF project can be seen here:

http://reff.romaeuropa.org

during these days:

on the 25th of February 2011 REFF will be opening up an exhibit at Furtherfield gallery in London

more info here:

http://www.furtherfield.org/exhibitio…

REFF – workshop at Westminster College, Feb. 22th 2011

REFF in London with Furtherfield

on Feb. 22th 2011 REFF (with AOS, Art is Open Source, and FakePress) held a workshop in London at Westminster College
The theme of the workshop was the reinvention of reality through critical practices and ubiquitous technologies.
During the workshop a short history of the REFF project was narrtes, quickly followed by a hands-on session in which the cross-media publishing tools released by FakePress under a GPL3 license have been installed and tested out:

MACME: a cross media publishing plugin for the WordPress platform allowing to transform any blog into an ubiquitous tool for publishing creating PDFs, ePub ebooks, QRCodes, location based media and augmented reality content.

KNOWNERS: a knowledge sharing ecosystem built on the wordpress platform

CoS, CONSCIOUSNESS OF STREAMS: a ubiquitous narrative first shown at the transmediale festival on 2011, through which FakePress created a global publication in which more than 35000 authors have created a realtime emotional map of the world

REFF at Westminster College

REFF at Westminster College

more info on REFF and the specific projects on:

http://www.artisopensource.net
http://www.fakepress.it
http://furtherfield.org

the global vision of REFF project can be seen here:

http://reff.romaeuropa.org

during these days:

on the 25th of February 2011 REFF will be opening up an exhibit at Furtherfield gallery in London

more info here:

http://www.furtherfield.org/exhibitio…