A note to self. Instructions on where to download it and how to embed are in Facebook’s docs. Even though they updated the GitHub project recently (November 23 at the time of writing), they still ship an old version of the JSON framework bundled with it. And since my project already uses a newer version of that framework, the app wouldn’t compile.
Fix:
after adding the SDK to the project, delete the JSON folder from the Facebook SDK;
in FBRequest.m replace the line #import "JSON.h" with #import "SBJson.h";
We’ve finally finished the first version of AllCafe for iPhone — one we can actually show off.
How many times have you walked into a place only to find there are no free seats — or just realised that today you don’t fancy this place after all? It happens to me a lot. And the first thought is: where else can we sit / eat / have a drink nearby?
Our portal AllCafe.ru has a fairly large database of restaurants across Russia. Plus user reviews about them. We made an iPhone app — which, by the way, weighs only about 200 KB. With it you can see nearby venues on a map, or as a list with the approximate distance.
For each venue you can see brief info — address, phone number (which you can of course dial straight from the app), what kind of cuisine it serves, read news about the venue, and — important — read reviews and decide whether to go.
You can also leave a review yourself. Sitting happily (or unhappily) in a restaurant — open the app and add a review.
That’s only what’s in the app right now. The list of planned features is pretty long and there’s plenty of work ahead.
This is, in fact, my first iOS app. Congrats to me.
My Rode Stereo VideoMic couldn’t handle loud gigs and was clipping the sound. On Tuesday I became the proud owner of a great little device, the Zoom H4N.
I won’t bother describing what’s great about it — that’s all over the internet. I’ll just say the recording quality is excellent. And, most importantly, it copes brilliantly with concerts. To put it through its paces I went straight to a show at Orlandina, where the German band WE BUTTER THE BREAD WITH BUTTER were playing yesterday. They play heavy stuff, so the recorder was thrown straight into the deep end of a loud, heavy gig.
In the recorder’s settings there’s a COMP/LIMITER option — as I understand it, that’s a set of presets for recording. I shot a video at the show with audio from the recorder. It’s in two parts. The first I recorded with the LIMIT2 (CONCERT) preset and a manual recording level (level 8 out of 100). I’m not too happy with how that came out. The second part used the LIMIT3 (STUDIO) preset — even at home it makes the sound cleaner and more pleasant. I left the recording level on AUTO. I like the result much better.
Either way, the way the audio came out at a gig like that is a strong sign that the device records very respectably. I think I’ll stick with it.
From the start of the video up to 9:43 it’s LIMIT2 (CONCERT) and recording level 8; from 9:43 to the end it’s LIMIT3 (STUDIO) with auto recording level. Result:
In this approach the app always has a Tab Bar — it’s always visible and you can always switch between tabs. Inside one of the tabs (or in all of them, if you like) there’s a view with a UINavigationController, in which you can move between views via push and pop.
Create two new files of type UIViewController subclass (with the «with XIB for user interface» checkbox). Let’s name them FirstViewController and SecondViewController. These will be the two views displayed in the two tabs.
Our AppDelegate.h in the empty project looks like this:
Now over to AppDelegate.m. Here we need to import the FirstViewController and SecondViewController we just created, and add a @synthesize for the tabs:
Inside didFinishLaunchingWithOptions we put the following:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// create the application window matching the screen size
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// create two UIViewController instances
UIViewController *viewController1, *viewController2;
// initialise the first view with our first controller’s interface
viewController1 = [[UINavigationController alloc] initWithRootViewController:[[FirstViewController alloc] initWithNibName:@"FirstViewController" bundle:nil]];
// initialise the second view with our second controller’s interface
viewController2 = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
// hook our views into the tab bar
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, viewController2, nil];
// make tabBarController the app’s root view controller
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
Now on launch we’ll get a tab bar at the bottom of the screen. Each tab will have its controller. The first controller (viewController1) will contain a UINavigationController, which lets us push and pop views. As an example let’s add another UIViewController subclass (with the «with XIB for user interface» checkbox). Let’s call it MyViewController. So the project now has 3 UIViewControllers:
Since viewController1 (a.k.a. FirstViewController) contains a UINavigationController, let’s add some action to it that takes us to our controller. First, at the top of FirstViewController.m add #import "DetailViewController.h", then add a method:
Add a UITabBarController to the xib, wire it up in Connections Inspector. Create two views in the project — FirstViewController and SecondViewController — and in the UITabBarController inside RootViewController.xib, wire the tabs to those views.
Here’s the start of AppDelegate.m:
#import "AppDelegate.h"
#import "RootViewController.h"
@implementation AppDelegate
@synthesize window = _window;
@synthesize viewController = _viewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// create the window
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// create the main controller
self.viewController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:nil];
// create the UINavigationController
navigationController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
// make UINavigationController the main controller
self.window.rootViewController = navigationController;
[self.window makeKeyAndVisible];
return YES;
}
The general idea: self.window.rootViewController is a UINavigationController. The app has a RootViewController with its own xib. You can leave it empty, but it needs an @property:
When the RootViewController’s view loads, we immediately push our tabBarController. So the first thing the user sees on launch is the tabs and the top bar with a Back button — which you can hide here and show only later somewhere else.
The main upside — inside the views loaded inside the UITabBarController you can navigate the main screen to other views and back, all from code. Video:
The VKontakte iPhone app is built on this principle. My example isn’t implemented perfectly — could be polished — but it works. Download the example.
Will come in handy in the future — and going through it again helped me lock it in.
Well, the new macOS with iCloud support is out, and iCloud itself has come out of beta.
So, after installing the updates, immediately after the system reboots you’re prompted to sign in to iCloud with your Apple ID. After signing in, you’re asked to tick the services you want to use.
I decided not to tick Mail — I don’t really see the point. I already use a mail client on both my computers and my mobile devices. Mail is over IMAP, so it all syncs anyway. Contacts is a relatively useful thing. I personally don’t need it yet, but after turning it on, all the contacts from the address book on the phone showed up on both my Macs.
The most useful thing, in my view, is calendar sync. I really didn’t want to bother syncing through Google and keeping a calendar there, especially since the only Google service I use regularly is YouTube. It’s very nice that everything now works and syncs out of the box. For example, I added the dates of film premieres I want to watch. They appeared in the calendars on all my devices and Macs. There is one annoying detail though — I added these events on one of the Macs. After syncing, those events were duplicated on it. But that’s probably an early-days glitch and an Apple oversight. After adding a new event it appeared everywhere just once.
Documents are still unclear. The desktop iWork apps only offer to publish files to iWork.com, which is still in public beta.
The «Find My Mac» feature lets you later track on iCloud.com where it is. As I understand it, this is for the case when it gets stolen, or you left it somewhere and don’t remember where.
iCloud.com is now also open to everyone — styled in the spirit of iOS, offering 5 tools (or rather 4).
Mail should be a web interface similar to the standard Mail app. Contacts and Calendar look exactly like the standard Mac OS apps.
The Find My iPhone feature looks pretty entertaining — despite the name, it shows not only phones, but also Macs that have «Find My Mac» enabled.
You can send a message and a sound alert to the devices. It arrives instantly, and on top of that you get an email saying that such-and-such message was sent and delivered to the device. You can remotely lock the device or wipe it. For iPhone there’s even a toggle — when found, immediately email me. So the location is monitored somehow, without your involvement, it seems.
The iWork section currently contains only ads inviting you to install the iWork apps on your iOS devices. Apparently those already work with iCloud. None of the iWork apps are installed on my iOS devices — no need.
On an iOS device, in the iCloud settings you can turn on Photo Stream. From the moment you turn it on, all new photos start being uploaded to iCloud and become available on your other devices. Only new ones are uploaded — i.e. the ones taken after enabling the feature. Anything taken before — doesn’t go anywhere. Here’s how they look in iPhoto on the Mac:
You also need to enable Photo Stream in iPhoto. As soon as I took a photo on the iPhone (and opened the photos list), the photo started flowing into iCloud. It appeared in iPhoto automatically without any action from me.
The most puzzling feature for me so far is «Back to My Mac». Judging by the icon, it’s a way to connect to your Mac via remote desktop, but I haven’t found out how to actually do it. I really want to use this feature to connect to my home computer from work, since TeamViewer is getting on my nerves with its glitches and intrusive messages, opening its website and offering me a paid version. Update: a description of how it works.
I didn’t enable Bookmarks in iCloud, since I barely use Safari. The bookmarks of the Opera I use are already synced through their built-in Opera Link service.
The cloud also stores backups of my iPhone, which have already eaten up almost half of the available free space. A useful thing if your computer suddenly dies. But somehow that doesn’t feel like a tragedy to me. The other syncs are also a kind of backup.
What I was looking forward to most was iTunes Match, but it won’t come for a while, and, alas, will only work in the US for now — like all the cloud music services, be it Amazon or Google. Sad — almost makes you want to write your own.
Tried a bunch of different mic settings at a show. The best combination — the -10 dB switch on, with the foam windshield fitted (turns out it doesn’t just protect from wind, it also helps against overload). Sadly, I still couldn’t get perfect sound, even though the gig was pretty loud. But it’s a lot better than the first attempts. The drums still get clipped in places.
I also lowered the recording level on the camera itself in the settings. Around 50% gives better sound. Going lower just makes the final video quieter without removing the clipping. Here’s the result:
I’ll keep filming at other gigs and figure out how to better isolate the mic acoustically so everything records cleanly.
Decided to get an external microphone for my Canon 60D DSLR, to record video at concerts with decent sound. After a bit of googling and brainstorming with @theproof, the focus settled on RODE products.
The mic is for a DSLR, so it has to have a hot-shoe mount to clip onto the camera. We figured: if we’re buying a mic, get one from a company that specialises in them, which RODE seems to be. The various Nikon/Sony mics were dismissed straight away. RODE has a fairly broad range. Within budget, the candidates were the condenser RODE VideoMIC and the RODE Stereo VideoMic. From the names it’s clear the first one records mono (and is also indecently long). The second one records stereo, which I like a lot more.
The mic needs its own power from a 9-volt battery, which is more of a plus than a minus — it won’t drain the camera battery. On a 9V it can run for about 60 hours, which is fine unless you’re shooting around the clock.
It connects to the camera via a 3.5 mm jack. It has three switches (it took me a moment to realise they’re switches — at first I thought they were buttons):
The left switch lets you cut the recording level by 10 dB, which is what you want when recording something loud — say, a concert (which is exactly what I’m planning to do). The middle switch is on/off. The right one, when on, reduces high-frequency noise — for example, traffic noise.
It also comes with a fluffy windshield for outdoor use in windy weather.
As usual, I didn’t read the manual or any tips. Just stuck it on the camera and went off to a show. Shot two videos. The audio came out clipped in places — I didn’t flick the -10 dB switch and I didn’t lower the recording level on the camera (recommended is 75%). For the record — it was a gig by two Japanese artists, Tezya and ASAKI. The internet calls it Future Glam Rock — for teenage girls, basically. It was in the small hall at Orlandina.
Resulting video:
Tomorrow I’ll try recording sound at the Smyslovye Gallyutsinatsii show with proper settings.