Monthly Archives: January 2015

Using Auto Layout to add a Comments Section to your iOS 8 App

 
Below there is a complete series of 4 screencasts (38 minutes total) to show how to add a comments section to your app.
It uses Auto Layout, the cell height is calculated automatically, it runs on iPhone and iPad, and it moves the transparent comments section automatically when the onscreen keyboard is shown.

Comments Section

The final result of our comments section…

 

Please note that iOS 8 is required for this tutorial.

The tutorial is divided into 4 screencasts:

1) Basic Setup (18 minutes)
2) Automatic Cell Height Calculation (7 minutes)
3) Handle the onscreen Keyboard (8 minutes)
4) A little bit of Polishing (5 minutes)

If there are any questions, simply leave a comment in the comments section of the blog.

Programmatically query specific DNS servers on iOS

 
DNS servers handle the mapping of hostnames to IP addresses. This happens under the hood automatically, unless you want to access some non-public resources that are managed by a non-public DNS server.

In my use case this was needed during the early phase of the development of an iOS app. So all team members had access to test resources without the need to change local network settings.

JetBrains has with CLion a new C/C++ IDE in development, publicly available through their Early Access Program. So the small routines were a good opportunity for me to get a first impression of their new tool. Jetbrains would not be themselves without offering comfortable editing and refactoring features – refactoring of C code, nice!

So here is a screencast of creating the small routines in CLion and integrating them into an iOS app in Xcode.

The header file:


#import <Foundation/Foundation.h>

@interface ResolveUtil : NSObject

+ (NSString *)resolveHost:(NSString *)host usingDNSServer:(NSString *)dnsServer;


@end


The implementation file:


#include <resolv.h>
#include <arpa/inet.h>
#include <string.h>

#import "ResolveUtil.h"


void setup_dns_server(res_state res, const char *dns_server);
void query_ip(res_state res, const char *host, char ip[]);



@implementation ResolveUtil



+ (NSString *)resolveHost:(NSString *)host usingDNSServer:(NSString *)dnsServer
{
    
    struct __res_state res;
    char ip[16];
    memset(ip, '\0', sizeof(ip));
    
    setup_dns_server(&res, [dnsServer cStringUsingEncoding:NSASCIIStringEncoding]);
    
    query_ip(&res, [host cStringUsingEncoding:NSUTF8StringEncoding], ip);

    return [[NSString alloc] initWithCString:ip encoding:NSASCIIStringEncoding];
    
}

void query_ip(res_state res, const char *host, char ip[])
{
    u_char answer[NS_PACKETSZ];
    int len = res_nquery(res, host, ns_c_in, ns_t_a, answer, sizeof(answer));
    
    ns_msg handle;
    ns_initparse(answer, len, &handle);
    
    
    if(ns_msg_count(handle, ns_s_an) > 0) {
        ns_rr rr;
        if(ns_parserr(&handle, ns_s_an, 0, &rr) == 0) {
            strcpy(ip, inet_ntoa(*(struct in_addr *)ns_rr_rdata(rr)));
        }
    }
}

void setup_dns_server(res_state res, const char *dns_server)
{
    res_ninit(res);
    struct in_addr addr;
    inet_aton(dns_server, &addr);
    
    res->nsaddr_list[0].sin_addr = addr;
    res->nsaddr_list[0].sin_family = AF_INET;
    res->nsaddr_list[0].sin_port = htons(NS_DEFAULTPORT);
    res->nscount = 1;
}

@end

Developing a HTTP Live Streaming App for iOS

 

HTTP Live Streaming (HLS) allows you to send audio and video without special server software to iOS-based devices. It supports multiple streams at different bit rates allowing the client to choose the one that fits the current bandwith the best.

A very simple video player app for iOS using HTTP live streaming can be created in a few minutes, see the following screencast.

The header file:


#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h> 

@interface ViewController : UIViewController

@property (nonatomic,strong) MPMoviePlayerController *player;

@end

The implementation file:


#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    NSURL *stream = [NSURL URLWithString:@"http://www.software7.com/wp-content/uploads/2015/01/videoPlayer/prog_index.m3u8"];
    self.player = [[MPMoviePlayerController alloc] initWithContentURL:stream];
    
    UIView *playerView = self.player.view;
    
    [playerView setTranslatesAutoresizingMaskIntoConstraints:NO];
    
    [self.view addSubview:playerView];
    
    [self.view addConstraints:[NSLayoutConstraint
                               constraintsWithVisualFormat:@"H:|-0-[playerView]-0-|"
                               options:NSLayoutFormatDirectionLeadingToTrailing
                               metrics:nil
                               views:NSDictionaryOfVariableBindings(playerView)]];
    
    [self.view addConstraints:[NSLayoutConstraint
                               constraintsWithVisualFormat:@"V:|-0-[playerView]-0-|"
                               options:NSLayoutFormatDirectionLeadingToTrailing
                               metrics:nil
                               views:NSDictionaryOfVariableBindings(playerView)]];
    [self.player play];
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end