I recently came up against an issue in an iOS app where the development server for the web service I needed to access was using a self-signed SSL certificate.

If you’ve ever come across this scenario before, you’ll know that iOS will not accept the certificate, as it is untrusted – so how do you access the web service?

NSURLConnection provides a couple of delegate APIs to handle these kinds of situations:

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace;
 
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;

In the first method, you’ll need to return YES or NO depending on whether or not your delegate object can authenticate against the different types of protection spaces. In this case, we’re interested in a protection space that uses the authentication method: NSURLAuthenticationMethodServerTrust. So if it’s that kind, return YES, like so:

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
	return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

Secondly, we need to manually tell the URL connection that the certificate is trusted by us, like this:

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
	if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
	{
		if ([challenge.protectionSpace.host isEqualToString:@"myhostname.com"])
		{
			[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
		}
	}
 
	[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

Notice that the above code is checking the authentication challenge for the hostname provided in the authentication. If the hostname is equal to the hostname we are expecting, then we tell the authentication challenge that we’d like to trust the certificate.

Et voila! The URL connection now succeeds when using a self-signed SLL certificate!

It should be noted that this was for a development environment where I had no control over the cert being used or how it was originally signed. In no cases should a production server be using a self-signed untrusted cert.

Whether the web service you’re working with is using HTTP Basic Auth or HTTP Digest Auth, as long as you’re using NSURLConnection, NSURLCredential has you covered.

Apple have made it very easy for us developers. All we have to do is implement a delegate method.

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
	if ([challenge previousFailureCount] < 0)
	{
		[[challenge sender] cancelAuthenticationChallenge:challenge];
		return;
	}
 
	NSURLCredential *credential = [NSURLCredential credentialWithUser:aUsername 
                                                                 password:aPassword 
                                                              persistence:NSURLCredentialPersistenceForSession];
	[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}

And that’s it. NSURLCredential will handle both HTTP Basic and Digest auth for you, including all the ugly base64 encoding and MD5 hashing.

Apple has a couple of weeds taking root in their walled garden recently.

The most recent being the Pokemon fiascos. There are a few “apps” in the App Store that are currently occupying alarmingly high rankings in the top app listings. One of these is “Pokemon Yellow”. “Wow, Pokemon Yellow is in the App Store!” Hold it right there.

It’s a scam, (you knew that, right?) According to the countless 1 Star reviews, the “game” simply opens, displays a picture of one of the newer Pokemon Nintendo DS games (not even Pokemon Yellow) and then promptly closes, leaving the poor sap who just paid 99c feeling a little more than dumb.

So what’s the problem here? The fact that someone is ripping off Mega Giant Nintendo for a quick buck? The fact that the app doesn’t work as advertised? That fact it’s blatantly a scam? These are all big problems, but, for me, they aren’t the problem. Sure people are losing out on their money – but individually it’s only 99c, it probably costs more for a bag of Haribo. Collectively, though, that is a lot of money. The amount of downloads it takes to get that high in the rankings leads to serious money.

However, the real problem is how the hell did this manage to get approved in the first place?! This is precisely the type of thing Apple’s review process is designed to prevent. Yet here we are, with hundreds (if not thousands) of people buying into false promises, having their money taken from them in dishonest ways. This is exactly what Apple tried to get rid of.

As a developer myself, I have had apps rejected in the past. Some of them have been silly reasons, some have been more sensible, but all of them have been in line with their published Guidelines (requires developer login).

Examples include:

  • Having an app rejected because the table cell selection states were persistent, which contradicts the Human Interface Guidelines.
  • Having an app rejected for using a circular, blue ‘plus’ button as an ‘invite friend button’, when its intended use is for adding existing contacts. (Again, with the HIG).
  • Attempting to sell an in-app purchase that used the name “Premier League” in its title. I was told I needed written consent from the copyright holder in order to use its trademarks. Perfectly fair enough.

So how the hell did this Pokemon Yellow get past these insanely picky reviewers?

The app uses Nintendo trademarks, copyrights and imagery for starters. If it was enough for my “Premier League” IAP to be rejected, why isn’t it enough for this one?

Not only that, the app doesn’t work as advertised. Unless, it says “will immediately close after opening” in the description (which, I couldn’t find at all, so maybe I’m missing it?). Again, this on its own should be enough for rejection.

Finally, the app, even if it did work, offers no substantial benefit or use whatsoever, yet another reason, which by itself should result in rejection.

What the hell Apple? This place is meant to be a haven from all this shit.

The only thing I can think of that would lead to this is an inside job. Maybe one of the reviewers wanted a quick buck and could successfully hide his true identity, like a real super villain. Where’s Batman when you need him?

Today I saw HP’s Z1 all-in-one workstation. A number of people on youtube and twitter are taking issue with the fact HP said “The first 27″ all-in-one” but they’re missing the most important part of the claim to give themselves an excuse to bash HP, and bring into light that Apple has a 27″ all-in-one and has done for a long while.

I’m not usually one to rush to HP’s defences but the part they’re missing is “workstation”. HP said “The first 27″ all-in-one workstation“.

Without that simple word, HP would be outright lying. We all know HP have copied Apple in the past, more recently with the HP Envy and, to some extent, they’re doing it again here with regard to the website’s page layout and the way the videos are presented and directed.

But they’re not lying.

The 27″ iMac, while very powerful, is not a workstation. The HP Z1 has the equivalent of a Mac Pro inside a case that is a similar (though, not as elegant or attractive) form factor as the iMac. It also has the ability to be opened very easily and has a mostly tool-less design that allows fast and easy swapping of the components. However, going off on a tangent here, I suspect that HP will require custom, HP branded components that will fit inside the Z1. And they’ll likely charge a lot more than if you bought the same component for a ‘normal’ system.

Anyway.

I’m going to call it, right now, at 23:00 on Sunday 19th February 2012: Right now would be the perfect time for Apple to discontinue the Mac Pro and announce the iMac Pro.

Think about it. Apple have been neglecting the Mac Pro for some time now, with product refreshes being just that – refreshes. Nothing ground-breakingly new. They’ve already discontinued the Xserve.

Removing the Mac Pro from their product lineup would mark the point where Apple leaves the server market (their current server offerings are Mac Pro’s which, ask any ‘server guy’ don’t really fit in those racks), but it’s becoming increasingly clear that the server market isn’t Apple’s target audience, and I don’t think they want to be there anymore.

I’m not going to make any assumptions on how Apple would create a mythical iMac Pro, but seeing the Z1 makes me think it can be done. Apple took existing consumer desktop computers and created an iMac. Why wouldn’t they be able to take existing workstation computers and create something just as attractive? I mean, if I told you before the Macbook Air came about that you could have a 13″ laptop with a Core i7 CPU and have it still be thinner than any other laptop, would you have believed me?

I’m not saying any kind of iMac Pro would be as customisable as the Z1, I mean, this is still Apple. Even the Mac Pro is only ‘so’ customisable. But still, an iMac with a desktop class GPU just screams “desire” to me. Also, there’s the small stumbling block of the price. I can’t imagine it would be very competitively priced. Again, this is Apple.

So there you have it. I respect HP for doing this. They’ll lead the way for more, better all-in-one workstations. Let’s all remember that Apple is almost never the first to enter a market. They see what others do first, wait for them to fail and do it better themselves.

In short, don’t.

Today, the company I work for had two of it’s clients apps rejected because they stated within the app that a portion of the profits made will be donated to charity.

Apple’s App Store Review Guidelines (requires a developer account login) state the two following points:

21. Charities and contributions

21.1
Apps that include the ability to make donations to recognized charitable organizations must be free
21.2
The collection of donations must be done via a web site in Safari or an SMS

The first point prevents any app that makes donations to charity from being a paid app. Even if the application doesn’t provide an actual means of donating as a feature, the act of donating profits from the sale price counts as an ability to make a donation.

Why would Apple do this, you ask? Are Apple evil? Do they hate charity? No, at least, I don’t think so.

There are some people out there who (for whatever reason) don’t like to or just don’t want to donate to charity. Apple is protecting their right to choose to donate to a given charity while also protecting the rights of people who do want to donate (nothing stops them from donating outside of Apple, for instance). Maybe these people don’t agree with the charity’s ideals or maybe they have some other reason. However, just because someone doesn’t want to donate to a charity doesn’t mean they shouldn’t be able to use your app. The choice of using your app and making a donation shouldn’t be mutually exclusive, and I agree with that.

There is also the question of legal liability – however, I can’t think of a case where that would apply without it also applying to Apple paying developers who don’t make charitable donations… so it seems less likely that this is a reason.

The solution, obviously, is to comply with the guidelines and make the app free while providing a website or SMS based donation feature. However, most companies simply remove the copy that says the profits will be donated – which allows them past the app store approval, but puts them in my “you’re a shady company and I don’t like you” book…

January 5th, 2012

iChat Plugins

No Comments, iPhone, by Jasarien.

A quick tip:

If you’re developing an iChat service plugin with IMServicePlugin and friends, don’t forget to run this from the command line after you install the plugin:

killall imagent

It appears that in order to actually get your plugin to load, imagent needs to be restarted, and restarting iChat itself isn’t quite enough. It doesn’t look like you need admin privileges to kill imagent so ‘sudo’ isn’t necessary. This also makes it easy to do as part of your build process – just add it to a script that runs after your build.

If you don’t do this after you install new service plugins, iChat will see your plugin (and list it in its services list) but won’t actually load the plugin itself.

August 20th, 2011

JSCoreTextHyperlinkView

No Comments, iPhone, by Jasarien.

Since I’ve posted the JSTokenField project, I might as well post about my other open source pride and joy, JSCoreTextHyperlinkView.

The project includes an example of how to use the core text view. It’s pretty simple – create the view with a 0 height frame, set the attributes, set its text, and then ask it for it’s size so that the height is just correct. It will calculate based on the constraining width, and any padding that you set.

There is also a Twitter specific subclass that enables @usernames and #hashtags to be linkified.

Settable Attributes:

- textAlignment
- textColor
- linkColor
- highlightedLinkColor
- fontName
- fontSize
- paddingTop
- paddingLeft
- backgroundImage
- bgImageTopStretchCap
- bgImageLeftStretchCap

To use CoreTextHyperlinkView in your apps:

Copy The contents of the AutoHyperlinks folder, and the files JSCoreTextView.h & .m and, if you want Twitter username and hashtag support, copy JSTwitterCoreTextView.h & .m too.
Link against the CoreText framework.

August 20th, 2011

JSTokenField

No Comments, iPhone, by Jasarien.

I’ve just made my latest iOS open source project available:

JSTokenField

JSTokenField

JSTokenField

It does it’s best to mimic the recipient field in Mail on the iPhone. Tokens will size themselves to fit their titles, rearrange themselves to fit on a line, expand the field as more tokens are added. You can select individual tokens to remove them without having to delete all the ones in front of it. And finally it supports adding entires from the address book.

A token has a title and a represented object. The represented object is simply an ‘id’ so it can be anything you like. Generally I use a string to hold the number, email address, etc.

Enjoy!

August 12th, 2011

Git Shortcuts

No Comments, Source Control, by Jasarien.

Whenever I clone a repo from Github I’m used to being able to use

git pull

and

git push

on their own to pull and push from origin and to master respectively.

When I set up my own git repo outside of Github, I wondered why these didn’t work out of the box. Executing those commands would give me an error saying Git doesn’t know which branch to merge with…

It turns out you can set up your preferred remote and local branches to pull and push to and from. Just edit the config file inside the .git/ directory in your local repo.

You may find that if you added a remote repo previous the [remote] section will already be present.

[branch "master"]
        remote = origin
        merge = refs/heads/master
 
[remote "origin"]
        url = url/to/my/gitrepo.git
        fetch = +refs/heads/*:refs/remotes/origin/*

August 12th, 2011

Deleting Remote Tags With Git

No Comments, Source Control, by Jasarien.

I’ve recently started favouring Git instead of SVN for my newer projects and one of the things I do religiously is tagging.

Tagging in Git is very easy and simple, but I ran into a small problem. I created a tag and named it incorrectly and pushed it to my remote repo before I noticed the mistake. So I deleted the tag and created a new one with the correct name and pushed it. Then I did a pull to ensure I was completely synced with the remote repo and it pulled down my old tag that I just deleted…

It turns out that in order to delete a remote tag you need to do the following (replace ‘MyTag’ with the name you gave your tag):

git tag -d MyTag
git push origin :refs/tags/MyTag