[Résolu] Renomer fichier avec NSURL

LeeroyLeeroy Membre
octobre 2010 modifié dans API AppKit #1
Bonjour,

J'essaie de renommer des fichiers pour ce faire j'utilise un NSOpenPanel pour récupérer l'url du fichier avec des NSString j'en m'en sors à  peu près.

NSArray* files = [openDlg filenames];<br />NSString* saveDialogString = [files objectAtIndex:0];<br />NSString* path = [saveDialogString stringByDeletingLastPathComponent];<br />NSString* newPath = [NSString stringWithFormat:@&quot;%@/newName&quot;,path];<br />[[[NSFileManager alloc] init] moveItemAtPath:saveDialogString toPath:newPath error:NULL];<br />


J'ai pas testé mais je suppose que ça marche. En lisant la doc j'ai vu qu'Apple poussait à  utiliser des NSURL donc j'ai changé le code en :

NSArray* files = [openDlg filenames];<br />NSURL* saveDialogString = (NSURL*)[files objectAtIndex:0];<br />NSURL* path = [saveDialogString URLByDeletingLastPathComponent];<br />


Mais la dernière ligne ne passe pas à  l'exécution j'obtiens cette erreur :

-[NSPathStore2 URLByDeletingLastPathComponent]: unrecognized selector sent to instance 0x1001e66a0


Au final j'arrive à  rien récupérer en utilisant des URL, chemin, nom du fichier.. Plus je lis la docs de NSURL moins je comprend cette classe.
Merci d'avance de m'aider :)

Edit marqué comme résolu

Réponses

  • wiskywisky Membre
    13:48 modifié #2
    Il faut regarder la doc ;)

    Tu compile pour quelle version de Mac Os X ?

    Je fait comme ça :
    NSURL * url = [NSURL URLWithString:@&quot;/mon chemin/&quot;];<br />NSString * path = [[url absoluteString] stringByDeletingLastPathComponent];<br />
    
  • CéroceCéroce Membre, Modérateur
    13:48 modifié #3
    C'est pas plutôt [tt]+[NSURL fileURLWithString:][/tt] ?
    Je suis sûr avoir été pris au piège au moins 10 fois.
  • wiskywisky Membre
    13:48 modifié #4
    dans 1287065635:

    C'est pas plutôt [tt]+[NSURL fileURLWithString:][/tt] ?
    Je suis sûr avoir été pris au piège au moins 10 fois.

    T'as raison il vaut mieux fileURLWithString:
  • AliGatorAliGator Membre, Modérateur
    13:48 modifié #5
    Bonjour et bienvenue !

    En fait le souci dans ton code vient de ton raisonnement "comme Apple poussait à  utiliser des NSURL donc j'ai changé le code de [tt]NSString* saveDialogString = [files objectAtIndex:0];[/tt] à  [tt]NSURL* saveDialogString = (NSURL*)[files objectAtIndex:0][/tt]"

    Mais faire un cast en rajoutant (NSURL*) devant l'objet retourné par [tt][files objectAtIndex:0][/tt] n'a jamais fait de conversion d'une instance d'une classe vers une autre classe ! Ce n'est qu'une réinterprétation du pointeur que tu demandes, pas une conversions !

    En fait [tt][openDlg filenames][/tt] retourne toujours un NSArray de NSString, ces NSStrings correspondant chacune au chemin d'accès au fichier sélectionné.
    Du coup [tt][[openDlg filenames] objectAtIndex:x][/tt] retournera toujours un objet de type NSString. Mettre [tt](NSURL*)[/tt] devant le retour de cette fonction ne transformera pas ce NSURL en NSString !! (c'est vrai pour les types atomiques du C, comme pour caster un int en float, mais pas pour les pointeurs (pour lesquels ça ne fait que de la réinterprétation du pointeur) donc à  fortiori pas pour types dynamiques de l'Objective-C.

    C'est pour cela qu'il faut, comme indiqué par les collègues, utiliser [NSURL fileURLWithString:...] pour construire ta NSURL à  partir de la NSString... ou de façon plus efficace, ne pas utiliser la méthode "filenames" de NSOpenPanel pour récupérer un NSArray de NSString représentant les chemins, mais utiliser la méthode "URLs" de NSOpenPanel, qui elle te retourne justement un NSArray de NSURLs représentant les fileURLs vers les fichiers, comme ça appeler objectAtIndex: sur ce NSArray te retournera bien un NSURL puisque c'est ce qu'il contient directement.
  • LeeroyLeeroy Membre
    octobre 2010 modifié #6
    D'abord merci de me répondre.  :).

    Pour le cast en NSURL* il était normalement inutile j'ai juste mal lu la doc. J'ai vu un retourne un array de NSURL mais c'était la méthode URLs. J'essayerai de mieux lire la doc la prochaine fois.

    Dans ce cas je vais devoir récupérer le nom du fichier en string avec lastPathComponent je suppose. Pour la suite je compte utiliser les méthodes – URLByAppendingPathComponent: et – URLByDeletingLastPathComponent, je voulais savoir si il y avait une autre méthode plus propre ou plus courte que je n'ai pas vu. J'ai encore un peu de mal à  m'y retrouver dans la doc d'apple.  ::)

    Edit: Encore merci j'ai fini mon bout de code et il marche parfaitement pour ceux que ça intéresse :

    -(IBAction) rename:(id)sender;<br />{<br />&nbsp; &nbsp; NSOpenPanel* openDlg = [NSOpenPanel openPanel];<br />&nbsp; &nbsp; [openDlg setCanChooseFiles:YES];<br />&nbsp; &nbsp; [openDlg setCanChooseDirectories:NO];<br />&nbsp; &nbsp; [openDlg setAllowsMultipleSelection:NO];<br /><br />&nbsp; &nbsp; if ( [openDlg runModalForDirectory:nil file:nil] == NSOKButton )<br />&nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; NSArray* files = [openDlg URLs];<br />&nbsp; &nbsp; &nbsp; &nbsp; NSURL* saveDialogURL = [files objectAtIndex:0];<br />&nbsp; &nbsp; &nbsp; &nbsp; NSURL* path = [saveDialogURL URLByDeletingLastPathComponent];<br />&nbsp; &nbsp; &nbsp; &nbsp; NSString* fileNameWithExtension = saveDialogURL.lastPathComponent;<br />&nbsp; &nbsp; &nbsp; &nbsp; NSString* newName = [NSString stringWithFormat:@&quot;%@1&quot;,[fileNameWithExtension stringByDeletingPathExtension]];<br />&nbsp; &nbsp; &nbsp; &nbsp; newName = [newName stringByAppendingPathExtension:fileNameWithExtension.pathExtension];<br />&nbsp; &nbsp; &nbsp; &nbsp; NSURL* newPath = [path URLByAppendingPathComponent:newName];<br />&nbsp; &nbsp; &nbsp; &nbsp; [[[NSFileManager alloc] init] moveItemAtURL:saveDialogURL toURL:newPath error:NULL];<br />&nbsp; &nbsp; }<br />}<br />
    
Connectez-vous ou Inscrivez-vous pour répondre.