tonymillion-blog
tonymillion-blog
Highly Opinionated
19 posts
Tony Million's blog - Life, iOS, Python and other stuff
Don't wanna be here? Send us removal request.
tonymillion-blog · 11 years ago
Text
Django is consistently shit in a specific way.
The problem with Flask is, because all the extensions to make it Django-like are built by 3rd parties its shit in every possible way.
Quite…
0 notes
tonymillion-blog · 11 years ago
Link
Today, the tech industry is apparently on track to destroy one of the world's most valuable cultural treasures, San Francisco, by pushing out the diverse..
0 notes
tonymillion-blog · 12 years ago
Link
It’s only been a few days since we launched v1.0, but there’s no time to rest. The main feature in our first update is support for multiple journals.
You can now create as many journals as you please and “rejournal" entries to them. Start journals for events, holidays, family life, work, pets,...
4 notes · View notes
tonymillion-blog · 12 years ago
Link
The hardest part about journaling is getting into the habit and remembering to keep it up.
When we sent out a survey to our followers, we learned that over 40% of respondents like the idea of keeping a journal or have tried to in the past and given up. 
9 notes · View notes
tonymillion-blog · 12 years ago
Photo
Tumblr media Tumblr media Tumblr media Tumblr media Tumblr media Tumblr media Tumblr media Tumblr media Tumblr media Tumblr media
This is Narrato’s new home. We moved into our new space at Wayra today!
2 notes · View notes
tonymillion-blog · 12 years ago
Text
Will the rise of wearable computing lead to an increase in life-logging and self-quantifying?
Currently, most of the popular wearable computers on sale are focused on health, fitness, and life-logging.
The Nike FuelBand, Fitbits, and even the Memoto camera are all made to help us collect more data about ourselves and use it to improve our lives in one way or another.
The Pebble Watch is an exception that shows signs of this changing. It’s a watch that’s mainly about the convenience of having important information on your wrist instead of in your pocket.
Tumblr media
“Wearable computing devices are projected to explode in popularity over the next year”
ABI research forecasts that 485 million wearable computing devices will be shipping yearly, by 2018. If that was to happen, would interest in life-logging and self-quantifying increase as much too?
Read More
3 notes · View notes
tonymillion-blog · 12 years ago
Text
Parsing python datetime isoformat using NSDateFormatter REDUX
So since my last post about parsing python datetime.isoformat using NSDateFormatter I’ve discovered a lot more about the intricacies of doing it successfully, and heres what I’ve gleaned:
First: When there is no microseconds in the datetime isoformat() wont print it
Second: if the microseconds aren’t included in the output, the previous code I posted wont parse it (it’ll return a nil date).
The fixed code:
NSString * inputDate = @"2012-07-19T08:31:23Z"; NSDate * parsedDate = nil; NSDateFormatter *dateFormatter = [NSDateFormatter new]; [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSSSS"]; dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; parsedDate = [dateFormatter dateFromString:inputDate]; if (parsedDate==nil) { NSDateFormatter *iso8601Formatter = [NSDateFormatter new]; [iso8601Formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"]; iso8601Formatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; iso8601Formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; parsedDate = [iso8601Formatter dateFromString:inputDate]; }
This code will “nicely” fail over and use a non-microsecond parser.
BUT WAIT THERES MORE
If you don’t actually need the microsecond accuracy then theres a “better” way to do this, from the python side. Anywhere you are outputting a datetime do the following:
output_ts = str(dt.replace(microsecond = 0).isoformat())+"Z"
(where dt is our datetime object). 
This has the advantage of making sure that all datetimes are “iso8601 compatible”. To decode it use the following code (taken from the code above)
NSDateFormatter *iso8601Formatter = [NSDateFormatter new]; [iso8601Formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"]; iso8601Formatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; iso8601Formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; parsedDate = [iso8601Formatter dateFromString:inputDate];
** its bad-form to allocate a NSDateFormatter each time, it has a fairly hefty setup overhead, you should allocate it in your instance init.
And in summation
If you need to include microseconds in your output, you would be better off outputting it as a float in the format seconds.microseconds and parsing it using [NSDate dateWithTimeIntervalSince1970:] which supports floating point NSTimeInterval input.
To output a float from a datetime (dt) in Python:
import mktime sec_ms = mktime(dt.timetuple()) + dt.microsecond/1000000.0
0 notes
tonymillion-blog · 13 years ago
Quote
Blindly using sample code you find on the internet without reading up on how the technology works is not a good way to develop applications (a lot of people are guilty of this)
0 notes
tonymillion-blog · 13 years ago
Note
Hello Tony, I am using your Reachability code from GitHub and i have a question. I noticed that sometimes my classes doesnt get deallocated when i call [self startNotifier];. Do i have to ever call [self stopNotifier];? also, do i have to declare the Reachability variable inside the method that is calling it or can i declare it as an ivar? Thanks, Newton
You shouldn't have to subclass Reachability, you can simply create it as an iVar in (for example) your App Delegate.
If you use the block based callbacks the Reachability object that is calling the block is passed in as a parameter, if you use the NSNotification system it is passed as the 'object' of the Notification.
When you call startNotifier, the Reachability object retains itself (this is by design) so it can dispatch Reachability change notifications, calling stopNotifier will cause the object to dealloc, unless you have a strong reference to it. 
Check the sample code for more information on how to correctly use Reachability.
0 notes
tonymillion-blog · 13 years ago
Text
How to parse python datetime isoformat using NSDateFormatter
I looked around for a while and didn't find anything that worked properly and included the millisecond param so here it is in all its glory:
NSDateFormatter *dateFormatter = [NSDateFormatter new];  [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSSSS"]; dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; NSDate * parsedDate = [dateFormatter dateFromString:@"2012-07-19T08:31:23.492123"]; NSLog(@"parsedDate: %@, %f", parsedDate, [parsedDate timeIntervalSince1970]);
Edit: to add this to RestKit use:
// Set it Globally [RKObjectMapping addDefaultDateFormatter:dateFormatter]; [RKObjectMapping setPreferredDateFormatter:dateFormatter];
0 notes
tonymillion-blog · 13 years ago
Video
youtube
If we can do this with Lemons then we can make Cave Johnson's dream a reality!
0 notes
tonymillion-blog · 13 years ago
Text
Why Instagram is so fast and has a million naughty photos
Remember that post that did the rounds a month ago or whatever that detailed the instagram photo upload process? If not, heres the slide.
For some reason it suddenly occurred to me this morning, since the upload starts before the user has actually hit the save button, I wonder how many people have taken photos of their genitals, or a lewd act, then just seen what the Instagram filters make it look like?
With the way they opportunistically upload the photo before you've pressed save, they may well have received your dirty picture before you hit the cancel button!
0 notes
tonymillion-blog · 13 years ago
Text
Grabbing a Random Document in Mongo
Recently with ZummZumm I had a requirement to grab a random document from a collection, A bit of googling ended up here, the jira for mongodb which is essentially marked ' will not do '.
A bit more googling resulted in people suggesting something like:
db.collection.all()->skip((rand()/RANDMAX)*documentcount)->limit(1)
which is horribly inefficient. It basically makes mongo load all the indexes of all the documents iterate over them to skip to the relevant document and return that, problem is it takes linear time to skip all those documents till it hits the index you want.
Buried in the comments is a link to this site, where the author basically advocates embedding a random number in the document then doing a find where you look for the next number higher than the return from Math.Random(). Now that works, but for sparsely populated data it often returns the same document, for example:
Imagine you have the following data:
[0.0, 0.1, 0.11, 0.2, 0.7, 0.8, 0.9]
for any value greater than 0.2 and less than 0.7 it will return the document at 0.7. Obviously not a good solution for sparse data sets.
Then I stumbled across an interesting idea, that is to use Mongo's geo-spacial extensions to provide a random document, heres how:
In your document add a field like so:
{randomizer:[Math.Random(), 0]}
add an index:
db.collection.ensureIndex({randomizer:{'2d', min:0.0, max:1.0}})
now, to select a random document you simple use a $near search to find the nearest document:
db.collection.findOne({randomizer:{$near:[Math.Random(),0]}})
Because I'm using Shanty Mongo to abstract the mongo stuff, I simply popped the code into a base class derived all my real classes from that, and boom, instant easy random document retrieval!
12 notes · View notes
tonymillion-blog · 13 years ago
Text
Do what you love, or stop doing it.
So, ZummZumm has been out a little while, and it has a decent user-base for an un-promoted, un-TechChrunched app/service, and you know what, every day working on it is a day filled with Joy.
Every time I see the comment count on the stats page jump up I feel a sense of deep satisfaction. Satisfaction that I've developed something that someone has found the software useful or joyful enough to use. I literally shake with excitement when I think of a cool new way of doing something, or something brilliant I can add behind the scenes that I hope people are going to, if not love, at least find cool.
Its still incredibly early days, and I'm glad of this time, with the friendly people using the service right now, and I love that they are finding worth in the software. The discussions it has brought up are amazingly deep and poignant considering no one knows who each other are.
Which brings me onto the reason for this post, to my last gig at Bababoo.
Now, Bababoo was an amazing idea, a seamless easy way to bypass the carrier when making calls. It was an great piece of technology and for the most part when it worked, it worked really well. I still get good feedback from people about it to this day.
But I never got any joy from it, and any complements I get about it these days sting.
It took over a year to develop, it shouldn't have done, but it did and by the time it hit the market, I had been through the mill, pulled this way and that during the development process, hindered in my work, and generally exhausted by the whole process.
So when I saw we got several hundred users in a day, it didn't fill me with joy that these people might be finding it a useful part of their lives, I simply felt despair at the fact it was several hundred more people I'd have to support.
I was embittered by my own software… And that felt awful.
I seemed to be constantly angry, moody and easily upset. Why the hell was I working so hard on this, slogging my guts out and getting no real satisfaction, emotionally or monetarily, in return? Looking back, I was probably not a nice person to be around at that point in time.
Then something crazy happened. Its been spun a number of ways, but to cut to the chase: I was fired. I was fired from a company based on software I made by someone who wasn't even involved until well after the time it was out.
I didn't feel any of the emotions I expected to feel, I wasn't sad, I didn't feel lost. I felt a sense of relief about the whole thing, because suddenly I didn't have to give a shit any more. I was finally divorced from this marriage:
I realise I had no love for Bababoo.
3 notes · View notes
tonymillion-blog · 13 years ago
Text
How to *really* reduce the size of your iOS app.
I recently read this article via @_DavidSmith on twitter. While noble, it does miss a fairly big optimisation technique. That is reducing the bit depth of your PNGs from 32bit(16 million colours) to 8bit (256 colours).
I hear many of you crying out in pain right now, but stay with me.
Really, unless you're using a huge colour gamut, or using alpha channel effects you may get away with using 256colour PNGs and save yourself 3/4 of the file size… yes thats right a 75% reduction in file size!
Here is an example of the splash screen for one of my apps one is 32bit the other is 8bit:
Can you tell the difference? Perceptially maybe not, but in terms of file size, the 32bit PNG is 999k and the 8bit PNG is 378k. Thats quite a saving eh? So how do you achieve this amazing saving?
Well if you use photoshop to generate your UI elements, quite simply: you use the 'Save for web and devices" 
This will bring up a funky UI allowing you to do a side by side comparison of the original image versus the one you are going to save. Up in the top right of this UI is a drop down where you can change the format of the saved file (I've highlighted it in the image below). Select PNG-8 from here, then set the dither to Diffusion. 
The dithering is important! Why? Well printers have been doing dithering for years, you might not have noticed as the PPI of printers was so high, but they do it. Guess what… your iPhone 4/4S has a PPI as high as the 'base' of a laser printer, so dithering is a very real option for graphics now.
From here you can save out the final image.
While this isn't perfect for every UI component, e.g. places where you use a wide colour gamut, or places where you need alpha translucency, it is a sure fire way to reduce the size of your application.
And while I can already hear complaints of 'but its 256 colours', yes that individual element is, but that doesn't stop it being composited at the full 32Bit colour of the iDevice's screen, so if you're clever with how your UI is layered you can create a full-colour UI from a whole bunch of 256colour PNGs each with their own palette.
So stop and ask yourself (or your graphics guy) do you really need that 32bit PNG for your nav bar or can you get away with a 256 colour one. 
Case in point: using this technique I reduced the size of the ZummZumm .ipa file from about 8 Megabytes down to the current size of 2.6Megs!
23 notes · View notes
tonymillion-blog · 14 years ago
Text
Finished!
We finished the new app we were working on and submitted it to the app store earlier this week. Wether it gets approved before the AppStore-Haitus on the 22nd is another matter entirely.
The service uses a whole bunch of 'modern' technology like MongoDB and such. So there was a learning curve involved too, but the app took less than 30 days to do from conception to delivery, really a lot less as I had to spend a week visiting my dad who was in hospital.
We wanted to launch with Audio recording, Video, and a whole bunch of other post types but it was obvious half way through development that those were going to add weeks of work to the development schedule, so we'd completely blow christmas and new year.
So I made a decision - "lets do them next revision" - after the pressure is off and we've had a moment to reflect. Too many times I've seen the situation where too few people are trying to do too much work.  We simply didn't have the bandwidth to deliver on all those things right now, and having too many balls in the air at once means we'd have dropped a few.
And this is the crux of this post, I took the decision to release an app that does a few things really well than to release an app that does a lot of things badly. We can, in subsequent revisions add another 'thing' that the app does really well. Until, at some distant point in the future, the app does a lot of things really, really, well.
The fact that I had complete control to make that decision is like a breath of fresh air, there are no management to worry about focus groups, no one to cast down a dictate of 'well if it doesn't do <minor feature that very few people will use> then we can't release'.
So, while its not perfect (yet) and theres absolutely no guarantee that it'll change the world, it cost about $2000 to make (yes thats right two thousand dollars). Since I've bootstrapped my startup with $100,000 we can make another 50 of these before we run out of cash.
0 notes
tonymillion-blog · 14 years ago
Text
I'm back baby!
And as a first post I'd like to point you to a new project of mine over on github called Reachability.
Its basically a 'drop in' replacement for the old Apple reachability, however it takes advantage of Grand Central Dispatch and Blocks to make your life a heckuvalot easier!
using it couldn't be easier, see the example below:
// allocate a reachability object Reachability* reach = [Reachability reachabilityWithHostname:@"www.google.com"]; // set the blocks reach.reachableBlock = ^(Reachability*reach) { NSLog(@"REACHABLE!"); }; reach.unreachableBlock = ^(Reachability*reach) { NSLog(@"UNREACHABLE!"); }; // start the notifier which will cause the reachability object to retain itself! [reach startNotifier];
In addition your old code that uses NSNotificationCenter will continue to work too!
8 notes · View notes