Jan
31
2012
Recently we had to conduct a performance test on our Push Notification Server software to measure how long it would take to deliver a large number of Push Notifications to the Apple APNS.
Bombarding the Apple APNS with 500,000+ messages might not go down well with Apple, and we didn’t want to risk getting our server IP blocked for any reason.
We created a fake APNS on a separate server that we could point our Push Notification Server to. This would accept the request but do nothing with it. It’s not a 100% accurate test (the Apple APNS would be slightly slower since it processes the data), but it’s good enough to find a benchmark.
We implemented this using Python, which you can find the code for below. To use this, run the script on the server you want to be the fake APNS. Then in your code that connects to the socket, replace the apple url with the one to this fake server.
e.g “ssl://gateway.push.apple.com:2195″ will become “tcp://yourserver.com:2195″
From this test and other tests we performed, we found that we could send between 1,000 to 3,800 Push Notifications a second to the APNS. Not too shabby I think!
import SocketServer
HOST = "0.0.0.0"
PORT = 2195
# this server uses ThreadingMixIn - one thread per connection
# replace with ForkMixIn to spawn a new process per connection
class EchoServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
# no need to override anything - default behavior is just fine
pass
class EchoRequestHandler(SocketServer.StreamRequestHandler):
"""
Handles one connection to the client.
"""
def handle(self):
print "connection from %s" % self.client_address[0]
while True:
line = self.rfile.readline()
if not line: break
print "%s wrote: %s" % (self.client_address[0], line.rstrip())
#self.wfile.write(line)
print "%s disconnected" % self.client_address[0]
# Create the server
server = EchoServer((HOST, PORT), EchoRequestHandler)
# Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
print "server listening on %s:%s" % server.server_address
server.serve_forever()
no comments
| posted in Code Examples, iPhone, Server
Aug
25
2011
Wow, I guess we all shouldn’t be surprised that eventually Steve Jobs would resign as CEO of Apple, especially considering his health problems and extended medical leave from the company’s day to day runnings.
However it is a little sad to find out the day has finally come. I wish Steve Jobs all the best for the future and with his recovery.
This is Steve Jobs’s Resignation letter in full:
To the Apple Board of Directors and the Apple Community:
I have always said if there ever came a day when I could no longer meet my duties and expectations as Apple’s CEO, I would be the first to let you know. Unfortunately, that day has come.
I hereby resign as CEO of Apple. I would like to serve, if the Board sees fit, as Chairman of the Board, director and Apple employee.
As far as my successor goes, I strongly recommend that we execute our succession plan and name Tim Cook as CEO of Apple.
I believe Apple’s brightest and most innovative days are ahead of it. And I look forward to watching and contributing to its success in a new role.
I have made some of the best friends of my life at Apple, and I thank you all for the many years of being able to work alongside you.
no comments
| posted in General, iPhone
Apr
11
2011
We recently upgraded to Xcode 4 and we found a lot of our static libraries no longer built due to a change Apple made with symbol visibility settings.
The errors crop up something like this:
ld: bad codegen, pointer diff in b2ContactListener::b2ContactListener()to global weak symbol vtable for b2ContactListener
The fix we found was to modify the build settings for every static library, as well as the App to:
Symbols Hidden By Default = YES
Inline Methods Hidden = NO
Hopefully this helps someone else out with the same problem!
1 comment
| posted in iPhone
Sep
24
2010
Using the UIImagePickerController with sourceType = UIImagePickerControllerSourceTypeCamera (to use the Camera), I wanted to overlay my own controls on the screen.
This is simple and can be done like this:
imagePickerController.showsCameraControls = NO;
No problem, right? However this leaves a black bar at the bottom, about 50px or so high!
The black bar is due to a difference in size ratio between the camera and the screen. You can fix this by transforming the camera very slightly:
CGAffineTransform transform = CGAffineTransformMakeScale(1.3, 1.3);
imagePickerController.cameraViewTransform = transform;
The result is a full screen camera image! It is ever so slightly bigger but it’s not noticeable unless you put it side by side with a non transformed version.
no comments
| posted in Code Examples, iPhone
Sep
11
2010
Apple has finally got round to publishing a document of guidelines for the App Store Review process. A lot of it is stuff we already know, but it’s nice to read it direct from Apple.
“We have over 250,000 apps in the App Store. We don’t need any more Fart apps. If your app doesn’t do something useful or provide some form of lasting entertainment, it may not be accepted.” – Thank you Apple!
no comments
| posted in General, iPhone
Aug
27
2010
Recently I wrote some conditional code to call various methods depending on the version of iOS running on the device. A problem I came across was that because I still called some deprecated methods I was getting warnings during my build. As I treat all warnings as errors I had to find a solution which would compile. #pragma was the answer.
You can use the following line to disable warnings for depreciated calls:
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
And use this to re-enable it:
#pragma GCC diagnostic warning "-Wdeprecated-declarations"
Here’s how I used it:
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- (id) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)reuseIdentifier
{
if([super respondsToSelector:@selector(initWithStyle:reuseIdentifier:)])
{
if(self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])
{
[self setupCell];
}
}
else
{
if(self = [super initWithFrame:CGRectZero reuseIdentifier:reuseIdentifier])
{
[self setupCell];
}
}
return self;
}
#pragma GCC diagnostic warning "-Wdeprecated-declarations"
no comments
| posted in Code Examples, iPhone
Mar
11
2010
UIImage is a great class, but it has a lot of limitations.
Image resizing is one of them (the lack of). If your looking for a way to re-size UIImages, save your self the agony of copy/pasting the numerous code examples you’ll find through stackoverflow or whatever. I was shocked by the amount of people posting buggy code, for what is actually a relatively simple problem.
I do find it funny that people describe CoreGraphics or Quartz as low level APIs. For a primarily Objective-C coder maybe, but for anyone who has experience with C, it shouldn’t pose much of a burden. Sure CoreGraphics IS lower level than UIImage, but I’d still describe it as a fairly “high level” API, especially when you compare it to OpenGL.
Anyhow, if your looking to re-size UIImages easily, without having to use CoreGraphics or Quartz, I would strongly recommend checking out Trevor’s article over here:
http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/
He has written some UIImage categories which will save a lot of time, and more importantly they are well written (and work).
no comments
| posted in iPhone
Mar
10
2010
Since the new year Apple appears to be making massive improvements to their overall approval times. An update for F1 Insider was approved in about 48 – 72 hours, which we had previously planned for 1 – 2 weeks!
Very good job, I hope it continues.
Now we just need to get some consistency in the approval/rejection guidelines
no comments
| posted in iPhone
Jan
12
2010
Had a frustrating issue this weekend with one of my Xcode projects. I’ve been working with this project for months, without problems, and then suddenly the application won’t install onto the Simulator, and when ran onto the device, I’m greeted with the error: “The application does not have a valid signature.”
Note this is not the same as the more common invalid provisioning profile error. I of course, googled my problem with the error message, but to my surprise found very little of anyone else with the same problem.
After a slow process of elimination, I finally tracked down the problem.
In my application, the directory structure of the resource files is very important. Added folders with the default option in Xcode, adds them as a group, and in the resulting application, all the files are copied into the top directory. This creates problems with you have files which share the same name, in different directories.
The solution to this is of course use reference folders (the second option you can select when added files to the project).
This is all fine and dandy, but what caused my Xcode project to go haywire, was the fact that my reference folder was called “resources”. The solution, was simply to rename the folder to “resource” (or anything else in fact), and after a clean, it works.
Very very strange error, but thankfully with an easy fix, once you know how!
6 comments
| posted in iPhone
Dec
2
2009

PageControl Examples
The UIPageControl has no way of changing the colors of the dots. Kind of annoying right? Well I knocked up a simple solution to customising the look of the UIPageControl.
This class allows you to replace the dots with your own UIImages, with the following 2 properties:
@property (nonatomic, readwrite, retain) UIImage* imageNormal;
@property (nonatomic, readwrite, retain) UIImage* imageCurrent;
It works by replacing the UIImage on the UIImageView containing the original dot.
One word of warning, if Apple change the way the UIPageControl works, this code will most likely break (especially if they change the dots so they are no longer UIImageViews!). However I’d say the only reason this would happen, is if they add their own functionality in to customise the look of it, so it’s probably OK.
Here’s the full code, in all it’s glory. Feel free to use how you see fit (I’m releasing this with no restrictions). It’s not very complicated, but I figured it might be useful to someone!
#import <UIKit/UIKit.h>
@interface OMPageControl : UIPageControl {
UIImage* mImageNormal;
UIImage* mImageCurrent;
}
@property (nonatomic, readwrite, retain) UIImage* imageNormal;
@property (nonatomic, readwrite, retain) UIImage* imageCurrent;
@end
#import "OMPageControl.h"
@interface OMPageControl (Private)
- (void) updateDots;
@end
@implementation OMPageControl
@synthesize imageNormal = mImageNormal;
@synthesize imageCurrent = mImageCurrent;
- (void) dealloc
{
[mImageNormal release], mImageNormal = nil;
[mImageCurrent release], mImageCurrent = nil;
[super dealloc];
}
/** override to update dots */
- (void) setCurrentPage:(NSInteger)currentPage
{
[super setCurrentPage:currentPage];
// update dot views
[self updateDots];
}
/** override to update dots */
- (void) updateCurrentPageDisplay
{
[super updateCurrentPageDisplay];
// update dot views
[self updateDots];
}
/** Override setImageNormal */
- (void) setImageNormal:(UIImage*)image
{
[mImageNormal release];
mImageNormal = [image retain];
// update dot views
[self updateDots];
}
/** Override setImageCurrent */
- (void) setImageCurrent:(UIImage*)image
{
[mImageCurrent release];
mImageCurrent = [image retain];
// update dot views
[self updateDots];
}
/** Override to fix when dots are directly clicked */
- (void) endTrackingWithTouch:(UITouch*)touch withEvent:(UIEvent*)event
{
[super endTrackingWithTouch:touch withEvent:event];
[self updateDots];
}
#pragma mark - (Private)
- (void) updateDots
{
if(mImageCurrent || mImageNormal)
{
// Get subviews
NSArray* dotViews = self.subviews;
for(int i = 0; i < dotViews.count; ++i)
{
UIImageView* dot = [dotViews objectAtIndex:i];
// Set image
dot.image = (i == self.currentPage) ? mImageCurrent : mImageNormal;
}
}
}
@end
36 comments
| posted in Code Examples, iPhone