Quickies » Cocoa/Objective-C
Cocoa/Objective-C
Catégories
Titres
Contenu
  1. Afficher / masquer la flèche de la souris
    [NSCursor hide];
    [NSCursor unhide];
    [NSCursor setHiddenUntilMouseMoves:YES];
    

    [Retour en haut]
  2. Afficher la date
    NSString *formattedDate = [[NSDate date] descriptionWithCalendarFormat:@"%Y-%m-%d %H:%M:%S"];
    

    2006-11-15 00:26:11


    [Retour en haut]
  3. Afficher une fenêtre modale en tant que sheet
    - (IBAction)openPrefsSheet:(id)sender {
             [NSApp beginSheet:prefsWindow 
                modalForWindow:mainWindow 
                 modalDelegate:nil
                didEndSelector:nil
                   contextInfo:nil];
    
        [NSApp runModalForWindow:prefsWindow];
        [NSApp endSheet:prefsWindow];
        [prefsWindow orderOut:self];
    }
    
    - (IBAction)closePrefsSheet:(id)sender {
        [NSApp stopModal];
    }
    

    [Retour en haut]
  4. Archivage binaire d'un graphe d'objets

    La classe à archiver doit implémenter le protocole NSCoding

    @interface Cat : NSObject < NSCoding > {
        ...
    }
    
    @end
    

    et ses méthodes :

    @implementation Cat
    
    - (void)encodeWithCoder:(NSCoder *)encoder {
        [encoder encodeObject:name forKey:@"Name"];
        [encoder encodeObject:dob forKey:@"BirthDate"];
    }
    
    - (id)initWithCoder:(NSCoder *)decoder {    
        // returned values are autoreleased
        [self setName: [decoder decodeObjectForKey:@"Name"]];
        [self setDob: [decoder decodeObjectForKey:@"BirthDate"]];
    
        return self;
    }
    
    @end
    

    L'appellant peut alors archiver et désarchiver :

    // archive
    [NSKeyedArchiver archiveRootObject:cw toFile:@"/tmp/cArchive"];
    
    // unarchive
    Cat *cr = [NSKeyedUnarchiver unarchiveObjectWithFile:@"/tmp/cArchive"];
    

    [Retour en haut]
  5. Cocoa regexp matching with NSPredicate
    NSString *s = @"Hello World!";
    NSString *re = @".*l{2}.*";
    NSPredicate *p = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", re];
    
    NSLog(@"Match: %d", [p evaluateWithObject:s]);
    

    [Retour en haut]
  6. Convertir une NSDate en NSCalendarDate
    NSDate *date = [NSDate date];
    NSCalendarDate *calendarDate = [date dateWithCalendarFormat:nil timeZone:[NSTimeZone defaultTimeZone]];
    

    [Retour en haut]
  7. Créer et lever ses propres exceptions

    Créer une classe MyException héritant de NSException, puis :

    @try {
        NSException *e = [MyException exceptionWithName: @"MyError"
                                                 reason: @"I threw this Exception"
                                               userInfo: nil];
        @throw e;
    } @catch (MyException *e) {
        NSLog(@"Exception name   : %@", [e name]);
        NSLog(@"Exception reason : %@", [e reason]);
    }
    

    En Objective-C, la tradition est plutôt au valeurs de retour comme nil, NULL, NO ou aux codes d'erreur.


    [Retour en haut]
  8. Current Application Name
    [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"]
    
    [[NSProcessInfo processInfo] processName]
    

    [Retour en haut]
  9. Default Images
    NSImage *image = [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kAlertNoteIcon)];
    

    [Retour en haut]
  10. Display Image Loading
    $ OBJC_PRINT_IMAGES=YES /Library/XcodeBuilds/Debug/HelloWorld 
    objc[39331]: IMAGES: processing 28 newly-mapped images...
    
    objc[39331]: IMAGES: loading image for /usr/lib/libobjc.A.dylib (supports GC)
    
    objc[39331]: IMAGES: loading image for /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (supports GC)
    
    objc[39331]: IMAGES: loading image for /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (supports GC)
    
    objc[39331]: IMAGES: loading image for /Library/XcodeBuilds/Debug/HelloWorld
    

    [Retour en haut]
  11. Ensure 64-Bit Readiness
    /Developer/Extras/64BitConversion/ConvertCocoa64 MyClass.m
    

    [Retour en haut]
  12. Enumerate CoreData entities
    for (NSEntityDescription *entity in [self managedObjectModel]) {
        NSLog(@"entity %@", entity.name);
    }
    

    [Retour en haut]
  13. Filtrer un tableau avec NSPredicate

    Exemple : supprimer les lignes commençant par "--" :

    -(NSString *)stringWithoutComments:(NSString *)string {
        NSArray *inputLines = [string componentsSeparatedByString:@"\n"];
        NSPredicate *commentsPredicate = [NSPredicate predicateWithFormat: @"SELF beginswith %@", @"--"];
        NSPredicate *notCommentsPredicate = [NSCompoundPredicate notPredicateWithSubpredicate:commentsPredicate];
        NSArray *filteredLines = [inputLines filteredArrayUsingPredicate:notCommentsPredicate];
        return [filteredLines componentsJoinedByString:@"\n"];
    }
    

    [Retour en haut]
  14. Get Computer Network Image
    [NSImage imageNamed:NSImageNameComputer]
    

    [Retour en haut]
  15. Get th Desktop path
    NSString *desktop = [NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    

    [Retour en haut]
  16. Get the app version number
    NSString *currentVersion = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleShortVersionString"];
    

    [Retour en haut]
  17. Info about the current process (os, environment, ...)

    Lots of useful info, thanks to NSProcessInfo.

    NSProcessInfo *pi = [NSProcessInfo processInfo];
    
    NSLog(@"environment SHELL: %@", [[pi environment] objectForKey:@"SHELL"]);
    NSLog(@"globallyUniqueString: %@", [pi globallyUniqueString]);
    NSLog(@"hostName: %@", [pi hostName]);
    NSLog(@"processIdentifier: %d", [pi processIdentifier]);
    NSLog(@"processName: %@", [pi processName]);
    [pi setProcessName:@"MyProcessNewName"];
    NSLog(@"processName: %@", [pi processName]);
    NSLog(@"operatingSystem: %d", [pi operatingSystem]);
    NSLog(@"operatingSystemName: %@", [pi operatingSystemName]);
    NSLog(@"operatingSystemVersionString: %@", [pi operatingSystemVersionString]);
    NSLog(@"processorCount: %d", [pi processorCount]);
    NSLog(@"activeProcessorCount: %d", [pi activeProcessorCount]);
    NSLog(@"physicalMemory: %qu", [pi physicalMemory]);
    NSLog(@"args: %@", [pi arguments]);
    

    Output:

    environment SHELL: /bin/bash
    globallyUniqueString: F68E72F1-257C-4E93-B23D-BA3A0DD15603-47346-0001600092C640D8
    hostName: nst.local
    processIdentifier: 47346
    processName: Untitled
    processName: MyProcessNewName
    operatingSystem: 5
    operatingSystemName: NSMACHOperatingSystem
    operatingSystemVersionString: Version 10.5.4 (Build 9E17)
    processorCount: 2
    activeProcessorCount: 2
    physicalMemory: 2147483648
    args: (
        "/Library/XCodeBuilds/Debug/Untitled"
    )
    

    [Retour en haut]
  18. Itérer sur un tableau

    Pareil qu'en C.

    int i;
    int count;
    
    count = [array count];
    
    for (i = 0; i < count; i++) {
        NSLog(@"%@", [array objectAtIndex:i]);
    }
    

    Avec un énumérateur.

    NSEnumerator *enumerator;
    enumerator = [array objectEnumerator];
    
    NSObject *obj;
    
    while (obj = [enumerator nextObject]) {
        NSLog(@"%@", obj);
    }
    

    [Retour en haut]
  19. Lancer une autre application
    NSWorkspace *ws = [NSWorkspace sharedWorkspace];
    BOOL appDidLaunch = [ws launchApplication:@"BluePhoneElite"];
    

    [Retour en haut]
  20. Lire des données dans un fichier du bundle

    Ici dans le cas d'un tableau.

    NSBundle *bundle;
    NSString *path;
    NSArray *usefulData;
    
    bundle = [NSBundle mainBundle];
    path = [bundle pathForResource:@"userfulData"
                            ofType:@"plist"];
    usefulData = [[NSArray alloc] initWithContentsOfFile:path];
    

    [Retour en haut]
  21. Mesurer le temps d'exécution d'un bout de code
    NSDate *startDate = [NSDate date];
    //...
    NSLog(@"took %f seconds", [[NSDate date] timeIntervalSinceDate:startDate]);
    

    [Retour en haut]
  22. Méthode pour créer un singleton
    + singleton {
        static Singleton *instance = nil;
    
        if (instance == nil) {
            instance = [[self alloc] init];
        }
    
        return instance;
    }
    

    [Retour en haut]
  23. Minimal command-line example
    #import <Foundation/Foundation.h>

    /*
    gcc -g -Wall -framework Foundation -o nslog nslog.m
    */


    int main (void) {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        NSLog(@"hello world");
        [pool release];
        return (0);
    }

    [Retour en haut]
  24. Network hostname and addresses
    NSArray *addresses = [[NSHost currentHost] addresses];
    NSString *hostName = [[NSProcessInfo processInfo] hostName];
    

    [Retour en haut]
  25. Number of dpi of an NSImageRep
    float dpi = ([image pixelsWide] / [image size].width) * 72.0);
    

    [Retour en haut]
  26. Obtenir la liste des applications ouvertes
    NSWorkspace * ws = [NSWorkspace sharedWorkspace];
    NSArray *runningApps = [ws valueForKeyPath:@"launchedApplications.NSApplicationName"];
    

    [Retour en haut]
  27. Ouvrir une URL
    [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:myURLString]];
    

    [Retour en haut]
  28. Pretty debug logs
    NSLog(@"%s:%d", __PRETTY_FUNCTION__, __LINE__);
    
    +[AppDelegate initialize]:23
    

    Thank you Stéphane.

    NSLog(@"-[%@ %s]", isa, SELNAME(_cmd));
    
    -[NSKVONotifying_AppDelegate awakeFromNib]
    

    [Retour en haut]
  29. Print the line number
    NSLog(@"line %d", __LINE__);
    

    [Retour en haut]
  30. Protocole NSTableDataSource

    La source de données d'un NSTableView doit implémenter les méthodes suivantes :

    Retourner le nombre de lignes :

    - (int)numberOfRowsInTableView: (NSTableView *)aTableView
    

    Retourner le contenu d'une cellule :

    - (id)              tableView: (NSTableView *)aTableView
        objectValueForTableColumn: (NSTableColumn *)aTableColumn
                              row: (int)rowIndex
    

    Modifier le contenu d'une cellule (optionnel)

    - (void) tableView: (NSTableView *)aTableView
        setObjectValue: (id)anObject
        forTableColumn: (NSTableColumn *)aTableColumn
                   row: (int)rowIndex
    

    [Retour en haut]
  31. Quitter une autre application
    NSDictionary *errors;
    NSAppleScript *quitBPE;
    
    quitBPE = [[NSAppleScript alloc] initWithSource:@"tell application \"BluePhoneElite\" to quit"];
    [quitBPE executeAndReturnError:&errors];
    [quitBPE release];
    
    if(errors != nil) {
        // manage error
    }
    

    [Retour en haut]
  32. Registering default NSUserDefaults
    + (void)initialize{
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:@"NO", @"disableRulerAntiAliasing",
                                                                               @"YES", @"disableTracksAntiAliasing", nil];
    
        [defaults registerDefaults:appDefaults];
    }
    

    [Retour en haut]
  33. Runtime Version Check
    if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_0) {
      /* On a 10.0.x or earlier system */
    } else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_1) {
      /* On a 10.1 - 10.1.x system */
    } else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_2) {
      /* On a 10.2 - 10.2.x system */
    } else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_3) {
      /* On a 10.3 - 10.3.x system */
    } else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_4) {
      /* On a 10.4 - 10.4.x system */
    } else {
      /* Leopard or later system */
    }
    

    http://developer.apple.com/releasenotes/Cocoa/AppKit.html


    [Retour en haut]
  34. Super Log

    Logs filename, line number, function name and optional arguments.

    #define superLog(format, ...) NSLog( @"File=%s Line=%d Function=%s " format, strrchr("/" __FILE__,'/')+1, __LINE__, __PRETTY_FUNCTION__, ## __VA_ARGS__ )
    

    Example:

    File=MyClass.m Line=16 Function=-[MyClass awakeFromNib]
    

    [Retour en haut]
  35. Trace Objective-C Messages
    $ NSObjCMessageLoggingEnabled=YES /Library/XcodeBuilds/Debug/HelloWorld 
    2009-02-04 10:54:41.728 HelloWorld[39133:10b] Hello, World!
    $ cat /tmp/msgSends-39133 
    + NSRecursiveLock NSObject initialize
    + NSRecursiveLock NSObject new
    + NSRecursiveLock NSObject alloc
    ...
    

    Tracing can be activated selectively in code:

    instrumentObjcMessageSends(YES);
    // messages will be traced here
    instrumentObjcMessageSends(NO);
    

    [Retour en haut]
  36. Traitement des exceptions
    NSMutableArray *array = [NSMutableArray new];
    
    @try {
        [array addObject:nil];
    } @catch (NSException* e) {
        NSLog(@"%@", e);
    } @finally {
        NSLog(@"over");
    }
    

    [Retour en haut]
  37. Utiliser des préférences

    Comment utiliser le système de préférences, ici dans le cas d'un tableau.

    NSUserDefaults *prefs;
    NSMutableArray *records;
    
    // read prefs at opening
    - (void)awakeFromNib {
        prefs = [[NSUserDefaults standardUserDefaults] retain];
    
        if([prefs objectForKey:@"Records"] != nil) {
            records = [[NSMutableArray alloc] initWithArray:[prefs arrayForKey:@"Records"]];
        } else {
            records = [[NSMutableArray alloc] init];
        }
    
    }
    
    // save prefs
    - (void) saveData {
        [prefs setObject:records forKey:@"Records"];
    }
    
    // dealloc
    - (void) dealloc {
        [self saveData]; // just to be sure
    
        [prefs synchronize];
        [prefs release];
        [records release];
    
        [super dealloc];
    }
    

    Ne pas oublier de définir le "bundle identifier name" dans targets / myapp / cmd-i / properties / identifier.


    [Retour en haut]
  38. Utiliser Python.h

    Télécharger un projet XCode de démonstration : CocoaPython.zip.

    #import
    #import

    int main (int argc, const char * argv[]) {
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
        
        /* initialization */
        
        Py_Initialize();
        
        PyObject *sysModule = PyImport_ImportModule("sys");
        PyObject *sysModuleDict = PyModule_GetDict(sysModule);
        PyObject *pathObject = PyDict_GetItemString(sysModuleDict, "path");
        PyObject_CallMethod(pathObject, "insert", "(is)", 0, "../../");
        
        Py_DECREF(sysModule); // borrowed reference
        
        /* import and instantiate Cat */
        
        // from Cat import *
        PyObject *CatModule = PyImport_ImportModule("Cat");
        
        // c = Cat()
        PyObject *Cat = PyDict_GetItemString(PyModule_GetDict(CatModule), "Cat");
        PyObject *cat = PyObject_CallObject(Cat, NULL);
        
        Py_DECREF(CatModule);
        Py_DECREF(Cat);
        
        /* use Cat instance methods */
        
        // c.scream()
        // c.set_name("charly")
        // c.print_family("jack", "cathy", 4)
        
        PyObject_CallMethod(cat,"scream",NULL);
        PyObject_CallMethod(cat,"set_name", "(s)", "charly");
        PyObject_CallMethod(cat,"print_family", "(ssi)", "jack", "cathy", 4);
        
        // c.is_asleep()
        PyObject *is_asleep = PyObject_CallMethod(cat,"is_asleep",NULL);
        BOOL isAsleep = (Py_True == is_asleep);
        Py_DECREF(is_asleep);
        NSLog(@"%d", isAsleep);
        
        // c.name()
        PyObject *name = PyObject_CallMethod(cat,"name",NULL);
        NSString *catName = [NSString stringWithCString: PyString_AsString(name)];
        Py_DECREF(name);
        NSLog(@"%@", catName);
        
        /* termination */
        
        Py_DECREF(cat);
        Py_Finalize();
        
        [pool release];
        return 0;
    }

    [Retour en haut]
  39. Utiliser une API non documentée

    Utiliser une API non documentée

    1. extraire l'API du framework binaire avec l'utilitaire class-dump, exemple :

      class-dump
          /System/Library/Frameworks/InstantMessage.framework/Versions/A/InstantMessage
          > ~/InstantMessage.h
      
    2. ajouter le framework au projet

    3. importer l'API

      #import "InstantMessage.h"
      

    Rien ne garanti que l'API fonctionne toujours dans les futures versions du système.


    [Retour en haut]
  40. Where to put Spotlight cache files
    ~/Library/Caches/Metadata/app.bundle.identifier
    

    [Retour en haut]
Tout afficher - Imprimer - Recherche avancée - RSS
© 2010 Nicolas Seriot