Showing posts with label Code. Show all posts
Showing posts with label Code. Show all posts

Thursday, December 08, 2016

Operator overloading in Swift

After years of having to write [@"bar" isEqualToString:@"foo"] I’m delighted that in swift we can simplify things and just write “bar” == “foo”.

However there is an important thing to note. Swift will match the overloaded operator to function that takes the same arguments. Simple.

So if I follow the example set by the equatable protocol, and wanted to compare two NSObject subclasses, I could create a function that looks something like:

And this would work everywhere as expected and print “hello world” …

Well, no. Remember I said exactly the same arguments.

So, If I was to change the optionality of one of the variables:

let a = Object(name: "foo")
var b:Object?

b = Object(name: "foo")

Our custom equality function will no longer be called, as it only expects unwrapped values. This means that the equality would fail, as the pointers do not match, and the test would fail and doSomethingWhenTheStringChanges would never be called.

The solution is fairly simple, you need to create a version of the overridden operator that accepts optionals, but again remember that the compiler is trying to match parameters, so you also need to cover the case where you have one/two unwrapped parameters.

What will now happen, is that when we have unwrapped parameters it will go directly to the first overridden operator, while optionals will use the second. We use the guard to ensure that we can unwrap both, and then do a pointer equality check which will return the correct result if one, or both are nil.

What makes this behaviour particularly “special” is that it will only happen with NSObject subclasses. When using doing the same thing with a pure Swift class, if you are missing the optional variation of the overridden operator the compiler will require you to explicitly unwrap the variable.

Ultimately I think the best way to avoid this mess is to just do things the old fashioned way and override isEqual: in your subclass.

It should also be noted that Xcode correctly syntax highlights the operator depending on whether you will use NSObject’s version of isEqual: or your own at runtime, but there is no warning.

Tuesday, November 13, 2012

When Magical Record stops being magical

Some time ago i discovered Magical Record. It offers some fantastic categories to help you setup your Core Data stack with a single line of code. But it's much more than a Core Data boilerplate thingy. It also offers a range of Active Record pattern like shorthand methods. For example you can find all the instances of a particular type of object without having to write your own NSPredicate and NSFetchRequest using MR_findAll.

Somewhat recently they moved to version 2.0, along with lots of others features they added support for Nested object contexts. If you haven't read about nested/ parent-child managed object context your missing out, especially if you've ever tried to use Core Data with multiple threads.

So when did it stop becoming magical?

Usually i use Magical Record to setup my core data stack, and take advantage of its singleton default context, for those times when i'm too lazy to pass it around like a good engineer. I've also been known to dabble a little with it's Active Record implementation.

However with 2.0, the developer(s) have chosen to change the internal structure slightly. A "Root" context is created at the top of the tree, this has a child context that is returned when you call the MR_defaultContext method. The root context controls the writing of data to disk. This means that if you attempt to save the MR_defaultContext your changes are not persisted to disk, but instead pushed up to the root context.

Well that awesome, right ...

Well it is, if it was obvious. Instead I was left no errors, an empty sqlite db, and no data. Personally I really think they should have just made the MR_defaultContext the root context, and allowed users to nest contexts themselves if they wish. In case your interested you can reach the 'Root' context by calling MR_rootSavingContext.

Anyways after digging around the source code, and a little RTFM I discovered that in order to actually persist your data to disk you have to call MR_saveNestedContexts. This method will recursively call up the tree and save each context. Neat, but not obvious, especially when the API convention is to simply call the native save:

So really this post exists to say, if your a fan of Magical Record and your pulling your hair wondering why save: has stopped working the answer is use MR_saveNestedContexts.



Thursday, October 18, 2012

Drawing UIImage's with blocks

I have a slight love affair with Quartz's drawing routines. I don't know what it is about them, but there is something I love about stroking rects and filling paths. It's like OpenGL for stupid people.

Anyways, during my love affair I got bit annoyed at having to subclass UIView every time i wanted to make a quick sprite, or overlay a one image on top of another.

CALayer's a are awesome and everything, but i still need to subclass UIView unless i want a bunch of layout mess every where.

So I thought wouldn't it be cool to be able to create UIImage's quickly and then just throw them into a CALayers or UIImageView's and worry about the rest later.
The above does just that, you give it a canvas size or more informally the size of the UIImage that you wish to generate.

It will create the CGBitmapContext with a RGB colorspace, and then you can draw to your hearts content.

You can treat the block almost like a you would drawRect. I say almost because it's not inserted into the graphics context stack, so some of the helper methods like [[UIColor blackColor] setFill] will not work, and you'll have to learn how to do it the 'proper way' (CGColorSetFillColor()). Just consider it a general rule, that if it renders something and doesn't take a CGContextRef you need an alternative method to use it inside this block.

Sunday, September 23, 2012

The evolution of lazy initialization

Lazy initialization is tent pole of Objective C. Apple placed a lot of emphasis on using the pattern in the early iPhone days. That was justified especially considering that the original iPhone shipped with 128MB of RAM, compared to the latest iPhone 5 with 1024MB of RAM.

In the beginning


The ARC evolution


The ARC evolution was fairly tame, allowing us to move the ivar into the implementation files. While the original method was great, and served me well until ARC. With no need to dealloc, and the ability to have iVars that aren't declared in the public interfac.

Clang takes it up a notch


With the most recent versions of Clang you no longer have to use the @synthesize & @dynamic keywords when making @property declarations.
This is all well and good, but I don't want to write my own ivars if I don't have to. So I've set about exploring ways that I can do away with having to create my own ivars.

Option 1.

This approach is comprised of three steps
  1. Public readonly property declaration
  2. Private readwrite property (re)declaration in a class extension
  3. Assign our instance to the ivar

The problem with this is that there is still the ability to overwrite the ivar. Granted it's only from within the class, but still not ideal. This could be an advantage as if you decide to move away from the pattern all you need to do is set the ivar via the mutator.

Option 2.

Another alternative, is to take advantage of another clang feature, where we use the @synthesize directive, to generate a backing ivar on request, without having to explicitly declare the ivar, or at least declare it in a conventional way.
Along with being the smallest version, we can specify the format of our private ivars, so if you want to suffix your underscore rather than prefix it, you have that option.

Whats the solution?

Quite frankly, i don't know. I'm leaning towards Option 2 as it doesn't provide an mutator for the ivar, and so there is almost no suggestion that the ivar should be mutated by anything thing other than the lazy accessor. However I'm interested to hear the opinions of others.

Thursday, September 20, 2012

Social.framework

It feels like an eternity since it was announced but iOS 6 is finally available to the masses, and we can now talk about the all the (few) new goodies that it contains.
Apple included the Social Framework in iOS 6 as an abstraction layer for accessing the various social services that are now included with iOS. The key feature here is that you never have to deal with the Facebook SDK again if you wish...
So let's explore how you can use the new Social framework classes to replace REST API access functionality that is provided via the Official Facebook SDK
TL;DR; Sample code

Create an ACAccountStore

According to Apple's developer documentation the ACAccountStore
[ACAccountStore] provides an interface for accessing, manipulating, and storing accounts. To create and retrieve accounts from the Accounts database, you must create an ACAccountStore object. Each ACAccount object belongs to a single ACAccountStore object.
A simple alloc && init sent to ACAccountStore will suffice. Perhaps the easiest thing you'll do this week.

Get the Facebook ACAccountType

The 2nd easiest thing you'll do this week

Request access to currently logged in Facebook User

Before the callback block is called the User will be presented with a UI to confirm that they want your app to have permission to access this API. In the event that initial permission has been revoked, or disabled you will be given a negative boolean value.

Select an authenticated ACAccount

Your block will need to reference your ACAccountStore instance in order to see which accounts you have access to. To actually access the accounts you need to call the accountsWithAccountType: method which returns a NSArray of ACAccount objects. Where the type argument is account type we got in the previous section.
Apple has designed the ACAccountStore class to support multiple authorised user accounts. While iOS 6 only supports a single Facebook account, it does support multiple Twitter accounts. So while it is safe to assume that first (and only entry) in this collection is the ACAccount you want to use, the same cannot be said when you are working with Twitter accounts. Ideally you would want to present a 'picker' UI to the end user.

Construct a SLRequest

SLRequest is the Social frameworks NSURL request abstraction to enable it to support request signing, and token passing, features used by Twitter and Facebook. The SLRequest class also has a convenience method for dispatching this request.
If you are a fan of request queuing, and application wide request management there is also the option to extract a prepared NSURLRequest object with you can then pass to something like an AFNetworking request operation (See below).


That's it! If you weren't able to string the process together in your head magically, you can view the entire gist. Thanks for reading!

Wednesday, September 07, 2011

Making UIImages with blocks

So i was going to post about something completely different today, but as i was typing i looked at my code, and thought it was verbose and a little bit ugly.

So i made it awesome, and as everyone knows to make your code awesome you add some blocks to it.

My problem was simple, i was faced with the need to create two CGBitmapContext, for the uniformed the following code is required to prepare a bitmap context for drawing.


So after a bit of thought, i decided what i really wanted was a method that did all of this for me, and meant that i didn't have to worry about constantly checking the code for leaks (DRY), and that was pleasant to look at and i came up with the above. The block that you pass in is given a fully formed CGBitmapContext, and the method returns a UIImage generated from that context. Almost like a UIView/CALayer.



So now your thinking, "Yeah, thats cool, but why the [INSERT FOUR LETTER WORD] would i want to use it ?" Well young grasshopper, have you ever wanted to mask a image in code? You know to do those trendy rounded corners ... well yes you can use CALayer's however the idea of using those off the main thread makes me uneasy, and we all know the cool kids do things in the background.


The above actually creates a rounded rect on the fly, and masks the image with it. It's made to be used in a category on UIImage. But look closer, yep thats right kids, no boiler plate, ZERO, NADA, 另, SQUAT (i think you get the point)!

I should take a moment to mention that the awesome code for the rounded rect comes from the awesome Oliver Drobnik, i have the utmost respect for this guy, not just for this snippet, but if you've ever seen his Rich text label and it's associated projects, you'll understand why real soon.

Sunday, April 10, 2011

Drawing text with a Gradient

Problem

You want to draw (unicode) text with filled with a gradient.

Solution

Since my middle name is now "Core Graphics", let me help you out. It's actually pretty simple. Create your desired gradient in a your image editor of choice, and save it as a PNG. Import it into your project and then ...

Yep folks thats it. Now if you find that your gradient is slightly out of place, you can use CGContextSetPatternPhase to help. You of course would use this before your drawing statement. The docs say:

The pattern phase is a translation that Quartz applies prior to drawing a pattern in the context. The pattern phase is part of the graphics state of a context, and the default pattern phase is (0,0). Setting the pattern phase has the effect of temporarily changing the pattern matrix of any pattern you draw. For example, setting the context’s pattern phase to (2,3) has the effect of moving the start of pattern cell tiling to the point (2,3) in default user space.

So when all is said and done you get this lovely effect

text drawn with a gradient Best of all this effect works all the back to iOS 2.0!

Sunday, January 27, 2008

The gift that just keeps on giving

After my 14 hour stint yesterday, i'm back on the trail.

Today i've cooked up a Javascript shopping cart. In true fashion it's all OO, and shiny. However very unlike me, it's JS library agnostic! Yes, thats right, i wrote by very own 'getElementById' staements!. I've only provided methods for adding, removing, and getting the price of all the objects. There is also a method for updating a ordered or unordered list, with the items stored in the object.

Javascript (No Library required!)

//Basket Object
//Library agnostic
var BasketObj = function(){
this.items = new Array();
this.bindToElementId = null

//Add an object to the basket
this.addItem = function( pObj ){
retVal = false;
if( pObj.name.length > 1 ){
this.items.push( pObj );
console.log('Object added to basket');
retVal = true;
}
else{
console.log('Not a valid object');
}

return retVal;
}
//Remove the first matching item from the basket and return it
this.removeItem = function( pItemName ){
var retVal = null;

for(i=0; i < this.items.length; i++){

if( this.items[i].name == pItemName ){

console.log('Object removed from basket')
// reference the obj
retVal = this.items[i];
//dereference it
this.items[i] = null;
//exit the loop
break;
}

}

return retVal;
}

//Calculate the total basket value
this.total = function(){
var retVal = 0.00;

for(i=0; i < this.items.length; i++){
retVal += this.items[i].price;
}

return retVal;
}

//Updates the gui display of the object
this.updateDisplay = function(){
if( this.bindToElementId != null ){
//Empty the element first
document.getElementById( this.bindToElementId ).innerHTML = '';

//Sort the array before we print
//this.items.sort();

//Now proceed to fill it
for(i=0; i < this.items.length; i++){
document.getElementById( this.bindToElementId ).innerHTML += '<li>' + this.items[i].name + '</li>';
}
}
}
}


To use it, you must first create the object,


x = new BasketObj();


Once thats done you can set it up, the only thing that you really need to set, is the id name of the object you wish to have the results shown in. This is store in a variable called bindToElementId.

x.bindToElementId = 'basketList';


Now you can add your objects to it. Your objects can be as complex as you want, however they must have the following properties,
name: This is the display name for the object, and the name that will be used for internal lookups
price: This is the value that will be added to create your total,

You use the addItem() to add items to the object, and the removeItem( nameOfObject ) to remove items.

To update your list with the current objects you call updateDisplay. And to get the total value of all the objects you can call total().

One other thing to mention, is that i use console.log statements, so be aware of those, and also i check for the name attribute before adding objects to the internal array, so don't try and add them, and prototype the method to your object later on.

Anyways, this object features in my DFTI coursework, which i've been streaming though over this past weekend, i've now implemented the Drag and drop shopping and it looks a little something like this...



I still have to do the admin page, and stock control logic, however imagine this could be done in a day or so.

When it rains it php's

Ever wanted to convert a camel case string into something more user friendly?

Introducing the super dupa know it all function, should be good for PHP 4+

PHP

/*
Make a camel case string user friendly ^_^
*/
function implodeCamelCase( $pStr, $delimiter = ' '){

$strArr = str_split($pStr);
$retArr = array();

foreach( $strArr as $val ){

if( ord($val) <= 90 ){
array_push($retArr, ' ');
}

//add to return array
array_push($retArr, $val);
}

//explictly destroy array
$strArr = null;

return mb_convert_case(implode('',$retArr),MB_CASE_TITLE);
}


It's a bit rough around the edges, anything thats not a lower case character or anything else with a decimal ascii number over 90, will have a space inserted before it, of course thats easy enough to tweak.

Saturday, January 26, 2008

Json Encoding

For a enterprising young developer like myself, i don't take advantage of json enough. So since i'm in the mix at the moment, with my DFTI course work, i thought now would be a good time.

Unfortunately the json_encode() function that i had seen in the PHP documentation, is only in the CVS distributions at the moment (v 5.1.2), so i came up with the below.

PHP

/*
This function converts an array to a Json string.
*/
function jsonEncode( $pArr ){
$arr = Array('{');

foreach( $pArr as $val ){

if( is_numeric( $val) ){
array_push($arr, $val );
}else{
array_push($arr, '"');
array_push($arr, $val);
array_push($arr, '"');
}
array_push($arr,',');
}
//Remove trailing comma
array_pop($arr);

return implode('',$arr);
}

/*
This function converts an associative array to a Json string.
*/
function jsonEncodeAssoc( $pArr ){
$arr = Array('{');

foreach( $pArr as $key => $val){
array_push($arr, '"');
array_push($arr, $key);
array_push($arr, '"');
array_push($arr, ':');

if( is_numeric( $val ) ){
array_push($arr, $val);
}
else{
array_push($arr, '"');
array_push($arr, $val);
array_push($arr, '"');
}

array_push($arr, ',');
}

//Remove trailing comma
array_pop($arr);

array_push($arr,'}');

return implode('',$arr);
}


Both functions take either a regular array, or a Associative and converts it to a json string, which looks like ...


{"id":1,"name":"Ham And Pineapple","description":"<p>Fusce magna sem, gravida in, feugiat ac, molestie eget, wisi.</p>","categoryId":1,"hasNuts":0,"vegetarians":0,"imagePath":"ham-and-pineapple.gif","price":4.95}



The above is just some data from my database. It's a pizza ordering system. I plan to go all ajaxan with a Drag and drop shopping cart, as well as some other shiny stuff.

I haven't a clue what i'm going to do concerning javascript, i'm looking at mootools, mochikit, and of course jquery and maybe even yahoo ui. Might be a last minute thing.

Thursday, July 19, 2007

CSS research

I'm completely knackered, but research is my life. One of my many clients wanted a semi transparent div. Now i say div, but they just want it to look shiny.

Basically then want an element with appox 20% opacity. Easy right, use a PNG. But that cancels out all ie versions apart from 7. How about a gif instead, you dont get alpha transparency! Well genius how about css, great, there are ways to do it on webkit, gecko, and ie, however they apply the same amount of transparency to their children.

the trick here is to think outside the box, literary...



Thanks to relative positioning, i made a solid div below my transparent div, and moved it over the transparent div, creating a the above effect. The cool things is that by modifing the z-index you can create a ghosting effect!

Best of all, there are no images used to create the above, (well apart form the obvious background pattern on the body), more testing is needed, but i think i might be on to something here.

The CSS
*{
text-align:center;
margin:0;
padding:0;
}
body{
background: url("pattern.gif");
}
div#wrapper{
margin:0 auto;
width:70%;
text-align:center;


padding:1em;
}
div#panel{
opacity: .50;
height:200px;
background: #ddd;
width:100%;
margin:0 auto;
}
div#wrapper p{
padding:1em;
background: #000;
color:#fff;
width:90%;
position:relative;
margin:0 auto;
top:-180px;
z-index:1;
}

The html


Transparent div

content goes here






Now if you excuse me, i'm off to bed

Friday, April 06, 2007

Useful Email validation

Got some javascript, for the coders out there. Not my finest work but quite neat.

This validates a email field, combined with a simple input field as shown.

HTML



"<"input id="emailInput" class="halfSize" type="text" value="Place Replay to Email here" name="replyTo" onkeyup="validateEmail( this.value);" />


However it does it in a funky AJAX way, allowing the user to see where exactly they have put a foot wrong.

it checks the following

  • Address is longer than 6 characters

  • There is a @ symbol present

  • and there is a "." within the domain section of the email



The 6 character mimumim was calculated using the following logic,

1 = one character for username
2 = one character for the @ symbol
3 = one character for the domain
4 = one dot/decimal to seperate the domain from the TLD
6 = two characters for TLD and ccTLD.

First improvement, that one should make, is enable both the input field, and result field to be supplied as function arguements, however in my case (internet computing assignments), this is only getting used once.

Javascript



function validateEmail( pEmailObj ){

var pEmailString;
var retVal;
var returnObj = "emailValidStatus";
var whereIsSymbol;

//Setup
pEmailString = pEmailObj;
document.getElementById(returnObj).style.background = "#bf3a3a";
document.getElementById(returnObj).style.color = "#fff";
document.getElementById(returnObj).style.padding = "2px";

//Go Down a level after each check
if(pEmailString.length > 6){ //Check length

if( (whereIsSymbol =pEmailString.search(/@/)) > -1){ //Check for @ symbol

//Find the dot after the @ Symbol
var lastDot = pEmailString.indexOf( ".", whereIsSymbol)

if(lastDot != -1){ //Check for . after @ symbol
document.getElementById( returnObj ).style.background = "#71ba43";
retVal = "Valid!";
}
else{
retVal = "Invalid: Bad Domain";
}
}
else{
retVal = "Invalid: Missing @ symbol";
}
}
else{
retVal = "Invalid: Too short";
}

document.getElementById( returnObj ).innerHTML = retVal;
}


Last but not least it's Released under the GPL, so use it and abuse it.

Friday, March 30, 2007

I love to function

While working on my piece of piss Java assignment, i came up with a neat little random number generating function. It's a mirror of a function that is commonly used by Objective-C developers, and allows you to have random numbers but within a range. I've casted the result before i return to the calling routine, so you simply change or remove the cast to get the primitive of your choice, as it's all Floating point arithmetic.

Java



private int randomIntWithinRange(int pLow, int pHighest, boolean pDebug){
boolean acceptableValue = false;
double possibleValue;
double finalValue = - 0.1;
int attemptsTillSuccess = 0;

//If the value is not acceptable continue
while(!acceptableValue){
possibleValue = Math.random() * (pHighest * 10);

if(possibleValue >= pLow && possibleValue <= pHighest){
finalValue = possibleValue;
acceptableValue = true;
}
else{
attemptsTillSuccess++; //How many times
}

}

if(pDebug){
System.out.println("" + attemptsTillSuccess + " attempt(s) till success"); //debuging
}

return (int)finalValue;
}

It's even does a little debugging line, so you can see the number of attempts till it succeeds. Released under the GPL 2.0, For use in non-commercial products yada yada. When i can be asked i'll write a Javascript, and C version, and if i feel really nice a VB version.

Update: With me having banned myself from facebook for a while, i thought i would make myself more useful and covert the java to ECMA script, of Javascript for lesser clued up, wasn't hard just replaced primitive declarations with var ^_^.

Javascript



function randomIntWithinRange( pLowest, pHighest, pDebug ){
var acceptableValue = false;
var possibleValue;
var finalValue;
var attemptsTillSuccess;

while(!acceptableValue){
possibleValue = Math.random() * (pHighest * 10 );

if(possibleValue >= pLow && possibleValue <= pHighest){
finalValue = possibleValue;
acceptableValue = true;
}
else{
attemptsTillSuccess++; //How many times
}
}

if(pDebug){
Document.write(attemptsTillSuccess + " attempts till success"); //debuging
}

//Damn loosely typed language!!
return Math.round(finalValue);



PS. I didn't test the javascript version, so don't count on it to work straight off the bat.