Precompiled libogg and libvorbis with 64-bit Support

OggVorbisArm64 I’ve updated my precompiled libogg and libvobis libraries on github. Also included in the updated repositories are the scripts I used to compiled them and instructions how to re-create the compilation process.

You can find the repositories here: libogg, libvorbis. Sample code for an Ogg Vorbis player is at IDZAQAudioPlayer.

Updated versions for Speex and FLAC should follow in the next few days.

If you find these libraries useful, or they saved you time, please consider donating to this site on .


Posted in Precompiled | 5 Comments

Tutorial: Building a Web Browser with UIWebView Revisited (Part 3)

If you completed part two of the tutorial and it seems to be working well you can continue with your current project, or if you prefer you can download the starting point here: GitHub IDZWebBrowser Step4

Outstanding Issues

In this tutorial, you will fix the issues noted at the end of part two, I have reordered them slightly so that dependent issues are dealt with in order:

  • the keyboard displayed is not the URL keyboard so it is awkward to type a URL,
  • the keyboard auto-capitalization mode is inappropriately set,
  • there is no clear button in the address field,
  • if the user omits the http:// the page will not load,
  • the address field can get out of sync with the displayed page,
  • if an error occurs, the user is never informed.

Fixing the Keyboard Configuration

Currently the keyboard type that appears is not really suitable for entering URLs. Much of the punctuation needed requires switching to another keyboard.

The keyboard type that appears when any subclass of UIResponder becomes first responder is controlled by the keyboardType of the object. Possible values are:

  • UIKeyboardTypeDefault
  • UIKeyboardTypeASCIICapable
  • UIKeyboardTypeNumbersAndPunctuation
  • UIKeyboardTypeURL
  • UIKeyboardTypeNumberPad
  • UIKeyboardTypePhonePad
  • UIKeyboardTypeNamePhonePad
  • UIKeyboardTypeEmailAddress

In your case you can make the appropriate keyboard appear by inserting the following line in viewDidLoad in WebBrowserViewController.m.

    address.font = [UIFont systemFontOfSize:17];
    address.keyboardType = UIKeyboardTypeURL;
    [address addTarget:self 
                action:@selector(loadAddress:event:) 
      forControlEvents:UIControlEventEditingDidEndOnExit];
    [navBar addSubview:address];

If you compile and run your code now you should find that the keyboard that appears has ‘/’ and ‘.com’ keys.

There are still problems with the keyboard. When you use backspace to erase the currently displayed URL the keyboard automatically switches to uppercase.

The keyboard auto-capitalization behavior is controlled by the autocapitalizationType property of the first responder. Possible values are:

  • UITextAutocapitalizationTypeNone
  • UITextAutocapitalizationTypeWords
  • UITextAutocapitalizationTypeSentences
  • UITextAutocapitalizationTypeAllCharacters

Add this line of code after the one you just added:

    address.autocapitalizationType = 
                UITextAutocapitalizationTypeNone;

Compile and run your project and confirm that the auto-capitalization behavior is now correct.

Adding a Clear Button to the Address Field

As it stands, if the address field is already displaying an address you have to backspace until you have erased the entire address. This is quite tedious. In Safari when you edit an address an ‘X’ in a grey circle appears on the right hand side of the address field. Touching this icon erases the complete field. Clearly this behavior is more desirable.

The clearButtonMode property of UITextField controls when this “clear button” is displayed. Possible values are:

  • UITextFieldViewModeNever
  • UITextFieldViewModeWhileEditing
  • UITextFieldViewModeUnlessEditing
  • UITextFieldViewModeAlways

In your case, the closest match to the behavior exhibited by Safari is UITextFieldViewModeWhileEditing.

Just after the last line of code you added add:

address.clearButtonMode = 
             UITextFieldViewModeWhileEditing;

Save everything, compile and run your project now. You should see the clear button appear when you start editing a URL.

Correcting User Input

Most modern web browsers allow the user to drop the “http://” prefix on URLs. At this point, if a user omits this prefix in your browser the page will not load. (In fact, an error will be generated but will have pushed off dealing with errors until the end of the tutorial.)

It is fairly simple to fix this. Edit your loadRequestFromString: method as follows.

- (void)loadRequestFromString:(NSString*)urlString
{
    NSURL *url = [NSURL URLWithString:urlString];
    if(!url.scheme)
    {
        NSString* modifiedURLString = [NSString stringWithFormat:@"http://%@", urlString];
        url = [NSURL URLWithString:modifiedURLString];
    }
    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
    [self.webView loadRequest:urlRequest];
}

This solution uses the scheme property of the NSURL class to determine whether the user set a scheme (the part of the URL before the colon). If not it prepends “http://” this will correct entries like www.yahoo.com to http://www.yahoo.com.

Compile and run your your code. Enter “www.yahoo.com” and verify that the correct web page is loaded.

Keeping the Address Field in Sync

If you use the back or forward buttons, or follow a link, the address bar is not in sync with the displayed page. It turns out there is more to solving this problem than meets the eye. So first define a method to update the address bar.

Add the following definition to your class extension:

- (void)updateAddress:(NSURLRequest*)request

The implementation of this method looks like this. Add this to your IDZWebBrowserViewController.m.

- (void)updateAddress:(NSURLRequest*)request
{
    NSURL* url = [request mainDocumentURL];
    NSString* absoluteString = [url absoluteString];
    self.addressField.text = absoluteString;
}

The key point about this code is that instead of requesting the URL from NSRequest you are requesting the mainDocumentURL which is more appropriate to show in the address field.

So this code solves how to display an updated URL in the address field, but not how and when you will be informed.

On the face of it, it should be simple. According to Apple documentation the delegate method webView:shouldStartLoadWithRequest:navigationType: is called before the web view starts loading content.

So the following code modification should ensure that your address field is always in sync with the currently displayed page.

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    [self updateAddress:request];
    return YES;
}

It turns out that this works most of the time, except when you use the “back” and “forward” buttons. It seems that sometimes calling goBack or goForward does not call shouldStartLoadWithRequest.

A reasonable workaround for this problem is to add the following code to your webViewDidFinishLoad:

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    [self updateButtons];
    [self updateTitle:webView];
    [self updateAddress:[webView request]];
}

Reporting Errors to the User

When UIWebView encounters an error it invokes the didFailLoadWithError method of its delegate.

You could handle the error right in the delegate method, but as your programs get bigger having a central error handling routine will be useful (a more general solution to this will be the topic of a future tutorial). So just add the highlighted code to your didFailLoadWithError.

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    [self updateButtons];
    [self informError:error];
}

Since this method is not yet declared you should add a declaration in your class extension.

- (void)informError:(NSError*)error;  

The UIAlertView class provides a convenient way of alerting users of errors.
Add the following code to WebBrowserViewController.m.

    UIAlertView* alertView = [[UIAlertView alloc]
                              initWithTitle:NSLocalizedString(@"Error", @"Title for error alert.")
                              message:localizedDescription delegate:nil
                              cancelButtonTitle:NSLocalizedString(@"OK", @"OK button in error alert.")
                              otherButtonTitles:nil];

The NSError class offers a variety of messages, but for your simple error handler the localizedDescription is the most appropriate. As regards the UIAlertView since there is no other sensible action that the user can do other than acknowledge the error a simple “OK” button will suffice, that is, “retry” or other options probably don’t make sense here.

Once you’ve made this change you can compile and run your project. You should now have a fully functional, albeit at a basic level, web browser.

Conclusion

Over the the three tutorials of this project you have learned a lot. You have used Interface Builder to layout a basic UI that contained a UIToolbar, a UIWebView and a number of UIBarButtonItems. You augmented this UI programmatically with a UINavigationBar, UILabel and a UITextField. To keep your UI in sync with the UIWebVIew your UIViewController subclass implemented the UIWebViewDelegate protocol and, when thing went wrong, you used UIAlertView to inform the user. Not bad for a few hours work!

Download the Source Code

You can download the completed code for this tutorial here:
GitHub IDZWebBrowser Step5

This web site is ad supported. If you would like to see other great tutorials like this one please visit one of our sponsors.


Posted in Tutorial | 2 Comments

Tutorial: Building a Web Browser with UIWebView Revisited (Part 2)

The Address Field and Title Label

The Address Field and Title Label

In part one of this tutorial you created the user interface for a simple web browser, but it could only go to a single hardcoded page.

In this part of the tutorial, you will customize the Navigation Bar to add an Address Field and a Page Title Label. In contrast to the earlier pieces of the UI, these pieces will all be constructed in code since Interface Builder does not support customization of the Navigation Bar.

If you completed the previous tutorial you can simply continue on with your existing code, or if you prefer you can download the starting point code here: GitHub IDZWebBrowser Step3

Add Properties to Refer to the New UI Element

First you will need some properties to refer to the new UI elements. Modify your class extension to include the highlighted code.

@interface IDZWebBrowserViewController () <UIWebViewDelegate>
@property (weak, nonatomic) IBOutlet UIWebView *webView;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *back;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *stop;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *refresh;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *forward;

@property (strong, nonatomic) UILabel *pageTitle;
@property (strong, nonatomic) UITextField *addressField;

- (void)loadRequestFromString:(NSString*)urlString;
- (void)updateButtons;
@end

And copy and paste the following constants above the class extension.

static const CGFloat kNavBarHeight = 52.0f;
static const CGFloat kLabelHeight = 14.0f;
static const CGFloat kMargin = 10.0f;
static const CGFloat kSpacer = 2.0f;
static const CGFloat kLabelFontSize = 12.0f;
static const CGFloat kAddressHeight = 24.0f;

These are dimensions that, by trial and error, gave an acceptable layout for the title label and address field.

Creating the Page Title Label

Add the following code to your viewDidLoad: method to create the page title label.

    /* Create the page title label */
    UINavigationBar *navBar = self.navigationController.navigationBar;
    CGRect labelFrame = CGRectMake(kMargin, kSpacer,
                                   navBar.bounds.size.width - 2*kMargin, kLabelHeight);
    UILabel *label = [[UILabel alloc] initWithFrame:labelFrame];
    label.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    label.backgroundColor = [UIColor clearColor];
    label.font = [UIFont systemFontOfSize:12];
    label.textAlignment = NSTextAlignmentCenter;
    [navBar addSubview:label];
    self.pageTitle = label;

In this code line 2 gives you a short hand for referring to self.navigationController.navigationBar, lines 5-8 create a label with a clear background, 12 point font and centered text, line 10 adds this label to the navigation bar and line 11 assigns it to your pageTitle property so that you can set its text later.

Creating the Address Field

To create the address bar, add this code just after the previous piece:

    /* Create the address bar */
    CGRect addressFrame = CGRectMake(kMargin, kSpacer*2.0 + kLabelHeight,
                                     labelFrame.size.width, kAddressHeight);
    UITextField *address = [[UITextField alloc] initWithFrame:addressFrame];
    address.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    address.borderStyle = UITextBorderStyleRoundedRect;
    address.font = [UIFont systemFontOfSize:17];
    [address addTarget:self
                action:@selector(loadRequestFromAddressField:)
      forControlEvents:UIControlEventEditingDidEndOnExit];
    [navBar addSubview:address];
    self.addressField = address;

This code follows a similar pattern to the previous piece, creating the text field, adding it to the navigation bar and assigning it to a property. Line 9 is, however, worth comment. This line tells the text field to call loadRequestFromAddressField:, a method you are about to implement, when the user finishes editing.

Loading a URL from the Address Bar

Add the declaration of loadRequestFromAddressField: to your class extension.

- (void)loadRequestFromAddressField:(id)addressField;

Then add the following code to your implementation section.

- (void)loadRequestFromAddressField:(id)addressField
{
    NSString *urlString = [addressField text];
    [self loadRequestFromString:urlString];
}

This code retrieves the text from the address field and uses the loadRequestFromString: method that you wrote previous to load the URL.

Updating the Page Title Label

To update the page title label you need to be able (obviously enough) to get the title of the web page. If you look at the documentation for UIWebView you will notice that there is no method to retrieve this information. The solution to this is to use some JavaScript to get the page title as shown here.

- (void)updateTitle:(UIWebView*)aWebView
{
    NSString* pageTitle = [aWebView stringByEvaluatingJavaScriptFromString:@"document.title"];
    self.pageTitle.text = pageTitle;
}

Add this code to your implementation section. Don’t forget to also add a declaration to the class extension as well!

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    [self updateButtons];
    [self updateTitle:webView];
}

This function should be called whenever a page finishes loading, so modify your webViewDidFinishLoad: to do so.

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    [self updateButtons];
    [self updateTitle:webView];
}

Remaining Issues

There are still a number of small issues that need to be taken care of. Tomorrow’s tutorial will address them. They are:

  • the address field can get out of sync with the displayed page,
  • the keyboard displayed is not the URL keyboard so it is awkward to type a URL,
  • the keyboard auto-capitalization mode is inappropriately set,
  • there is no clear button in the address field,
  • if the user omits the http:// the page will not load,
  • if an error occurs, the user is never informed.

Download the Source Code

You can download the completed source code for this part of the tutorial here:
GitHub IDZWebBrowser Step4


Posted in Tutorial | 2 Comments

Tutorial: Building a Web Browser with UIWebView Revisited (Part 1)

By far the most popular tutorial series on this site has been the “Building a Web Browser with UIWebView” series. Over time, however, the tools and code presented have become outdated. Manual memory management has been replaced with Automatic Reference Counting (ARC), which greatly simplifies code. In Interface Builder, storyboards are now the preferred way of creating user interfaces (UIs). So it seemed high time that I revisited the series and updated the tutorials for Xcode 5 and iOS 7.

To get started create a single view project and name it IDZWebBrowser. The main view controller will be called IDZViewController; rename this to IDZWebBrowserViewController using refactoring (see How to Rename a Class using Refactor if you are not sure how to do this). I also recommend renaming the storyboard file to IDZWebBrowser.storyboard. These changes are to allow the web browser component to be more easily integrated into other projects. If this all sounds a little tedious you can download the starting code here: GitHub IDZWebBrowser Step0

Creating the User Interface

To create the user interface, click on the IDZWebBrowser.storyboard file. Add a UIWebView to your view controller by dragging a Web View from the Object Library (ObjectLibraryIcon) onto the view controller, then embed the view controller in a navigation controller by clicking Editor > Embed in > Navigation Controller.

ShowsToolbar Then select the navigation controller and in Attributes Inspector click the Shows Toolbar check box.

Now click on the Web Browser View Controller and drag four bar button items onto the toolbar. In the attributes inspector, working from left to right, set the identifiers of the buttons to Rewind, Stop, Refresh and Fast Forward. The buttons will be bunched on the left hand side of the toolbar. Add Flexible Space Bar Button Items between each pair of buttons. You storyboard should now look like the image below.

Storyboard after adding toolbar buttons.

Now is a good time to save your work!

If you are having difficulty you can compare your work to this version: GitHub IDZWebBrowser Step1

Connecting the User Interface to Code

In this next section you will use Interface Builder to generate code to interact with the user interface. This can save you a lot of typing.

Creating IBOutlets


To get started, with the storyboard file still selected, click on the Assistant Editor () you should now see the view controller implementation file displayed side-by-side with the storyboard. If your screen is small it may be useful to hide your Navigator using the View > Navigators > Hide Navigator menu item, the Toolbar icon or the ⌘0 keyboard shortcut and/or your Utilities using the View > Utilities > Hide Utilities menu item, the toolbar item or the ⌥⌘0 keyboard shortcut.

To create a property in your view controller to access your web view, click drag from the UIWebView on the storyboard to the class extension portion of the IDZWebBrowserViewController.m file as shown below.

Click-drag from the UIView to create a property.

Click-drag from the UIView to create a property.

In the callout that appears when you release the drag enter webView into the name field.

Enter webView in the Name field of the call out.

Repeat this process for the four toolbar buttons, naming them back, stop, refresh and forward respectively.

CompletedOutlets Your code should now look something like this.

Connecting Buttons to Actions

In addition to creating outlets that allow your code to access elements of your UI, it also possible to connect buttons to actions in Interface Builder. You can do this to connect you back, stop, refresh and forward buttons to your UIWebView.

In your storyboard control-drap from the back button on the toolbar to the UIWebView as shown below.

ControlDragFromBackToUIWebView

UIWebViewActionsPopup When you release, choose goBack from the popup that appears.

Repeat this process to connect the stop button to the stopLoading action, the refresh button to the reload action and the forward button to the goForward action.

At this point, you are almost ready to leave Interface Builder and write some code, but before doing so click on the UIWebView and in the Attributes Inspector click the Scales Page to Fit checkbox.

Loading a Web Page

A little bit of code is needed to load a web page into your web browser. Add the highlighted code to the end of IDZWebBrowserViewController class extension.

@interface IDZWebBrowserViewController ()
@property (weak, nonatomic) IBOutlet UIWebView *webView;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *back;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *stop;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *refresh;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *forward;

- (void)loadRequestFromString:(NSString*)urlString;
@end

And near the end of the implementation section add:

- (void)loadRequestFromString:(NSString*)urlString
{
    NSURL *url = [NSURL URLWithString:urlString];
    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
    [self.webView loadRequest:urlRequest];
}

Finally, for testing purposes, add the highlighted line to your viewDidLoad method.

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
    [self loadRequestFromString:@"http://iosdeveloperzone.com"];
}

You should now be able to compile and run your project. If all goes well you should see the homepage of this site displayed. You should also be able to follow links and the back, forward, stop and reload buttons should all work.

If something does not seem to work, update your viewDidLoad method as follows. This code will detect which connections are not correct.

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSAssert([self.webView isKindOfClass:[UIWebView class]], @"You webView outlet is not correctly connected.");
    NSAssert(self.back, @"Your back button outlet is not correctly connected");
    NSAssert(self.stop, @"Your stop button outlet is not correctly connected");
    NSAssert(self.refresh, @"Your refresh button outlet is not correctly connected");
    NSAssert(self.forward, @"Your forward button outlet is not correctly connected");
    NSAssert((self.back.target == self.webView) && (self.back.action = @selector(goBack)), @"Your back button action is not connected to goBack.");
    NSAssert((self.stop.target == self.webView) && (self.stop.action = @selector(stopLoading)), @"Your stop button action is not connected to stopLoading.");
    NSAssert((self.refresh  .target == self.webView) && (self.refresh.action = @selector(reload)), @"Your refresh button action is not connected to reload.");
    NSAssert((self.forward.target == self.webView) && (self.forward.action = @selector(goForward)), @"Your forward button action is not connected to goForward.");
    NSAssert(self.webView.scalesPageToFit, @"You forgot to check 'Scales Page to Fit' for your web view.");
	// Do any additional setup after loading the view, typically from a nib.
    [self loadRequestFromString:@"http://iosdeveloperzone.com"];
}

You can also compare your work to this version: GitHub IDZWebBrowser Step2

Monitoring the UIWebView’s state: Implementing UIWebViewDelegate

The current UI has some problems that can easily be solved with a little more code: all the buttons on the toolbar are enabled all the time and there is no indication to the user that network activity is taking place.

To add a method to update the state of the toolbar buttons, add the following declaration to your class extension at the top of the implementation file.

- (void)updateButtons;

Then add the following code to the implementation section.

- (void)updateButtons
{
    self.forward.enabled = self.webView.canGoForward;
    self.back.enabled = self.webView.canGoBack;
    self.stop.enabled = self.webView.loading;
}

This code uses the UIWebView’s properties to determine which buttons should be enabled. This code needs to be called any time the state of the UIWebView changes. The UIWebViewDelegate protocol allows your view controller to be informed when the web view changes state.

To declare that you view controller implements the protocol, modify the class extension line.

@interface IDZWebBrowserViewController () <UIWebViewDelegate>

Next in the implementation section add the delegate methods.

- (void)webViewDidStartLoad:(UIWebView *)webView
{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    [self updateButtons];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    [self updateButtons];
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    [self updateButtons];
}

These routines ensure that the updateButtons is called at the right times and also they display a network activity indicator in the status bar when the web view is loading.

All the remains is to connect the UIWebView delegate to your view controller. This can be done in Interface Builder, but it is also easily done by adding the highlighted line before the call to loadRequestFromString: in viewDidLoad.

- (void)viewDidLoad
{
    [super viewDidLoad];

    // NSAsserts not shown...

    self.webView.delegate = self;
    [self loadRequestFromString:@"http://iosdeveloperzone.com"];
}

If you compile and run the project now you should see that the toolbar buttons will enable and disable appropriately.

Clearly a web browser that can only visit a single site is of limited use, in part two of the tutorial you will customize the navigation bar to add an address bar and a title label to allow users to enter a URL and to display the title of the web page.

Source Code Download

The complete source code for this tutorial can be downloaded here:
You can also compare your work to this version: GitHub IDZWebBrowser Step3


Posted in Tutorial | 3 Comments

New iOS 7 SDK Features

During the WWDC keynote, Craig Federighi showed a very busy slide with a list of new and/or improved APIs in the iOS SDK. Here’s an alphabetical list:

  • 3D Map View
  • 60-fps Video Capture
  • Add to Reading List
  • AirDrop from Activity Sheet
  • Authenticated Game Center Players
  • Automatic Configuration
  • Background Asset Downloads
  • Barcode Scanning
  • Custom Video Compositors
  • Data Protection By Default
  • Directions API
  • Dynamic Types Size
  • Expanded Bluetooth LE Profile Support
  • Geodesic Polylines
  • Guided Access API
  • iBeacons
  • Improved Map Overlays
  • Inter-app Audio
  • Map Snapshots
  • MFi Game Controllers
  • New Multitsking APIs
  • New Turn-based Game Modes
  • Peer-to-peer Connectivity
  • Push Updates
  • Ranking-style Leaderboards
  • Secure Game Scores
  • Sprite Kit
  • UI Dynamics

Posted in WWDC | Leave a comment

Snippet: Macros for ARC-agnostic Code

In an ideal World, we would all be using ARC now and all our code bases would have been converted to ARC but, if like me, you still have some legacy code you may find yourself needed to make some code work both with and without ARC.

I wrote the following macros to make converting old non-ARC code to ARC-agnostic code. It’s by no means an exhaustive set, but it may save you some time if you find yourself needing to do the same thing.

Update: In the first posting of this code the ARC versions of retain and autorelease were incorrect. User sophtwhere was kind enough to send solutions to the problem.

#if  ! __has_feature(objc_arc)
#define IDZ_RETAIN(_o) [(_o) retain]
#define IDZ_RELEASE(_o) [(_o) release]
#define IDZ_AUTORELEASE(_o) [(_o) autorelease]
#define IDZ_SUPER_DEALLOC [super dealloc]
#define IDZ_BRIDGE_CAST(_type, _identifier) ((_type)(_identifier))
#else
#define IDZ_RETAIN(_o) (_o)
#define IDZ_RELEASE(_o) 
#define IDZ_AUTORELEASE(_o) (_o)
#define IDZ_SUPER_DEALLOC
#define IDZ_BRIDGE_CAST(_type, _identifier) ((__bridge _type)(_identifier))
#endif

Posted in Code Snippets, Objective-C | 4 Comments

Snippet: Finding the Current First Responder

In iOS there is no simple call to retrieve the current first responder (without resorting to private APIs). A google search turns up lots of methods that involving walking the view hierarchy, but I really like this simple, efficient method by Jakob Egger posted as an answer to this question on stack overflow.

#import "UIResponder+FirstResponder.h"

static __weak id currentFirstResponder;

@implementation UIResponder (FirstResponder)

+(id)currentFirstResponder {
    currentFirstResponder = nil;
    [[UIApplication sharedApplication] sendAction:@selector(findFirstResponder:) to:nil from:nil forEvent:nil];
    return currentFirstResponder;
}

-(void)findFirstResponder:(id)sender {
   currentFirstResponder = self;
}

@end

I don’t normally repost code from stack overflow, but the google incantations necessary to find this are non-obvious.


Posted in Code Snippets | Leave a comment

iOS Support Matrix

iOS Versions Supported by Device and Other Goodies.

iOS Versions Supported by Device and Other Goodies.


I had been meaning, for quite some time, to create a spreadsheet or graphic cross-referencing the various iOS devices and the OS version they support. By sheer happenstance, the other day, I discovered the iOS Support Matrix (see www.iosupportmatrix.com). They have created a great info-graphic that summarizes this and a bunch of other information at a glance. The graphic is free to download and available in a variety of sizes and formats.


Posted in Tips | Leave a comment

Precompiled FLAC Library for iOS


Continuing the series of precompiled audio compression libraries, tonight’s library is the Free Lossless Audio Codec. I compiled version 1.2.1 and am making the binaries available on GitHub. As soon as I get a spare moment I will document the process of compiling the library.

Compilation

The library was compiled using Xcode 4.6.1 for the armv7, armv7s and i386 architectures.

Packaging

The pseudo-framework FLAC.framework includes libFLAC.a and its header file. The library libFLAC++.a was omitted.

Testing

The decoder was tested on the iPhone simulator, running iOS 6.1, and on an iPhone 5, running iOS 6.0.1. The tests confirmed successful decoding; performance tests were not done.

The encoder has not been tested as yet.

Download

The pseudo-framework may be obtained from GitHub: IDZPrecompiledFLAC


Posted in Precompiled | 2 Comments

Precompiled Speex Libraries for iOS

Ever since I produced the Ogg and Vorbis libraries, I have been receiving requests to compile other open source media libraries. I’d love to be able to fulfill all such requests but, unfortunately, that just isn’t possible.

Today I am happy to be able to announce the availability of a precompiled version of Speex 1.2rc1 from speex.org.

Compilation

The library was compiled using Xcode 4.6.1 for the armv7, armv7s and i386 architectures.

Packaging

The libspeex.a and libspeexdsp.a along with the header files were combined into a pseudo-framework Speex.framework.

Testing

The decoder was tested on the iPhone simulator, running iOS 6.1, and on an iPhone 5, running iOS 6.0.1. The tests confirmed successful decoding; performance tests were not done.

The encoder has not been tested as yet.

Download

The pseudo-framework may be obtained from GitHub: IDZPrecompiledSpeex


Posted in Uncategorized | 3 Comments