Learning Cocoa
February 9th, 2008
Putting things into an NSPopupButton
- it’s easier to use an array of objects with a string property than it is to just use an array of strings. e.g. create a ‘Thing’ class that has a ‘name’ property of type NSString, and put some of them in an NS(Mutable)Array
- you can initialise this array in the
awakeFromNibmethod in your controller - you want to drag an Object from the palette into your MainMenu.nib amd set the Class (in the Identity tab – the ‘i’) to be that of your controller
- then drag an Object Controller into the nib, and control+drag it to your controller (the object you just renamed), selecting the ‘content’ outlet where prompted. Rename this to ControllerAlias (or at least subsitute this where ‘ControllerAlias’ is used below…)
- then, you want an Array Controller as well that will represent the array that’s been initialised in the controller. I named this after the array in my controller
- In the ‘Bindings’ tab (green shapes), expand the ‘Content Array’ section, tick the box and select ‘ControllerAlias’ from the menu. The Controller Key wants to be ‘selection’ and the Model Key Path should be the same as the property of your controller that contains the array of items.
- Your controller should have an IBOutlet for the NSPopupButton you’ve created in the window, so control+drag the NSPopupButton to the Object you created for the controller, and select the outlet when prompted – it will only show you a list of NSPopupButtons (or subclasses).
- Next, select the NSPopupButton in the window (click on it just once, more clicks will select the ‘Cell’ instead, which we don’t want) and then flip to the Bindings tab in the inspector.
- For ‘Content’, tick the box and choose/type the name of the ArrayController you created. The Controller Key wants to be ‘arrangedObjects’, the other two boxes should be empty.
- ‘Content Values’ wants to also be bound to the ArrayController, and again the Controller Key should be ‘arrangedObjects’, but this time the Model Key Path wants to be ‘name’ – or the name you gave to the property on your ‘Thing’s. Finally, the Selected Index also wants to be bound to the ArrayController, with Controller Key set to ‘selectionIndex’
- to get at the value from the controller, setup an IBAction (from a button click or similar) and then you can get at the string value using
[popupbuttonField titleOfSelectedItem]. More useful would be to access the object that you used to bind in the first place, but I can’t seem to get that to work.
Making HTTP POST requests
Coming from PHP, this seems like it’s really complicated, so I wouldn’t be at all surprised if I was missing something…
- To make a request, you need one each of NSURL, NSURLRequest and NSURLConnection. Using NSMutableURLRequest makes the code a bit neater (as you can set properties after initialisation), not sure why you wouldn’t want to use it always? (memory? does ‘mutating’ involve copies?)
- the NSURL is quite basic, just a wrapper around a string:
[url initWithString:@"http://www.example.com"]
- NSURLRequest has initWithURL that takes an NSURL
- To make it a POST request:
setHTTPMethod:@"POST"
- the body of the request can’t just be a string (so far as I understand it…), it has to be an instance of NSData:
NSString* postBody = @"foo=bar&baz=bax";
NSMutableData* requestData = [NSMutableData data];
[requestData appendData:[postBody dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:requestData]; //request is a NSMutableURLRequest
- NSURLConnection has initWithRequest, but uses ‘delegate’ to handle what happens with the response. Using
delegate:selfand defining the prescribed methods on the class you’re calling from is probably the simplest way, but seems to mix concerns a bit too much? - You need to implement didReceiveResponse, didReceiveData, didFailWithError and didFinishLoading. The Apple Docs do a pretty good job of explaining this.
- One thing I did differently though, was change the signature of didReceiveResponse to specify NSHTTPURLResponse (instead of just NSURLResponse) as the parameter-type, as then code-completion gives you the ‘statusCode’ property (200=success, 404=not found etc.).
- The NSHTTPURLResponse class also has a static ‘localizedStringForStatusCode’ method that converts the numbered codes into (presumably localised) strings.
- This will let you know what’s happening, but any action that uses the returned data should be in didFinishLoading
Bear in mind this is the way I’ve discovered to do things. If there are better ways I’d like to know about them!
London PHP Conference 2008
January 9th, 2008
It seems registration is now open, and the talks and speakers posted look like it’ll be quite good. In particular, a couple of talks on sending and handling of email look interesting and relevant, while IBM’s Project Zero sounds like it might be worth at least knowing about.
Last year had just the one track whereas this year will have two leaving me with decisions to make, we’ll see how that goes.
Somebody really needs to make the process of booking train tickets easier, it shouldn’t take as long as it did just now for me.
http://phpconference.co.uk
Zend Studio Neon
October 13th, 2007
Zend sent me an email this week letting me know that there was a Beta Release of the new Zend Studio product available, to try for free. I’d tried previous versions of Zend Studio and found them to be unintuitive, unresponsive and generally clunky so I was interested to see how much of an improvement the new version would be, given that rather than being solely a Zend-made product, it’s built on top of Eclipse, more specifically on top of the free PDT project that I’ve been using as my main IDE for a while now.
It definitely is an improvement, but I’m not convinced that there is enough that PDT doesn’t have that will make it worth paying for:- The code formatting options are more powerful, there’s a setting for practically every aspect of the language.
- The ‘new Class’ wizard is quite nice, letting you specify the class-name, a superclass and any interfaces and having these, as well as any prescribed methods, filled in for you in the resulting file.
- The variable-renaming feature works, to some degree. In PDT there’s a menu option, but it doesn’t seem to do anything. With Neon, this will find all uses of the name within the current function or class, but it doesn’t make changes in other files- I realise it wouldn’t be possible to find them all, but it’s a shame it doesn’t even seem to try.
There doesn’t seem to be any mention of how much they plan to charge, only that current subscribers to Zend Studio will get the upgrade for free and that it should be released early next year. You can download it here but you do need to register.
prototype news ticker #2- ProtoTicker
October 3rd, 2007
I was bored so, as you do, I decided to tidy up the BBC-style newsticker I put up a while ago and make it a bit less hacked-MochiKit and a bit more Prototype. It's about half the number of lines, and a whole 1k smaller in filesize, but most importantly it's tidier and hopefully easily extensible. As seems to be the done thing, I'm going to call it ProtoTicker and requires the latest (1.6 release candidates as the time of writing) version of prototype"
Only tested in Firefox and Opera, and only with a couple of known-good RSS feeds, but seems to work just fine. It works with Atom too, I think.
A quick demo:
<script type="text/javascript">
Event.observe(window,'load',function() {
var myTicker = new ProtoTicker('newsticker','/feed/atom.xml',{char_frequency: 80, item_frequency: 1500});
myTicker.start();
});
</script>
Download the Code
authors
September 27th, 2007
Two people I know have announced recently that they are writing books and they both look like they’re going to be really interesting and useful reads.
Rob Allen (who I know from PHPWM) is co-writing Zend Framework in Action which, after reading his tutorial and hearing him talk about the Zend Framework, is bound to be good. Ajax in Action, from the same publishers, is one of the few tech books I actually own, so this can make it a little less lonely on my bookshelf.
Elliot Smith (who I met at last year’s LugRadioLive) is also co-writing a tech book, this time Ruby on Rails Enterprise Application Development: Plan, Program, Extend which with the summary “Building a complete Ruby on Rails business application from start to finish” might inspire me to do some more with Rails than the infamous blog example. For what it’s worth, I think ‘Rails in Context’ is a better title, but what do I know?
Both guys give the warning that writing is difficult and as I’m under no illusions as to the contrary, I’m impressed by their dedication.
Maybe one day…
Having fun with Zend_XmlRpc_Client
August 7th, 2007
In the help that it will be useful:
If you get the error:
Fatal error: Uncaught exception 'Zend_Http_Client_Adapter_Exception' with message 'Unable to Connect to sslv2://<servername>when trying to connect to a server over SSL with the Zend_XmlRpc_Client, then the problem might well be that you need to tell the client that it should use sslv3 rather than the default sslv2. Fortunately, the Zend Framework makes this really quite simple:
$socket = new Zend_Http_Client_Adapter_Socket();
$socket->setConfig(array('ssltransport'=>'sslv3'));
$http_client = new Zend_Http_Client();
$http_client->setAdapter($socket);
$client = new Zend_XmlRpc_Client($endpoint_url);
$client->setHttpClient($http_client);
Basically, Zend_XmlRpc_Client allows you to specify a Zend_Http_Client instance to use instead of creating a new one. Zend_Http_Client in turn lets you specify an Adapter instance to use in place of the default, and the Socket_Adapter lets you set its ‘ssltransport’ config option, so chaining these together makes things work.
javascipt date-picker
June 28th, 2007
For a while now I’ve been tinkering away creating a date-picker in javascript.
JSCalendar has served me well until now, but I can’t help but feel that I must be able to make something that does enough for what I want, without it being as big. I use prototype.js with everything, so I wanted to see how much smaller a prototype-based date-picker, that maintains as much (useful) functionality as possible, could be.
I don’t yet have anything that I want to show off, but I figured that writing something here might just give me that motivation to do the necessary tidying that will be required to let it out into the wild.
Is there anyone reading who has found JSCalendar (or similar things) lacking in any way that I could perhaps address? The main point of my endeavours (aside from being a learning excercise) is to avoid unnecessary bloat, and to create just enough for what I want, but you might just have something that I decide I want.
what's the opposite of unobtrusive?
May 29th, 2007
There were two articles on ajaxian recently that made me question the sanity of the code’s authors. Did they not think as they were developing just how ridiculously convoluted and completely non-unobtrusive their behaviour-attachment is?
The author of the code written about in the first link doesn’t exactly do himself any favours in the comments, and clearly can’t comprehend that giving an element a classname of fValidate['required','phone'] is horrible. He argues that it is no better than having “required phone”, and that by ‘namespacing’ it’s in some way better. HTML documents are hierarchical. Inputs and Selects sit inside (at least) a Form. There’s your namespacing.
The form validation proposed for HTML5 (I can dream) will allow the use the ‘type’ attribute of fields to deal with client-side validation. A required ‘email’ field, for example, will be declared with type="required email". Does it not make more sense to mimic that style now, in readiness for support?
What if I, later, wanted to make ‘required’ input fields look different to the user? (Something the Ajaxian author hinted at in the summary). I’d either need to add CSS rules, or add an additional classname to for each input. That wouldn’t be fun.
I’m willing to be a bit more forgiving to the author of the code covered in the 2nd of the articles, as it seems his work was submitted to the site by someone else (what people get up to in the privacy of their own homes is none of my business) but the premise behind it is equally ridiculous.
It suggests that in order to trigger a function with the onclick event of a link, I should add the classname bvr-observe-click-xhrTheFunction. How this is possibly any easier or less obtrusive than
$(the_link).observe('click',theFunction);
I’m not entirely sure. As an aside, the ‘example’ alternative he gives is unnecessarily verbose, the anonymous function is redundant. I’ve also heard rumours that future versions of Prototype will be even more succinct.
If people are happy using this kind of system, then it doesn’t really have any effect on me and so I probably shouldn’t care, but when a fairly popular news-channel is passing it off as worth knowing about, then that annoys me.
head. wall. bang.
April 3rd, 2007
I spent most of yesterday banging my head against a wall due to Internet Explorer being retarded. I had a table-row in my webpage with an id of ‘element’. Not particularly descriptive I’ll admit, but it’s my page goddamnit so I’ll name things how I want to. Perhaps IE was trying to impose it’s semantic ideals upon me by deciding that in a completely unconnected piece of javascript a variable ‘element’ (with local-scope no less) wouldn’t refer to what I wanted it to refer to, but would instead refer to the HTML element.
We started a company blog the other day at http://www.senokian.com/barking. I might decide to write things there instead, so keep an eye on both!
uk php conference review
February 24th, 2007
It was good. The end.
Ok, not quite, there’s a bit more:
The speakers were all interesting- in the order they appeared:
Cal Evans (he’s the Editor of Zend’s DevZone) walked us through connecting together the UPS package-tracking API and a Google map. He was an entertaining speaker, and made for a good start to the day, even if the talk didn’t really tell me anything I didn’t know.
Simon Laws (a member of the Open SOA group) then explained how the SCA Pecl extension can be used as a way of abstracting access to ‘services’. It seemed like quite a good idea, but I can’t really see myself having much cause to use it. The guy giving the talk seemed to know what he was talking about, and seemed quite passionate about it, but I didn’t feel he did the best job of introducing the subject. Perhaps it was just down to the limited time available, but a bit more background and context would have gone down better with me, rather than the focus on code examples.
After the break for lunch, Kevlin Henney (a consultant/trainer/writer specialising in OOP, Agile development, languages and patterns) answered a series of questions (sent, I believe, in advance) regarding OOP, and how it is implemented in PHP. The main theme of the answers was that he is ‘surprised’ by the way PHP introduces elements of Statically typed languages into its primarily dynamic class system. Kevlin was the most entertaining speaker of the day not just because he made a lot of amusing comments but because he was clearly very passionate about the topic. It’s a shame he only had 45 minutes, I could quite happily have listened for a lot longer.
Immediately following Kevlin was the ‘big name’ of the day, Rasmus Lerdorf whose talk entitled “Fast and Rich” dealt, briefly, with getting the most out of a PHP application. There were some useful points that I took away from the talk, but I was disappointed that the 2nd half of the talk was mainly giving reasons to upgrade to PHP5. It was interesting to hear him speak, and if hearing the message coming from the horse’s mouth means more people stop using PHP4 then that’s great, but I can’t help but feel that his time would have been better spent going into some more examples of improving performance.
The final talk of the day, Desiging for the Curious Home by Bill Gaver of Goldsmiths College, had nothing to do with PHP. It was about interesting devices that Bill and his team have developed to put in peoples homes and observe what they do with them. They made a coffee table that contains a screen showing aerial photographs of the UK. Placing weights on parts of the table affects the direction of ‘drift’ over the map and so over time, the view through the table changes. One of the people they gave this too seemed to get quite into it, carefully placing rocks and referring to an atlas in order to travel around the country finding friends’ houses. Another project involved placing sensors around a family home, recording things such as noise levels, which doors were open and where people sat in order to try and determine the mood of the house as a whole. With this, each day a horoscope was printed for the family to read- they were aware of the sensor-boxes (they were bright orange!) but not of what they were doing, or of what the project was trying to determine. A TV crew, also with no knowledge of the project, were brought in to talk to the family members and review the progress, and it was quite interesting seeing the theories and thoughts ranging from paranoia about being monitored, through to curiosity about what was going on.
The day as a whole was well worth the trip down and I hope I’ll be able to go again next year. It was well organised, there was plenty of coffee and the food put on for lunch was pretty good. There were a lot of people though and while everyone just about fit in the lecture theatre, it was a bit cramped in the gallery area in between the talks.
uk php conference
February 22nd, 2007
I’m off to the PHP Conference in London tomorrow, organised by the London PHP User Group.
I was just checking the website now, and it seems it’s sold out which has to be a good thing for the organisers- perhaps it will mean it’s even bigger next year?
There are 5 talks, covering mashups, web services, OOP, Scalable applications and, deviating slightly from the theme, “Designing for the Curious Home”.
It is the last two that intrigue me most- Rasmus Lerdorf’s “Fast and Rich Web Applications with PHP 5” because I hope to learn some things I can use to make the applications I develop that bit better/faster and the latter because, well, it’s different and sounds quite interesting.
Details of each talk can be found on the site, and I believe it is planned that audio and video will be available afterwards.
I’ve never been to a conference before and I’m quite looking forward to it. To get there though, means waking up at 5:30 am to walk to the station (no buses early enough…) for a 6:30 train, followed by a tube ride from Euston to Elephant & Castle where it’s apparently only a short walk to the venue, which is good. I have a good sense of direction when I’m in the countryside (hiking/driving on rural roads) but as soon as I get into built up areas it goes out of the window and I tend to get lost. Reducing the opportunity for that is best.
plotr
February 7th, 2007
There are a lot of very good Javascript libraries around at the moment, and while the variety is certainly a good thing, it’s a shame that there is so much duplicated effort.
I’ve been using Prototype (and Scriptaculous) for quite a while now and I like it. I genuinely feel now that I understand how it works, and I’m comfortable using it. Recently though, there have been a few occasions where my life would have been easier, if only I’d been using Mochikit.
Most recently, the only decent newsticker I could find (that met client requirements…grr) was reliant on Mochikit. Fortunately the reliance was quite small, and I was able to convert it to use prototype instead.
A while ago, I was asked to look into ways of presenting graphs and charts for the web application I work on. I came across a rather nifty looking javascript solution called Plotkit, but after discovering it relied on the Mochikit library, it got put on the back burner and we’re currently using a Flash-based solution, as it ticks all the ‘pretty’ boxes.
At the end of last week, my attention was drawn to plotr, a prototype-based version of Plotkit, and I got very excited.
My current plan is not to rip out the Flash charts, but instead give the users the choice over which rendering method should be used, with the data retrieval and calculations remaining the same. The Flash files are fed data by providing them with a url to an XML file that contains the necessary data points and config options, and having plotr working in a similar way would probably make my life easiest.
I’ve been having a play around with the code, and I’ve had a go at extending it to allow for remote (insofar as the same-domain policy of xhr will allow…) dataset- and options-retrieval.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
Object.extend(Plotr.LineChart.prototype,{ getRemoteDatasetAndRender: function(url) { var xhr_options = { method: 'get' } xhr_options.onComplete = function(xhr) { var json = eval('('+xhr.responseText+')'); this.addDataset(json.dataset); this.setOptions(Object.extend(this.options,json.options)); this.render(); }.bind(this); new Ajax.Request(url,xhr_options); } }); //we won't include the axis details in the options, // as the remote call will provide them var options = { padding: {left: 30, right: 0, top: 10, bottom: 30}, backgroundColor: '#dbdbdb', colorScheme: 'green' }; var line = new Plotr.LineChart('plotr',options); //then just pass the URL to the function line.getRemoteDatasetAndRender('/dataset.php'); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?php
$dataset = array(
'ds1'=>array(
array(0,0),
array(1,2),
array(2,8),
array(3,32)
)
);
$options = array(
'xTicks'=>array(
array('v'=>0,'label'=>'Mon'),
array('v'=>1,'label'=>'Tue'),
array('v'=>2,'label'=>'Wed'),
array('v'=>3,'label'=>'Thur')
)
);
$return = array(
'dataset'=>$dataset,
'options'=>$options
);
header("Content-type: text/json");
echo json_encode($return);
?> |
I’m not really sure whether this method will be suitable for my purposes or not, I will need to try and integrate it into the actual code, but getting my thoughts down in writing seems to help me think things through, and if it’s useful to anyone else, then excellent.
prototype news ticker
February 7th, 2007
Update:
New version released, look hereThis is a prototype-reliant version of the Mochikit-reliant newsticker found at http://lifeofweb.com/code/javascript-rss-news-ticker/
usage is exactly the same, except you need prototype.js rather than anything from Mochikit; replace the url and element arguments within the start_rss_ticker() function, and you’re away.
There were only a couple of changes needed, namely using Prototype’s Ajax.Request rather than the Mochikit equivalent, and copying in the scrapeText and getElement functions (using $() rather than getElement seemed to break in IE- I assume because of the Element.Extend parts…?)
Get the file: newsticker.js
widgets
January 17th, 2007
I’m a big fan of constructing self-contained ‘widgets’ rather than trying to preserve some semblence of state through a series of unconnected event handlers on different elements. For example, I recently needed to make a lightbox-esque ‘popup’ to show more information about a manufacturer for an ecommerce site.
One approach to doing this, and one I’ve used in similar situations in the past, would be to have something like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<script type="text/javascript"> function openInfoWindow(link) { var div_id = link.id.replace('link_','info_'); $(div_id).show(); } function closeInfoWindow(button) { var div_id = $(button).up('div').hide(); } </script> ... <a href="/manufactures/info/calvin_klein" onclick="openInfoWindow(this);" id="link_calvin_klein"> More Info</a> <div style="display:none;" id="info_calvin_klein"> <input type="button" onclick="closeInfoWindow(this);" value="X" /> <!--etc.--> </div> |
This should be perfectly functional, but it’s clunky. Having the html onclick attributes is the first problem, one I solve using behaviour.js and prototype’s Event functions; for example, adding a class of ‘info_link’ to all the open links allows you to have:
1 2 3 4 5 6 7 8 |
var my_rules = { 'a.info_link': function(link) { $(link).observe('click',function() { this.next('div').show(); },false); } } Behaviour.register(my_rules); |
But it’s still a bit too dispersed for my liking. What I ended up doing is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
var myrules = { 'a.info_link': function(link) { var widget = new InfoWindow(link,link.next('div')); } } var InfoWindow = Class.create(); InfoWindow.prototype = { initialize: function(opener,container) { this.container = $(container); this.opener.onclick = this.openWindow.bind(this); this.container.down('input').onclick = this.closeWindow.bind(this); }, openWindow: function() { this.container.show(); }, closeWindow: function() { this.container.close(); } } |
Now, this is more code but it’s all in one place and it’s still pretty simple and when, in a large application, you find yourself doing lots of similar things, every bit of clarity helps.
versioning databases
December 20th, 2006
Keeping track of, and applying, database changes is probably the part of web development that I find to be the most difficult and annoying.
At the moment, we have a folder in the svn repository called ‘sql’, into which are placed numbered files containing a set of database changes. When the code that needs the changes is checked in, the appropriate file is included along with it. When an update is done elsewhere, it’s a matter of running each .sql file in turn against the database to bring it up to the current version.
The system is working well for us so far, with 3 (ish) developers working on the project, but it seems so brittle. The best approach seems to be to make sure that absolutely every line of sql gets typed into a text file before it is pasted into/run against the development database; this makes it more difficult to forget to include a change, but it can still happen. Performing the update is a laborious task at present- it could probably be scripted, but it seems wrong to put any more effort into this system when there must be better ways of doing things.
Read the rest of this entry