VisuaBlog

Aller au contenu | Aller au menu | Aller à la recherche

dimanche, décembre 30 2007

Iphone : VSDownloadManager, gestion des codes des réponses HTTP

NSURLConnection ne permet pas par défaut de gérer les codes retours des requêtes HTTP. Lorsqu'un 404 Not found se présente il faut le gérer à la main.

Cette version 1.1 intègre la gestion des erreurs HTTP.

samedi, décembre 29 2007

iPhone : Télécharger des fichiers avec NSURLConnection (asynchrone)

Voici un composant qui permet de télécharger des fichiers de manières asynchrone. L'avantage de cette méthode est, hormis une gestion plus précise des événements de téléchargement, de libérer du temps/machine pour faire autre chose pendant la session de téléchargement. Typiquement, l'ajout d'un progressView à ce composant est assez facile.

VSDownloadManager utilise NSURLConnection en mode asynchrone (et non NSURLDownload qui n'est pas implémenté sur l'iPhone).

Téléchargement des sources !

Exemple d'utilisation de VSDownloadManager

#import "VSDownloadManager.h"

....

....

- (void) downloadManagerDemo {

VSDownloadManager *downloadManager = [VSDownloadManager getInstance];

// set the delegate that will receive the "

[downloadManager setDelegate:self];

// Empty the current queue

[downloadManager clearItems];

// Adding an element to download

VSDownloadManagerItem *dwlItem = [[VSDownloadManagerItem alloc] initWithURL:@"http://blog.visuaweb.com/public/Images/springboard.jpeg" AndFile:@"/var/root/springboard.jpeg" AndText:nil];

[downloadManager addItem:dwlItem];

[dwlItem release];

// Addning an element to download

VSDownloadManagerItem *dwlItem = [[VSDownloadManagerItem alloc] initWithURL:@"http://blog.visuaweb.com/public/Files/snap_joe.jpg" AndFile:@"/var/root/joe.jpeg" AndText:nil];

[downloadManager addItem:dwlItem];

[dwlItem release];

// Start the download session

[downloadManager start];

}

- (void) VSDownloadManagerDidFinishedDownloadSession:(VSDownloadManager *) sender {

NSLog(@"Download session finiched!");

VSDownloadManager.h

//

//  VSDownloadManager.h

//

//  Created by Jeremie Engel on 28/12/07.

//  Copyright 2007 VISUAWEB - http://blog.visuaweb.com. All rights reserved.

//

#import <CoreFoundation/CoreFoundation.h>

#import <Foundation/Foundation.h>

@interface VSDownloadManagerItem : NSObject {

NSString*url;

NSString*filename;

NSString*text;

}

- (id) initWithURL:(NSString*) inURL AndFile:(NSString *) inFilename AndText:(NSString *) inText;

- (NSString *) url;

- (NSString *) filename;

- (NSString *) text;

@end

@interface VSDownloadManager : NSObject {

NSMutableArray*items;

VSDownloadManagerItem * currentItem;

iddelegate;

NSURLConnection*urlConnection;

NSMutableData*receivedData;

intstate;

}

+ (void) initialize;

+ (id) getInstance;

+ (id) allocWithZone:(NSZone *)zone;

- (id) init;

- (void) addItem:(VSDownloadManagerItem *) inItem ;

- (void) clearItems ;

- (void) setDelegate:(id) inDelegate ;

- (void) start ;

@end

VSDownloadManager.m

//

//  VSDownloadManager.m

//

//  Created by Jeremie Engel on 28/12/07.

//  Copyright 2007 VISUAWEB - http://blog.visuaweb.com. All rights reserved.

//

#import "VSLog.h"

#import "VSDownloadManager.h"

@implementation VSDownloadManagerItem

- (id) initWithURL:(NSString*) inURL AndFile:(NSString *) inFilename AndText:(NSString *) inText {

if ((self=[super init])) {

[inURL retain];

url = inURL;

[inFilename retain];

filename = inFilename;

if (inText) {

[inText retain] ;

text = inText;

}

return self;

}

return nil;

}

- (NSString*) url { return url; }

- (NSString*) filename { return filename; }

- (NSString*) text { return text; }

- (NSString *) description {

return url;

}

@end

/*****************************************************************************/

static VSDownloadManager  *defaultVSDownloadManager = nil;

@implementation VSDownloadManager

+ (void) initialize { }

+ (id) getInstance {

    @synchronized(self) {

        if (defaultVSDownloadManager == nil) {

            [[self alloc] init]; // assignment not done here

        }

    }

    returndefaultVSDownloadManager;

}

+ (id)allocWithZone:(NSZone *)zone

{

    @synchronized(self) {

        if (defaultVSDownloadManager == nil) {

            defaultVSDownloadManager = [super allocWithZone:zone];

            returndefaultVSDownloadManager// assignment and return on first allocation

        }

    }

    return nil; //on subsequent allocation attempts return nil

}

- (id) init {

NSLog(@"VSDownloadManager initialize");

if ((self=[super init])) {

items = [[NSMutableArray alloc] init];

//receivedData = [[NSMutableData data] retain];

}

returnself;

}

- (void) setDelegate:(id) inDelegate {

if (delegate) [delegate release];

[inDelegate retain];

delegate = inDelegate;

}

- (void) addItem:(VSDownloadManagerItem *) inItem {

if (![items containsObject:inItem]) [items addObject:inItem];

}

- (void) clearItems {

[items removeAllObjects];

}

- (void) start {

NSLog(@"Starting download");

int i;

for (i=0; i<[items count]; i++) {

state = 1;

receivedData = [[NSMutableData alloc] initWithLength: 0];

currentItem = [items objectAtIndex:i];

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[currentItem url]] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:5];

urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

while(state == 1) {

[[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.1f] ];

}

}

if (delegate && [delegate respondsToSelector:@selector(VSDownloadManagerDidFinishedDownloadSession:)]) {

[delegate performSelector:@selector(VSDownloadManagerDidFinishedDownloadSession:) withObject: self];

}

}

/************** NSURLConnection Delegates *****************/

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

[receivedData setLength:0];

}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

    [receivedData appendData:data];

}

- (void)connection:(NSURLConnection *)connection  didFailWithError:(NSError *)error {

    [receivedData release];

[connection release];

state = -1;

    NSLog(@"Connection failed! Error - %@ %@",

          [error localizedDescription],

          [[error userInfo] objectForKey:NSErrorFailingURLStringKey]);

}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {

if ([currentItem filename]) [[NSFileManager defaultManager] createFileAtPath:[currentItem filename]  contents:receivedData attributes:nil] ;

[connection release];

    [receivedData release];

state = 0;

NSLog(@"Download finished for %@", [currentItem url]);

}

/***********************************************************/

- (void) dealloc {

if (receivedData) [receivedData release];

if (urlConnection) [urlConnection release];

[items release];

[superdealloc];

}

@end

 

mercredi, décembre 12 2007

Débuggage Iphone : pas facile ! Une solution autour de NSLog.

En attendant des solution pour tracer et debugger correctement une appli Iphone, voici un moyen simple qui permet de récupérer les résultats des NSLog dans une application lancée par le Springboard : réorienter les NSLog vers un fichier.

Une macro remplace le NSLog.
Les données sont écrites dans /var/root/VSLog.txt

/*

* VSLog.h

* Created by Jérémie Engel 12/12/2007.

* Copyright 2007 VisuaWeb. All rights reserved.

*

*/

#include <Foundation/Foundation.h>

#include <CoreFoundation/CoreFoundation.h>

#define VSLog(s,...) [VSLog LogToDefaultFile:(s),##__VA_ARGS__]

#define NSLog(s,...) [VSLog LogToDefaultFile:(s),##__VA_ARGS__]

@interface VSLog : NSObject {

va_list ap;

NSFileHandle *fileOutHandle;

NSString *strToWrite, *fileOut;

}

+ (void)LogToDefaultFile: (NSString*)format, ...;

@end

/*

* VSLog.m

* Created by Jérémie Engel 12/12/2007.

* Copyright 2007 VisuaWeb. All rights reserved.

*

*/

#include "VSLog.h"

@implementation VSLog

+ (void)LogToDefaultFile:(NSString*)format, ...; {

va_listap;

NSFileHandle *fileOutHandle;

NSString *strToWrite, *fileOut;

va_start(ap,format);

strToWrite=[[[NSStringalloc] initWithFormat:format arguments:ap] stringByAppendingString:@"\n"];

va_end(ap);

if (![[NSFileManagerdefaultManager] fileExistsAtPath:@"/var/root/VSLog.txt"]) [[NSFileManagerdefaultManager] createFileAtPath:@"/var/root/VSLog.txt"contents:nilattributes:nil];

fileOut = [[NSStringstringWithString:@"/var/root/VSLog.txt"] stringByExpandingTildeInPath];

fileOutHandle = [NSFileHandlefileHandleForWritingAtPath:fileOut];

[fileOutHandletruncateFileAtOffset:[fileOutHandleseekToEndOfFile]];

[fileOutHandlewriteData:[strToWritedataUsingEncoding:NSUTF8StringEncoding]];

[fileOutHandlecloseFile];

[fileOutHandlerelease];

[fileOutrelease];

[strToWriterelease];

return;

}

@end

Joe-editor 3.5 pour Iphone

Voici une compilation de Joe-Editor 3.5 pour Iphone.

Pour l'installer et qu'il soit disponible en ligne de commande via un connexion ssh sur votre IPhone ou votre IPod, copiez juste le binaire "joe" dans le répertoire /usr/bin de votre iMachine.

Binaire de joe-editor pour IPhone. snap_joe.jpg

jeudi, décembre 6 2007

Iphone Dev : Changer la font d'un UITableCell


Vous développez une application IPhone qui utilise un tableau UITable pour afficher du texte et vous souhaitez changer la taille du texte ?

Voici une solution simple. Il s'agit d'ajouter à la vue de la cellule un objet UITextLabel dont la font sera modifiable.
Dans l'exemple ci-dessous, la UITable créée contient 2 colonnes et 1 ligne dont la typo est Helvetica de taille 16.
WebFontCache.h est a importer, il fait parti de WebKit.

-(void)showTable

{

UIView *v = [[[UIView alloc] initWithFrame: [window bounds]] autorelease];

float th = 115;

CGSize vs = [v bounds].size;

table = [[UITable alloc] initWithFrame: CGRectMake(0,th,vs.width,vs.height-s.height-th)];

[table addTableColumn: [[[UITableColumn alloc] initWithTitle:@"" identifier:@"col1" width:220] autorelease]];

[table addTableColumn: [[[UITableColumn alloc] initWithTitle:@"" identifier:@"col2" width:100] autorelease]];

[table setDataSource: self];

[v addSubview: table];

[window setContentView: v];

}

- (int)numberOfRowsInTable:(UITable*)table

{

return 1;

}

- (UITableCell*)table:(UITable*)table cellForRow:(int)row column:(UITableColumn *)column

{

id cell = [[[UIImageAndTextTableCell alloc] init] autorelease];

UITextLabel *textLabel = [UITextLabel alloc];

if ([column identifier] == @"col1") [textLabel initWithFrame:CGRectMake(10.0f,0.0f,210.0f,30.0f)];

else if ([column identifier] == @"col2") [textLabel initWithFrame:CGRectMake(0.0f,0.0f,100.0f,30.0f)];

if( row == 0 && [column identifier] == @"col1" )  [textLabel setText: @"text to print Col1"];

if( row == 0 && [column identifier] == @"col2" ) [textLabel setText: @"text to print Col2"];

// Modify the UITableCell Font with a subview UITextLabel

[textLabel setFont: [NSClassFromString(@"WebFontCache") createFontWithFamily:@"Helvetica" traits:2 size:16]];

[textLabel setCentersHorizontally:NO];

[cell addSubview: textLabel];

[textLabel release];

return cell;

}

mardi, décembre 4 2007

Jailbreak d'un IPhone Orange : retrouver le Visual Voice Mail (VVM)

La manipulation s'avère être des plus simples. Pour retrouver le Visual Voice Mail (VVM) sur un IPhone Orange Jailbreaké, il faut juste réinitialiser les paramètres du IPhone. - aller dans Réglages - cliquer sur General puis sur Réinitialiser - Sélectionner "Réinitialiser tous les réglages"

Certains paramètres seront alors à resaisir mais les données personnelles (média notamment) sont conservées ; seules les infos de paramétrage sont remises à zéro.

Redémarrer SpringBoard pour prendre en compte une nouvelle application dans votre IPhone

SpringBoard IPhone

Lorsque l'on dépose une application dans de répertoire Applications de l'iPhone, il est nécessaire de rebooter l'IPhone pour que celle-ci soit prise en compte par le SpringBoard. Ceci peut s'avérer rébarbatif dans une phase de développement où cette opération doit être répétée un grand nombre de fois.

Plusieurs solutions existent pour éviter de redémarrer l'IPhone :

Utiliser SummerBoard qui propose une option de redémarrage du SpringBoard.

Installer les EricaUtilities pour bénéficier de la commande en ligne restart et redémarrer le SpringBoard en 1 ligne de commande via une connexion ssh :
restart /System/Library/CoreServices/SpringBoard.app/SpringBoard

Une copie est disponible de la version 0.30 ici.

Personnellement, j'utilise la méthode en ligne de commande associée à un alias zsh, c'est plus rapide quand on a une console ssh ouverte.

Configurer le Shell du IPhone

Vous avez débridé votre IPhone. Vous vous connectez dessus en ssh dès que vous pouvez ? Alors, forcément vous souhaitez personnaliser votre shell.

Le shell livré avec votre Iphone est SH (ZSH) dont voici le manuel.

Pour configurer le Shell au niveau utilisateur, il s'agit d'éditer un fichier ~/.zsh et d'ajouter la ligne suivante dans /etc/profile :
[ -r ~/.zsh ] && . ~/.zsh

le /etc/profile doit donc ressembler à :
# System-wide .profile for sh(1)

PATH="/bin:/sbin:/usr/bin:/usr/local/bin:/usr/sbin"
export PATH

TERM="vt102"
export TERM

if [ "${BASH-no}" != "no" ]; then
[ -r /etc/bashrc ] && . /etc/bashrc
fi

[ -r ~/.zsh ] && . ~/.zsh

Un alias bien pratique pour redémarrer le SpringBoard en utilisant EricaUtils (à placer dans ~/.zsh) :
alias sr='/usr/local/bin/restart \
/System/Library/CoreServices/SpringBoard.app/SpringBoard