Archive

Posts Tagged ‘XCode’

Gérez vos dépendances Objective-C avec CocoaPods

October 22nd, 2012 No comments

La popularité du langage Objective-C est en constante augmentation ces dernières années. Les succès de l’iPhone et de l’iPad en sont à coup sûr une raison évidente. L’Objective-C, cependant, est utilisé depuis bien plus longtemps dans le développement des logiciels Apple. Le langage en lui-même a été inventé en 1983 comme indiqué sur sa page Wikipedia. Apple prend d’ailleurs un soin particulier à faire évoluer son langage en y apportant de nouveaux raffinements chaque année (Spécification Objective-C 2.0, …).

Bien qu’Apple propose une tool chain à la pointe basée sur LLVM et Clang, il faut se rendre à l’évidence: la gestion des dépendances en Objective-C reste un domaine assez peu exploré, et laisse un petit goût amer lorsqu’on a goûté à d’autres langages accompagnés de leur gestionnaires de dépendances. Je pense ici à JavaScript avec Node.JS et NPM, Ruby et ses Gem, ou bien encore notre bon vieux Java et autres languages de la JVM qui fournissent eux aussi une multitude d’outils répondant à ce besoin.

Il semble que les langages des générations C / C++ et Objective-C aient plus de mal à fournir des outils de ce type. L’intégration de librairies et frameworks peut d’ailleurs rapidement donner des maux de têtes aux développeurs, ce qui n’est pas acceptable pour un langage / écosystème de développement qui se veut moderne.

Concernant l’Objective-C, la réponse à l’absence de gestionnaire de dépendance est venue de la communauté à travers la création d’un outil appelé: CocoaPods. Cet outil est basé sur le partage de configurations également nommées Spec. Elles ont pour rôle de décrire le contenu d’une dépendance. L’outil, développé en Ruby, est visiblement assez inspiré de l’éco-système qui existe autour de ce langage.

Installation & Utilisation

Pour installer CocoaPods, vous devez exécuter les commandes suivantes:

$ [sudo] gem install cocoapods
$ pod setup

Un des points très intéressant de cet outil est sa simplicité d’utilisation : il suffit en effet de créer un fichier “Podfile” à la racine de son projet XCode listant les dépendances requises et de lancer la commande:

pod install

pour que l’outil aille télécharger tous les fichiers sources nécessaires sur internet et vous configure un workspace XCode en bonne et due forme sans effort supplémentaire de votre part. Pour ouvrir le workspace XCode configuré avec toutes ses dépendances, il suffit d’exécuter ensuite la commande :

open my-project.xcworkspace

Les pré-requis à l’utilisation de CocoaPods se résument à installer Ruby 1.9 sur sa machine (si ce n’est déjà fait).

Note : Si vous avez exécuté l’installation avec une version de Ruby 1.8, je vous conseille de nettoyer votre dossier .gem dans votre dossier home, et de recommencer l’installation pour éviter tout problème de compatibilité.

Configuration

L’outil est utilisable aussi bien pour des projets iOS que pour des projet OS X. Pour cela, il suffit de spécifier la cible en début de fichier comme indiqué dans l’exemple ci-dessous :

platform :ios

pod 'JSONKit', '1.5pre'
pod 'LibComponentLogging-Core', '1.2.2'
pod 'LibComponentLogging-NSLog', '1.0.4'
pod 'Reachability', '3.0.0'
pod 'RestKit', '0.10.1'

Contrairement à ce que laisse penser l’exemple précédent, différents opérateurs de comparaison permettent d’affiner les versions des librairies utilisées. Il est possible de créer des configurations plus complexes si votre projet le requiert en allant visiter la documentation du projet. Vous pouvez, entre autre chose, créer plusieurs target correspondant, par exemple, à des targets de test ou de debug de vos applications.

Spécifications

Cerise sur le gâteau, le système de contribution d’une dépendance est très simple, puisque vous pouvez, vous-même, constituer une spécification de dépendances et la soumettre via un Pull Request sur le repository Github CocoaPods/Specs. Ce repository contient l’ensemble des spécifications de dépendances utilisables avec CocoaPods. La lecture de différents fichiers Spec, en plus de la lecture du wiki du projet, permet de comprendre très rapidement le format.

Exemple de spécification pour la librairie Cordova 2.1.0 (PhoneGap) :

Pod::Spec.new do |s|
s.name = "Cordova"
s.version = "2.1.0"
s.summary = "Apache Cordova is a platform for building native mobile applications using HTML, CSS and JavaScript."
s.homepage = "http://incubator.apache.org/cordova/"
s.author = "Original developed by Nitobi (acquire by Adobe) and all other PhoneGap and Cordova Contributors"

s.license = 'Apache License, Version 2.0'

s.source = { :git => "http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios.git", :tag => "2.1.0" }
# s.source = { :git => "https://github.com/apache/incubator-cordova-ios.git", :tag => "2.1.0" }
s.source_files = 'CordovaLib/Classes/*.{h,m}'
s.resources = 'CordovaLib/javascript/*.js', 'CordovaLib/VERSION'

s.platform = :ios, '4.3'
s.requires_arc = true

# TODO: Missing AddressBookUI here, but CocoaPods generates incorrect OTHER_LDFLAGS in Pods/Pods.xcconfig. Will analyse this soon..
# OTHER_LDFLAGS = -ObjC UI -framework AVFoundation < - incorrect UI argument here!

s.frameworks = 'AddressBook', 'AudioToolbox', 'AVFoundation', 'CoreLocation', 'MediaPlayer', 'QuartzCore', 'SystemConfiguration', 'MobileCoreServices', 'CoreMedia', 'UIKit'

# Note: This is not the same like the original JSONKit. Cordova developers decide to integrate
# *a changed copy* (with prefixed class and method names) of it instead of using CocoaPods. :S
# But they missed to translate it like the main project to use ARC, yet.
s.subspec 'JSON' do |json|
json.source_files = 'CordovaLib/Classes/JSON/*.{h,m}'
json.platform = :ios, '4.3'
json.requires_arc = false
# TODO requires_arc does not work for subproject, so set compiler flag by hand until CocoaPods 0.15(?) will support this.
json.compiler_flags = '-fno-objc-arc'
end

end

Moteur de recherche

Bien entendu, il ne serait pas possible de tirer toute la quintessence d’un tel outil sans un moteur de recherche de dépendances associé, c’est ce que propose le site CocoaPods.org.

Les fans de la ligne de commande pourront bien entendu lister les dépendances disponibles via la commande :

pod list

ou bien encore trouver la liste des autres commandes disponibles via l’aide :

pod help

Conclusion

Doucement mais sûrement, un éco-système composé d’outils modernes d’aide au développement s’est formé autour d’Objective-C, et CocoaPods en est un rouages important. Parmi ces nouveaux outils, nous pouvons en citer quelques uns: :

  • ios-boilerplate.com est un kickstarter pour démarrer une application iOS.  Ce template permet de gagner un temps précieux au bootstrap du projet, et fait inévitablement penser au désormais célèbre html5-boilerplate.
  • cocoacontrol.com est un site web référençant nombre de composants utilisables dans vos projet iOS.
  • iosframeworks.com est un catalogue référençant classes et frameworks utiles pour vos projets.
Categories: iOS, Mobilité Tags: , ,

Customisez Xcode avec un thème inspiré de Railscasts !

August 11th, 2012 No comments

J’ai découvert, il y a quelques mois, le plaisir de travailler avec un thème sombre dans mes différents IDEs, et j’avoue avoir du mal à revenir en arrière. Le thème Railscasts, bien connu des développeurs, est décliné sur de nombreux environnements de développement en allant de VIM à IntelliJ IDEA, mais il manque à l’appel sur Xcode.

N’étant pas fan du thème proposé par défaut dans Xcode, je vous propose à travers ce billet de blog de découvrir un thème personnalisé inspiré du fameux thème Railscasts. Celui-ci à la particularité d’utiliser uniquement des tons sobres, ainsi qu’un nombre réduit de variations de couleurs.

Travaillant au quotidien depuis de nombreux mois avec cette base de thème que ce soit sur Xcode ou IntelliJ IDEA, je trouve qu’elle a pour effet de diminuer la fatigue visuelle, et d’améliorer la concentration. 

Installation

Le thème peut être téléchargé depuis la home du thème ou bien depuis Github. Pour cela, il suffit de cloner le repository suivant: https://github.com/akinsella/xcode-railscasts-theme, et de copier le fichier RailsCast_Inspired.dvtcolortheme dans le dossier suivant de votre mac : ~/Library/Developer/Xcode/UserData/FontAndColorThemes.

Une fois le fichier copié, il vous suffit de sélectionner le thème RailsCast_Inspired dans les préférences (Cmd+,) de l’application Xcode.

Screenshots

Vous trouverez ci-dessous quelques screenshots du résultat dans Xcode:

Inspiration

Ce thème a été développé sur la base d’un thème Xcode proposé par Simon Wallner. Vous pouvez le retrouver sur son repository GitHub: https://github.com/SimonWallner/RailsCast-Xcode-Theme. Ce thème est assez proche des couleurs habituelles du thème Railscasts original.

Sachez cependant qu’il existe d’autres variantes ici ou . Libre à vous de trouver chaussure à votre pied !

Questions et remarques

N’hésitez pas à laisser vos commentaires ainsi que vos retours et remarques !

Un thème complet basé sur ces même couleurs existe également pour IntelliJ IDEA. Si vous êtes intéressés, indiquez-le dans les commentaires afin de voir s’il est utile de le proposer dans un futur article !

Categories: iOS, Mobilité, Outils Tags: , ,

Code source de l’application Clock pour iPhone proposé dans un tutoriel OVH

June 10th, 2012 No comments

Il y a trois mois, OVH proposait sur son site un tutoriel aidant à développer sa première application iPhone. Le tutoriel en question avait pour objectif le développement d’une application permettant d’afficher l’heure au centre de l’écran sur un fond noir. Rien d’extraordinaire de premier abord, mais la complexité de prise en main de l’IDE d’Apple (XCode) donne à ce tutoriel son intérêt puisqu’il permet de démarrer en douceur en se familiarisant avec différentes de ses fonctionnalités.

Malheureusement, le code source du tutoriel n’est pas fourni, je vous propose donc de le retrouver sur GitHub, et de le consulter tout au long de la lecture du tutoriel.

L’url du repo GitHub: https://github.com/akinsella/clock

L’url du tutoriel sur le site d’OVH: http://www.ovh.com/fr/all/a494.creer_sa_premiere_application_iphone

  • Le fichier ‘ViewController.h’
//
//  ViewController.h
//  Clock
//
//  Created by Alexis Kinsella on 09/06/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import <uikit /UIKit.h>

@interface ViewController : UIViewController {
    UILabel *hoursAndMinutesLabel;
    UILabel *secondsLabel;
}

@property (nonatomic, retain) IBOutlet UILabel *hoursAndMinutesLabel;
@property (nonatomic, retain) IBOutlet UILabel *secondsLabel;

@property (nonatomic, retain) NSDateFormatter *dateFormatter;
@property (nonatomic, retain) NSTimer *walkTimer;



- (void)updateClock;
   
@end
  • Le fichier ‘ViewController.m’
//
//  ViewController.m
//  Clock
//
//  Created by Alexis Kinsella on 09/06/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "ViewController.h"

@implementation ViewController

@synthesize hoursAndMinutesLabel;
@synthesize secondsLabel;
@synthesize walkTimer;
@synthesize dateFormatter;

-(void)updateClock {
    NSDate *currentDate = [[NSDate alloc] init];
   
    [self.dateFormatter setDateFormat:@"hh:mm"];
    self.hoursAndMinutesLabel.text = [self.dateFormatter stringFromDate:currentDate];
    [self.dateFormatter setDateFormat:@"ss"];
    self.secondsLabel.text = [self.dateFormatter stringFromDate:currentDate];
   
    // ARC forbids explicits release  
    // [currentDate release];
}

- (void) viewWillAppear:(BOOL)animated {
    NSTimer *timer = [NSTimer timerWithTimeInterval:1.0
                                             target:self
                                           selector:@selector(updateClock)
                                           userInfo:nil repeats:YES];
    [self setWalkTimer: timer];
   
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
   
    [self updateClock];
   
    [super viewWillAppear:animated];
}

- (void) viewDidDisappear:(BOOL)animated {
    [[self walkTimer] invalidate];
    [self setWalkTimer:nil];
}


- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    NSDateFormatter *df = [[NSDateFormatter alloc] init];
   
    [self setDateFormatter: df];
   
    // [dateFormatter release];
   
    [self.dateFormatter setLocale:[NSLocale autoupdatingCurrentLocale]];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
   
    self.dateFormatter = nil;

    // Release any retained subviews of the main view.    
    self.hoursAndMinutesLabel = nil;
    self.secondsLabel = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

@end
  • Le fichier ‘AppDelegate.m’
//
//  AppDelegate.m
//  Clock
//
//  Created by Alexis Kinsella on 09/06/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "AppDelegate.h"

#import "ViewController.h"

@implementation AppDelegate

@synthesize window = _window;
@synthesize viewController = _viewController;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end

Categories: iOS Tags: , , , , ,