Aller au contenu


Photo

Swift - NSSharingServiceNameComposeEmail

swift xcode 6 NSSharingServiceNameComposeEm Yosemite

  • Please log in to reply
30 replies to this topic

#1 Fredo

Fredo

    Grand(e) bavard(e)

  • Membres
  • PipPipPip
  • 236 Messages :
  • Configuration:Imac 27 - 2014 - Yosemite 10.10.3
  • Sexe:Masculin
  • Localisation:Marolles-sur-Zenne
  • Passions:Alexandre Dumas, l'Histoire, l'alchimie, le magnétisme, les plantes.

Posté 08 mai 2015 - 16:18

Bonjour à tous,

 

Bien plongé dans ma découverte du nouveau langage de programmation d'Apple (Swift), j'éprouve des difficultés afin d'utiliser l'api "NSSharingServiceNameComposeEmail" afin d'envoyer un courriel via Xcode.

Voici mon code :

 

@IBAction func envoiCourrier(sender: AnyObject) {

        

        

        let corps = "C'est un courriel"

        let elemPart = [corps] as NSArray

        

        var service = NSSharingService(named:NSSharingServiceNameComposeEmail)

        service?.delegate = self

        service?.recipients = ["COURRIELDUDESTINATAIRE"]

        

        let sujet = "Test d'envoi"

        service?.subject = sujet

        service?.performWithItems([elemPart])

 

 
La création du mail se passe bien mais j'aimerai faire en sorte que le corps du courriel soit plus complexe (comportant des variables, des carriage return, de la ponctuation bien placée).
Or, le contenu de la variable ne peut accepter de CR et la ponctuation est mal placée (le point se met en début de phrase suivante au lieu de se situer à la fin du mot se trouvant sur la ligne précédente).
 
Pour les variables, je procède de la manière suivante :
 
@IBOutlet weak var Fonction: NSTextField!
@IBAction func Courriel(sender: AnyObject) {

        

        let Resultat1:NSString = (Fonction.stringValue)

           

        let Corps = "C'est un courriel \(Resultat1)."

        let elemPart = [Corps] as NSArray

        

        var service = NSSharingService(named:NSSharingServiceNameComposeEmail)

        service?.delegate = self

        service?.recipients = ["COURRIELDUDESTINATAIRE"]

        

        let Sujet = "le sujet"

        service?.subject = Sujet

        service?.performWithItems(elemPart as [AnyObject])

        

   }

 
Comment faire pour que la variable "Corps" puisse contenir un corps de courriel normal (contenant ponctuation, espace, tabulation, CR)? J'ai beau chercher, je ne trouve rien à ce sujet.
D'avance merci.


#2 Fredo

Fredo

    Grand(e) bavard(e)

  • Membres
  • PipPipPip
  • 236 Messages :
  • Configuration:Imac 27 - 2014 - Yosemite 10.10.3
  • Sexe:Masculin
  • Localisation:Marolles-sur-Zenne
  • Passions:Alexandre Dumas, l'Histoire, l'alchimie, le magnétisme, les plantes.

Posté 08 mai 2015 - 18:14

Pour passer à la ligne, j'ai trouvé \r et \n. Quelle est la différence entre les deux?



#3 Fredo

Fredo

    Grand(e) bavard(e)

  • Membres
  • PipPipPip
  • 236 Messages :
  • Configuration:Imac 27 - 2014 - Yosemite 10.10.3
  • Sexe:Masculin
  • Localisation:Marolles-sur-Zenne
  • Passions:Alexandre Dumas, l'Histoire, l'alchimie, le magnétisme, les plantes.

Posté 08 mai 2015 - 18:56

La ponctuation se place mal parce que la variable qui précède contient "\n" à la fin

08/05/2015\n

 

Je suppose que c'est la raison pour laquelle le point qui doit suivre se place à la ligne.

 

Comment se débarrasse-t'on de ce "\n"? J'ai essayé "!" mais ça ne marche pas (c'est une NSString issue de la commande shell "systemsetup getdate").

 

var dateOutput : NSString? = NSString(data: dateSortie, encoding:NSUTF8StringEncoding)


Ce message a été modifié par Fredo - 08 mai 2015 - 18:56 .


#4 BorakLeRouge

BorakLeRouge

    Hamster d'or (dort ?)

  • Membres
  • PipPipPipPipPipPipPip
  • 3 983 Messages :
  • Configuration:Mac Mini Core i7 2019 - 16Go - 2x1To SSD
  • Sexe:Masculin
  • Localisation:Cormeilles en Parisis.rb
  • Passions:Macintosh, Photo, Haute-fidélité, Ski, Roller, Call of Duty, Tactical Ops, Counter Strike, Worms 1

Posté 08 mai 2015 - 19:52

\r\n

 

Ok,je connais la version Basic de ces caractères. Ca fait un peu partie de l'histoire de l'informatique :)

 

Le saut de ligne est géré de trois manières différentes selon les trois systèmes principaux.

1) Le Macintosh, a toujours utilisé le chr(13) ou "\r" comme saut de ligne.

2) Le PC à toujours utilisé le chr(13)+chr(10) ou "\r\n" comme saut de ligne

3) Unix utilise lui chr(10) ou "\n".

 

Quand on veut être tranquille, il vaut mieux utiliser la version PC, au moins elle marche partout (surtout pour les mails) :)

 

\r : Retour chariot

\n : Saut de ligne.

 

Pour swift : désolé, je ne connais pas :)


Ce message a été modifié par BorakLeRouge - 08 mai 2015 - 19:53 .

Je fais mes sauvegardes sur NSA-Cloud !

Au bout de 10 ans, le vieux MacPro vient de laisser sa place à un MacMini i7...


#5 Fredo

Fredo

    Grand(e) bavard(e)

  • Membres
  • PipPipPip
  • 236 Messages :
  • Configuration:Imac 27 - 2014 - Yosemite 10.10.3
  • Sexe:Masculin
  • Localisation:Marolles-sur-Zenne
  • Passions:Alexandre Dumas, l'Histoire, l'alchimie, le magnétisme, les plantes.

Posté 08 mai 2015 - 22:52

\r\n

 

Ok,je connais la version Basic de ces caractères. Ca fait un peu partie de l'histoire de l'informatique :)

 

Le saut de ligne est géré de trois manières différentes selon les trois systèmes principaux.

1) Le Macintosh, a toujours utilisé le chr(13) ou "\r" comme saut de ligne.

2) Le PC à toujours utilisé le chr(13)+chr(10) ou "\r\n" comme saut de ligne

3) Unix utilise lui chr(10) ou "\n".

 

Quand on veut être tranquille, il vaut mieux utiliser la version PC, au moins elle marche partout (surtout pour les mails) :)

 

\r : Retour chariot

\n : Saut de ligne.

 

Pour swift : désolé, je ne connais pas :)

 

Merci pour ces informations Borak :-)

 

J'ai résolu tous mes problèmes de syntaxe excepté celui qui concerne le "\n"suivant la date du jour et qui m'empêche de mettre un point après la date lors de la création du courriel.

Je vais enlever cette date puisqu'elle apparaît de toute façon dans le courriel. 

 

C'est en fait un programme d'envoi automatique de courriel avec entête et formule de politesse adaptées au sexe de la personne, si vous croyez que ça peut servir, j'envoi le code...



#6 Amarok II

Amarok II

    NeoAdmin

  • Administrateurs
  • PipPipPipPipPipPip
  • 1 472 Messages :
  • Configuration:Un petit truc en alu avec un grand rectangle lumineux qui affiche des choses qui bougent quand je chatouille un autre truc en alu, là... tout plat.
  • Sexe:Mystère
  • Localisation:Perpignan, France
  • Passions:MacFr bien sûr !

Posté 09 mai 2015 - 11:59

rien à voir avec l'histoire, mais si ca peut aider, il existe aussi une option dans le protocole de mail afin d'envoyer en mail au format html et non texte brut. Si l'option existe dans swift, cela serait judicieux de l'ajouter afin d'être peut-être plus libre de sa mise en forme...

Je dis ça, je suis peut-être (surement ?) à coté de la plaque. :)



MacBook Pro (13", fin 2012)
8Go RAM - 256Go SSD - 1To HD

Technicien certifié ACMT et plein d'autres trucs...

"On peut voir de bien des façons. On peut être aveugle de bien des façons." (Frank Herbert, Dune)

"Tu ne feras point de machine à l'esprit de l'homme semblable." (Frank Herbert, Dune)


#7 Fredo

Fredo

    Grand(e) bavard(e)

  • Membres
  • PipPipPip
  • 236 Messages :
  • Configuration:Imac 27 - 2014 - Yosemite 10.10.3
  • Sexe:Masculin
  • Localisation:Marolles-sur-Zenne
  • Passions:Alexandre Dumas, l'Histoire, l'alchimie, le magnétisme, les plantes.

Posté 10 mai 2015 - 00:02

Ca tangue, ça tangue, dans mon cerveau. Voilà quelques heures que je me gratte la tête à essayer d'inclure un attachement au corps du courriel (pdf).

Voilà ou j'en suis...

 

let elemPart = [body] as NSArray

        

        var service = NSSharingService(named:NSSharingServiceNameComposeEmail)

        service?.delegate = self

        service?.recipients = [(Resultat5)]

        service?.attachmentFileURLs = [NSURL.fileURLWithPath("/Volumes/....pdf)]

 

Il me manque l'API (à insérer après "body"?) me permettant de de gérer l'attachement? Est-ce la syntaxe qui est mauvaise (dans la dernière ligne)?

Je ne sais plus à quel saint me vouer, je les ai tous essayés. ;-)



#8 Fredo

Fredo

    Grand(e) bavard(e)

  • Membres
  • PipPipPip
  • 236 Messages :
  • Configuration:Imac 27 - 2014 - Yosemite 10.10.3
  • Sexe:Masculin
  • Localisation:Marolles-sur-Zenne
  • Passions:Alexandre Dumas, l'Histoire, l'alchimie, le magnétisme, les plantes.

Posté 10 mai 2015 - 01:22

Concernant le nettoyage de chaîne (\d à la fin de la variable), j'ai trouvé le code suivant (à adapter pour swift) :

 

function nettoyerChaine($chaine)

{
// rajoute autant de caractères invisibles à supprimer que tu le souhaite dans ce tableau
$caracteresASupprimer = array("\r","\n","\t");
 
foreach($caracteresASupprimer as $unCaract)
$chaine = str_replace($unCaract,'',$chaine);
 
return $chaine;
}



#9 jp

jp

    Touriste

  • Modérateurs
  • PipPipPipPipPipPipPipPipPip
  • 6 564 Messages :
  • Configuration:N/A
  • Sexe:Masculin
  • Localisation:Créteil

Posté 10 mai 2015 - 01:59

À noter tout d'abord qu'il s'agit plus d'une problématique de Cocoa que de Swift ici.

 

Sinon, les pièces à joindre sont à mettre dans le même array que ton texte de corp de message.

 

func forge_body() -> NSAttributedString
{
   let line1 = NSAttributedString(string: "Première ligne.", attributes: [NSFontAttributeName : NSFont(name: "Helvetica-Bold", size: 12.0)!])
   let line2 = NSAttributedString(string: "Deuxième ligne.", attributes: [NSFontAttributeName : NSFont(name: "Helvetica-Oblique", size: 12.0)!])
 
   let result = NSMutableAttributedString()
 
   result.appendAttributedString(line1)
   result.appendAttributedString(NSAttributedString(string: "\n"))
   result.appendAttributedString(line2)
 
   return result
}
 
func forge_mail()
{
   let recipient = "test@free.fr"
   let subject = "Mon Email"
   let body = forge_body()
   let attachement = "/path/to/my.pdf"
 
   if let service = NSSharingService(named:NSSharingServiceNameComposeEmail), let attachementURL = NSURL(fileURLWithPath: attachement)
   {
      let items = [ body, attachementURL ]
 
      service.recipients = [ recipient ]
      service.subject = subject
 
      service.performWithItems(items)
   }
   else
   {
      NSLog("Something is wrong somewhere")
   }
}

La phrase suivante est fausse. La phrase précédente est vraie.

#10 zekiller28

zekiller28

    Admin qui mord

  • Administrateurs
  • PipPipPipPipPipPipPipPipPip
  • 10 691 Messages :
  • Configuration:Toutes sortes de Mac du PPC à l'Intel et toute sorte de MacOS X De Panther Client à Maverick.
  • Sexe:Masculin
  • Localisation:Saint-Hilarion (78)

Posté 10 mai 2015 - 12:09

Fredo :

Je suis preneur du code si c'est toujours possible…  :zz-big-candidat:


Le site de ToolsX
Le site de ToolsXOptimizer

Apple Certified Mac Management Basics 10.12
Apple Certified Mac Management Basics 10.9 English
Apple Certified Mac Integration Basics 10.9 English
Apple Certified Associate Mac Integration 10.8
Apple Certified Mac Management Basics 10.8

#11 Fredo

Fredo

    Grand(e) bavard(e)

  • Membres
  • PipPipPip
  • 236 Messages :
  • Configuration:Imac 27 - 2014 - Yosemite 10.10.3
  • Sexe:Masculin
  • Localisation:Marolles-sur-Zenne
  • Passions:Alexandre Dumas, l'Histoire, l'alchimie, le magnétisme, les plantes.

Posté 10 mai 2015 - 18:11

Un grand merci à toi J.P., ton code fonctionne parfaitement (je l'ai un peu adapté).

 

Il me reste un obstacle pour rendre cette application utile pour tous. Il faudrait pouvoir fournir le chemin vers l'attachement dans l'application.

 

J'ai essayé via NSPathControl mais je reçois une erreur parce que le résultat de l'opération n'est pas un chemin :

 

file:///.file/id=6628294.377330

2015-05-10 17:39:06.652 AutoCv-Fin[3294:103287] --error: [ShareKit] SHKSandbox: No read access to file file:/.file/id=6628294.377330

 

Comment faire pour récupérer le chemin du fichier glissé sur le bouton NSPathControl?

 

Voici le code :

 

    @IBOutlet weak var Fonction: NSTextField!

    @IBOutlet weak var Vreferences: NSTextField!

    @IBOutlet weak var Politesse: NSTextField!

    @IBOutlet weak var Famille: NSTextField!

    @IBOutlet weak var Societe: NSTextField!

    @IBOutlet weak var CourrielCon: NSTextField!

    @IBOutlet weak var Motivations: NSTextField!

    @IBOutlet weak var Signature: NSTextField!

    @IBOutlet weak var Extra: NSTextField!

    @IBOutlet weak var Attachement: NSPathControl!

    

    

    @IBAction func Courriel(sender: AnyObject) {

        

        let Resultat1:NSString = (Fonction.stringValue)

        let Resultat2:NSString = (Vreferences.stringValue)

        let Resultat3:NSString = (Famille.stringValue)

        let Resultat4:NSString = (Societe.stringValue)

        let Resultat5:NSString = (CourrielCon.stringValue)

        let Resultat6:NSString = (Politesse.stringValue)

        let Resultat7:NSString = (Motivations.stringValue)

        let Resultat8:NSString = (Signature.stringValue)

        let Resultat9:NSString = (Extra.stringValue)

        let Resultat10:NSString = (Attachement.stringValue)

        var FormPoli : NSString = NSString()

        

        

        println(Resultat10)

        

        // Formatage du texte

        if Resultat6.hasPrefix("Madame"){

            

            FormPoli = "Chère"

            

        }else if Resultat6.hasPrefix("Mademoiselle"){

            

            FormPoli = "Chère"

        }else{

            FormPoli = "Cher"

        }

        

        println(FormPoli)

        

        let body = "\r\r\(Resultat6) \(Resultat3)\r\(Resultat4)\r\r\r\(FormPoli) \(Resultat6) \(Resultat3), \r\rC'est avec un grand intérêt que je découvre votre offre d'emploi au poste de \(Resultat1). V.Réf : \(Resultat2).\r\r\(Resultat7)\r\rPersuadé de l’intérêt que vous porterez à ma candidature, je me tiens à votre disposition pour tout complément d’information ou pour une entrevue à votre convenance.\r\rEn vous souhaitant bonne réception de la présente, je vous prie d’agréer, \(FormPoli) \(Resultat6) \(Resultat3), l'expression de mes sentiments distingués.\r\r\(Resultat8)\r\(Resultat9)"

        

        let attachement = "\(Resultat10)"

        println(attachement)

        

        // Création du courriel

        let elemPart = [body] as NSArray

        

        if let service = NSSharingService(named:NSSharingServiceNameComposeEmail), let attachementURL = NSURL(fileURLWithPath: attachement){

            let elemPart = [body, attachementURL] as NSArray

            

        service.delegate = self

        service.recipients = [(Resultat5)]

        

        let Sujet = "Votre offre d'emploi au poste de \(Resultat1). V. Réf. : \(Resultat2)"

        service.subject = Sujet

        service.performWithItems(elemPart as [AnyObject])

        

        }else{

            NSLog("Ca cloche quelque part")

        }

}

Fichier(s) joint(s)



#12 jp

jp

    Touriste

  • Modérateurs
  • PipPipPipPipPipPipPipPipPip
  • 6 564 Messages :
  • Configuration:N/A
  • Sexe:Masculin
  • Localisation:Créteil

Posté 10 mai 2015 - 18:59

Je n’ai pas de soucis avec un NSPathControl. Tu utilises bien la propriété "URL" ? (et pour le coup, tu n’as plus besoin de "let attachementURL = NSURL(fileURLWithPath: attachement)" vu que tu as déjà une NSURL sous les mains).

 

Pour ce qui est du \n et \r, c'est un vieux cauchemar venant d'obscures raisons historiques tout à fait discutables.

 

Si je me rappelle bien, ça vient des premières imprimantes et Télétypes.

 

\n c'est Line Feed, c'est à dire "instruction de scroller d'une ligne vers le bas".

\r c'est Carriage Return, c'est-à-dire "instruction de remettre le chariot en début de ligne".

 

Pour passer à la ligne, il fallait les deux instructions.

 

C'est devenu complètement désuet bien sûr, mais forcément tout le monde a choisi de faire évoluer ça "à sa sauce" pour représenter un passage à la ligne. Microsoft a choisi CRLF (\r\n), Unix LF (\n) et Apple CR (\r).

 

Bon, mais depuis OS X, et vu que c'est un Unix, on utilise aussi \n pour passer à la ligne. Tout ça pour dire que si \r marche surement (la plupart des codes gèrent les 3 cas), la norme sous OS X et Unix est d'utiliser \n.


La phrase suivante est fausse. La phrase précédente est vraie.

#13 Fredo

Fredo

    Grand(e) bavard(e)

  • Membres
  • PipPipPip
  • 236 Messages :
  • Configuration:Imac 27 - 2014 - Yosemite 10.10.3
  • Sexe:Masculin
  • Localisation:Marolles-sur-Zenne
  • Passions:Alexandre Dumas, l'Histoire, l'alchimie, le magnétisme, les plantes.

Posté 10 mai 2015 - 19:36

J'ai essayé le code suivant :

 

@IBOutlet weak var Attachement: NSPathControl!

let Resultat10:NSString = (Attachement.stringValue)

let attachement = "\(Resultat10)"

 

...

 

 

        // Création du courriel

        

        if let service = NSSharingService(named:NSSharingServiceNameComposeEmail)

        {

            let elemPart = [body, attachement] as NSArray

            

        service.delegate = self

        service.recipients = [(Resultat5)]

        

        let Sujet = "Votre offre d'emploi au poste de \(Resultat1). V. Réf. : \(Resultat2)"

        service.subject = Sujet

        service.performWithItems(elemPart as [AnyObject])

        

        }else{

            NSLog("Ca cloche quelque part")

        }

 
Hélas j'ai toujours la même erreur.
 
Merci pour les précisions concernant \r \n, cela s'avèrera surement utile un jour.

Ce message a été modifié par Fredo - 10 mai 2015 - 19:36 .


#14 Fredo

Fredo

    Grand(e) bavard(e)

  • Membres
  • PipPipPip
  • 236 Messages :
  • Configuration:Imac 27 - 2014 - Yosemite 10.10.3
  • Sexe:Masculin
  • Localisation:Marolles-sur-Zenne
  • Passions:Alexandre Dumas, l'Histoire, l'alchimie, le magnétisme, les plantes.

Posté 10 mai 2015 - 19:48

J'ai redémarre l'ordi mais rien n'y fait, je reçois toujours la même erreur. Xcode 6.3.1 ou 6.4 beta (6E14) idem

 

J'ai mis le projet Xcode en attachement, pourrais-tu le tester chez toi J.P.?

 

Merci.

Fichier(s) joint(s)



#15 jp

jp

    Touriste

  • Modérateurs
  • PipPipPipPipPipPipPipPipPip
  • 6 564 Messages :
  • Configuration:N/A
  • Sexe:Masculin
  • Localisation:Créteil

Posté 11 mai 2015 - 00:06

Voilà j'ai fait quelques fix. Le plus important est sur l'utilisation de NSPathControl. Le reste, c'est juste du formatage sans importance.

 

Fichier joint  AutoCv-Fin.zip   18,62 Ko   3 Nombre de téléchargements 


La phrase suivante est fausse. La phrase précédente est vraie.

#16 Fredo

Fredo

    Grand(e) bavard(e)

  • Membres
  • PipPipPip
  • 236 Messages :
  • Configuration:Imac 27 - 2014 - Yosemite 10.10.3
  • Sexe:Masculin
  • Localisation:Marolles-sur-Zenne
  • Passions:Alexandre Dumas, l'Histoire, l'alchimie, le magnétisme, les plantes.

Posté 11 mai 2015 - 00:25

L'ajout de l'attachement fonctionne à merveille. C'est simple en plus. Encore merci, sans toi, je n'aurai jamais trouvé tout ça.

 

@IBOutlet weak var Attachement: NSPathControl!

attachement = Attachement.URL

let elemPart = [body.componentsJoinedByString("\n"), attachement]

service.performWithItems(elemPart)

;-)

 

Par contre Mail se plante lorsque certains champs ne sont pas remplis (le mail se crée, mais vide, et Mail se plante).



#17 Fredo

Fredo

    Grand(e) bavard(e)

  • Membres
  • PipPipPip
  • 236 Messages :
  • Configuration:Imac 27 - 2014 - Yosemite 10.10.3
  • Sexe:Masculin
  • Localisation:Marolles-sur-Zenne
  • Passions:Alexandre Dumas, l'Histoire, l'alchimie, le magnétisme, les plantes.

Posté 11 mai 2015 - 00:33

Le plantage est lié à l'attachement. S'il y en a pas, Mail se plante.

Il faudrait que cela marche aussi sans attachement, de préférence.



#18 Fredo

Fredo

    Grand(e) bavard(e)

  • Membres
  • PipPipPip
  • 236 Messages :
  • Configuration:Imac 27 - 2014 - Yosemite 10.10.3
  • Sexe:Masculin
  • Localisation:Marolles-sur-Zenne
  • Passions:Alexandre Dumas, l'Histoire, l'alchimie, le magnétisme, les plantes.

Posté 11 mai 2015 - 22:22

Ce que je découvre de NSPathController est assez désespérant.

 

http://stackoverflow...-it-me-yosemite

 

Alors que cette fonction est assez importante, non?

Il existe des applications qui reçoivent des fichiers par simple "déposé" sur la fenêtre, ne serait-ce pas une meilleur solution? Quelle Api est utilisée pour faire cela? Le sais-tu J.P.?



#19 jp

jp

    Touriste

  • Modérateurs
  • PipPipPipPipPipPipPipPipPip
  • 6 564 Messages :
  • Configuration:N/A
  • Sexe:Masculin
  • Localisation:Créteil

Posté 11 mai 2015 - 23:06

Le NSPathController fonctionne assez bien non ? J'ai lu en diagonale le lien que tu donne, mais il me semble qu'ils rallent (à raison) sur un truc que tu n'utilise pas.

 

Tu peut faire un drag & drop sur la fenêtre elle même, mais c'est un peu plus chiant à gérer. L'avantage de NSPathController, c'est que tout est géré pour toi (jolie affichage du path + drag & drop).

 

Pour vérifier l'attachement, le mieux est surement de ne pas mettre de path du tout dans ton NSPathController dans ton XIB de manière à ce que par défaut "Attachement.URL" soit nil. Ensuite dans ta méthode "Courriel", si cet URL est nil tu le met pas dans l'array "elemPart", et si c'est pas nil tu vérifie que c'est bien un fichier, et si tel est le cas, tu le met dans "elemPart".


La phrase suivante est fausse. La phrase précédente est vraie.

#20 Fredo

Fredo

    Grand(e) bavard(e)

  • Membres
  • PipPipPip
  • 236 Messages :
  • Configuration:Imac 27 - 2014 - Yosemite 10.10.3
  • Sexe:Masculin
  • Localisation:Marolles-sur-Zenne
  • Passions:Alexandre Dumas, l'Histoire, l'alchimie, le magnétisme, les plantes.

Posté 12 mai 2015 - 22:06

J'ai effacé le contenu du champs "Path", et inséré du texte dans "Placeholder" (sans quoi NSPathControl n'apparaît pas dans l'appli!!!).

 

Au niveau du code, je pense n'être plus très loin du compte mais ça coince toujours quelque part.

 // Création du courriel
if let service = NSSharingService(named:NSSharingServiceNameComposeEmail), let attachement = Attachement.URL{
            
  let sanslien : NSString? = attachement.absoluteString!
  println(sanslien)
            
  if sanslien  == nil {
    let elemPart = [body]
            
  }else{
                
    let elemPart = [body.componentsJoinedByString("\n"), attachement]
  }
            
  service.delegate = self
  service.recipients = [(courrielStr)]
        
  let sujet = "Votre offre d'emploi au poste de \(fonctionStr). V. Réf. : \(vRefStr)"
 
  service.subject = sujet
  service.performWithItems(elemPart)
}

Ce message a été modifié par jp - 13 mai 2015 - 00:07 .


#21 Fredo

Fredo

    Grand(e) bavard(e)

  • Membres
  • PipPipPip
  • 236 Messages :
  • Configuration:Imac 27 - 2014 - Yosemite 10.10.3
  • Sexe:Masculin
  • Localisation:Marolles-sur-Zenne
  • Passions:Alexandre Dumas, l'Histoire, l'alchimie, le magnétisme, les plantes.

Posté 12 mai 2015 - 22:20

Pour ceux que le code Swift intéresse, je découvre le site suivant :

 

http://swiftcodes.eu

 

Il y a quelques exemples de procédures très utiles.



#22 jp

jp

    Touriste

  • Modérateurs
  • PipPipPipPipPipPipPipPipPip
  • 6 564 Messages :
  • Configuration:N/A
  • Sexe:Masculin
  • Localisation:Créteil

Posté 12 mai 2015 - 23:59

Je pense que tu doit raisonner encore trop en terme de script shell. Swift (comme beaucoup d'autres langages) utilise le concept de scope pour les déclarations.

 

Une déclaration faite dans un scope n'est visible qu'à l'intérieur de ce scope, pas à l'extérieur.

 

Dans ton code, tu déclare deux fois elemPart dans deux scopes différents (délimités par { et } ) qui sont les corps de ton "if" et de son "else". Au moment où tu appelle "service.performWithItems(elemPart)" tu n'est plus du tout dans un de ces deux scopes, et elemPart n'existe plus. Le compilateur te fait une erreur pour te dire qu'il ne sais pas de quoi tu parle.

 

Si on garde ta structure, ça devrais plutôt être comme ça :

if let service = NSSharingService(named:NSSharingServiceNameComposeEmail)
{
  let elemPart : [AnyObject]
 
  if let attachement = Attachement.URL
  {
    elemPart = [ body.componentsJoinedByString("\n"), attachement ]
  }
  else
  {
    elemPart = [ body.componentsJoinedByString("\n") ]
  }
 
  service.delegate = self
  service.recipients = [courrielStr]
  service.subject = "Votre offre d'emploi au poste de \(fonctionStr). V. Réf. : \(vRefStr)"
  
  service.performWithItems(elemPart)
}
else
{
  NSLog("Impossible d'utiliser le service d'envois de mail")
}

Note: tu ne doit plus tester l'attachement dans la première condition, sinon tu ne rentre jamais dans ton code quand il n'y a pas d'attachement (ce qui n'est pas ce que tu veut).

Note 2 : ne met pas de ( ) autour de tes nom de variables, ça ne sert vraiment à rien.

Note 3 : la possibilité d'initialiser une déclaration "let" plus tard est une nouveauté bien pratique des dernières versions de Swift. L'idée est que tu fait l'init quand tu veut, du moment qu'au moment où tu l'utilise dans ton code, elle soit complètement initialisée.

 

Mais dans ton cas, plutôt que de construire deux versions différentes de ton array, je pense que c'est mieux d'en construire un seul variable dans lequel tu rajoute l'attachement s'il y en a un, comme ça :

if let service = NSSharingService(named:NSSharingServiceNameComposeEmail)
{
  var elemPart : [AnyObject] = [ body.componentsJoinedByString("\n") ]
 
  if let attachement = Attachement.URL
  {
    elemPart.append(attachement)
  }
 
  service.delegate = self
  service.recipients = [courrielStr]
  service.subject = "Votre offre d'emploi au poste de \(fonctionStr). V. Réf. : \(vRefStr)"

  service.performWithItems(elemPart)
}
else
{
  NSLog("Impossible d'utiliser le service d'envois de mail")
}

La phrase suivante est fausse. La phrase précédente est vraie.

#23 Fredo

Fredo

    Grand(e) bavard(e)

  • Membres
  • PipPipPip
  • 236 Messages :
  • Configuration:Imac 27 - 2014 - Yosemite 10.10.3
  • Sexe:Masculin
  • Localisation:Marolles-sur-Zenne
  • Passions:Alexandre Dumas, l'Histoire, l'alchimie, le magnétisme, les plantes.

Posté 13 mai 2015 - 01:30

Qu'est ce qui motive ton choix d'une variable AnyObject pour 'elemPart'?

La fonction 'append' a été abordée lors de la rédaction du script précédent mais je ne connais pas bien sont étendue. Permet-elle de lier toute sorte de variable? 

NSURL avec AnyObject (et surement d'autres combinaisons), quelles sont ses limites? Y a-t-il des types de variables incompatibles?

Quelle est la raison de l'utilisation de "componentsJoinedByString("\n")"? Est-ce lié au fait que c'est une NSURL?

 

Désolé de poser autant de questions mais c'est très important pour moi de connaître les détails.

 

Merci pour ces exemples qui en disent un peu plus sur la syntaxe (j'aime beaucoup le deuxième exemple).



#24 jp

jp

    Touriste

  • Modérateurs
  • PipPipPipPipPipPipPipPipPip
  • 6 564 Messages :
  • Configuration:N/A
  • Sexe:Masculin
  • Localisation:Créteil

Posté 13 mai 2015 - 09:59

Qu'est ce qui motive ton choix d'une variable AnyObject pour 'elemPart'?
Alors il faut être précis : c'est un array de AnyObject, pas juste un AnyObject. Et il y a deux choses qui motivent ce choix :
1 - C'est le type qu'attend la méthode "performWithItems"
2 - On met des éléments de différents types dans l'array (une string et une NSURL). AnyObject est le plus proche équivalent de "id" en Objective-C, c'est à dire un type qui accepte tous les objets. C'est d'ailleurs pour ça que les NSArray des méthodes OC sont bridgé vers du [AnyObject].

 

 

La fonction 'append' a été abordée lors de la rédaction du script précédent mais je ne connais pas bien sont étendue. Permet-elle de lier toute sorte de variable?
La variable elemPart est un array. La fonction 'append' permet d'ajouter un élément à cet array. Y'a pas tellement de lien entre les objets (enfin autant qu'il peut y en avoir entre un livre et un DVD que tu stockerais dans une bibliothèque : ce sont tous les deux des objets). Ils sont juste stockés dans un même conteneur.
 
Là encore je pense que tu restes dans le modèle "programmation shell" où y'a pas de notion de conteneur ni de typage. Il faut que tu te renseignes sur la programmation orientée objet, les conteneurs, et les conteneurs dans Swift.

 

 

NSURL avec AnyObject (et surement d'autres combinaisons), quelles sont ses limites? Y a-t-il des types de variables incompatibles?

AnyObject accepte toutes les instances de classe (mais pas les structures). NSURL est un objet et String est une structure (mais le compilateur cast implicitement les String en NSString dans ce cas, d'où le fait qu'on a pas d'erreur en mettant un String dans une variable de type [AnyObject]).

 

 

 

Quelle est la raison de l'utilisation de "componentsJoinedByString("\n")"? Est-ce lié au fait que c'est une NSURL?

1 - La variable 'body' est un array (enfin en tout cas dans la version que je t'ai renvoyée). La fonction 'componentsJoinedByString' permet de générer un string en joignant tous les strings de l'array avec le caractère "\n". C'est juste pour faciliter la lecture / écriture du code (c'est subjectif).

2 - La variable 'body' n'est PAS une NSURL. C'est 'attachement' qui en est une.


La phrase suivante est fausse. La phrase précédente est vraie.

#25 Fredo

Fredo

    Grand(e) bavard(e)

  • Membres
  • PipPipPip
  • 236 Messages :
  • Configuration:Imac 27 - 2014 - Yosemite 10.10.3
  • Sexe:Masculin
  • Localisation:Marolles-sur-Zenne
  • Passions:Alexandre Dumas, l'Histoire, l'alchimie, le magnétisme, les plantes.

Posté 13 mai 2015 - 22:19

Merci pour toutes ces précisions, cela m'évitera des erreurs par la suite (espérons-le).

 

 

Alors il faut être précis : c'est un array de AnyObject, pas juste un AnyObject. Et il y a deux choses qui motivent ce choix :
1 - C'est le type qu'attend la méthode "performWithItems"
2 - On met des éléments de différents types dans l'array (une string et une NSURL). AnyObject est le plus proche équivalent de "id" en Objective-C, c'est à dire un type qui accepte tous les objets. C'est d'ailleurs pour ça que les NSArray des méthodes OC sont bridgé vers du [AnyObject].

 

 

AnyObject offre plus de souplesse. On utilise lorsqu'il faut assembler divers types de variables, mais aussi lorsqu'on ne sait pas quel type d'informations seront rentrées dans un champs donné? 

 

Dans le script, rien n'indique que c'est un Array de AnyObject. Est-ce dû au fait que tu utilises AnyObject et donc qu'il n'est pas obligatoire de déclarer que c'est un Array? 

Cela se détermine lors de l'assemblage des variables?

On utilise un Array à chaque fois que le résultat est fait de multiples réponses ou uniquement lorsque les résultats sont faits de types de variables différents?

 

 

Là encore je pense que tu restes dans le modèle "programmation shell" où y'a pas de notion de conteneur ni de typage. Il faut que tu te renseignes sur la programmation orientée objet, les conteneurs, et les conteneurs dans Swift.

 

Oui, mais je commence à comprendre la notion de conteneur, grâce aux exercices, et tes éclaircissements. Je vais néanmoins m'y pencher plus profondément, car la syntaxe des conteneurs influence énormément la manière dont doit être conçu le script.

 

2 - La variable 'body' n'est PAS une NSURL. C'est 'attachement' qui en est une.

 

 

C'est juste, j'ai commis une faute d'inattention.

Ce qui m'intéressait c'était surtout de savoir si componentsJoinedByString est exclusivement réservé au variable de type Array ou aussi disponible à d'autres.

Chaque type de variable utilise sont propre type d'objets?

 

 

Voici donc le code final de la section de composition du courriel (j'ai rajouté un popup).

  

        // composition du courriel

        if let service = NSSharingService(named:NSSharingServiceNameComposeEmail)

        {

            var elemPart : [AnyObject] = [ body.componentsJoinedByString("\n") ]

            

            if let attachement = Attachement.URL

            {

                elemPart.append(attachement)

            }

            

            service.delegate = self

            service.recipients = [courrielStr]

            service.subject = "Votre offre d'emploi au poste de \(fonctionStr). V. Réf. : \(vRefStr)."

            

            service.performWithItems(elemPart)

        }

        else

        {

            NSLog("Impossible d'utiliser le service d'envoi de courriel.")

            let monPopup:NSAlert = NSAlert()

            monPopup.messageText = "Erreur"

            monPopup.informativeText = "Impossible d'utiliser le service d'envoi de courriel."

            monPopup.runModal()

        }

    }

 

 

Est-il possible de poster l'application sur votre site (ça pourrait vous faire un peu de pub)? Elle fait 4,8 MB.



#26 jp

jp

    Touriste

  • Modérateurs
  • PipPipPipPipPipPipPipPipPip
  • 6 564 Messages :
  • Configuration:N/A
  • Sexe:Masculin
  • Localisation:Créteil

Posté 13 mai 2015 - 23:31

AnyObject offre plus de souplesse. On utilise lorsqu'il faut assembler divers types de variables, mais aussi lorsqu'on ne sait pas quel type d'informations seront rentrées dans un champs donné?

Oui, pour simplifier oui. Et il existe un type encore plus générique : "Any". Lui peut absolument tout contenir (les objets comme les structures).

 

Mais de manière générale, il vaut mieux éviter (ça casse un peu le système de typage, et ça rend le code plus obscure). Là on l'utilise parce 1/ on peut pas vraiment faire autrement (plusieurs types différents à collectionner) 2/ l'API Cocoa nous y oblige.

 

Dans le script, rien n'indique que c'est un Array de AnyObject.

En fait si : les [ ] autour de AnyObject indique que c'est un Array. Une variable de type "[AnyObject]" est un array de AnyObject. Une variable de type "[String]" est un array de String, etc.

 

AnyObject peut être utilisé en dehors du cadre d'un Array (une variable peut-être de type AnyObject simple). Il n'y a pas de rapport entre AnyObject et les arrays.

 

On utilise un Array à chaque fois que le résultat est fait de multiples réponses ou uniquement lorsque les résultats sont faits de types de variables différents?

Disons qu'on l'utilise quand on a besoin de réunir des objets dans un même endroit. Le besoin d'utiliser un Array est pratiquement aussi naturel que le besoin d'utiliser une bibliothèque pour stocker ses livres dans la vie réelle.

Y'a pas tellement de règles générale, mais usuellement quand tu as un nombre d'élément variables à stocker quelque part ou à transmettre à une méthode, tu utilise un Array (ou un conteneur autre).

 

Ce qui m'intéressait c'était surtout de savoir si componentsJoinedByString est exclusivement réservé au variable de type Array ou aussi disponible à d'autres.

C'est réservé aux Array (c'est une méthode de classe, associé au type Array - à ce niveau là il faut que tu étudie la POO). Enfin plus précisément au type cocoa NSArray. Mais Swift bridge les deux de toute façon (assez logique : ce sont des conteneurs du même type), donc ça reviens au même.

 

Chaque type de variable utilise sont propre type d'objets?

Chaque variable à son type oui.

 

var toto : String // Variable de type String uniquement

var toto : Int // Variable de type Int uniquement

var toto : Any // Variable qui peut contenir tous les types, ce qui se rapproche le plus des variables Shell. À éviter autant que faire se peut.

etc.

 

Est-il possible de poster l'application sur votre site (ça pourrait vous faire un peu de pub)? Elle fait 4,8 MB.

Non je ne met pas d'application tiers sur mon site. Mais peut-être que ça pourrais avoir sa place ici. Je sais plus si on a une section pour ça. Faut voir avec les admins :)


La phrase suivante est fausse. La phrase précédente est vraie.

#27 Fredo

Fredo

    Grand(e) bavard(e)

  • Membres
  • PipPipPip
  • 236 Messages :
  • Configuration:Imac 27 - 2014 - Yosemite 10.10.3
  • Sexe:Masculin
  • Localisation:Marolles-sur-Zenne
  • Passions:Alexandre Dumas, l'Histoire, l'alchimie, le magnétisme, les plantes.

Posté 13 mai 2015 - 23:58

J'avance à grand pas (même si le travail est loin d'être terminé) et c'est grâce à toi. Encore merci pour toutes ces infos sans lesquelles j'aurai déjà laissé tomber depuis longtemps.

 

J'utiliserai dorénavant les "[ ]" à bon escient. Mais qu'en est-il des "< >"? Qu'indiquent-ils?

 

Par "Votre site" j'entendais le ci-présent (ici). Je pensais que tu faisais partie des admins, erreur (encore une...). OK, je vois ça avec les admins.



#28 Fredo

Fredo

    Grand(e) bavard(e)

  • Membres
  • PipPipPip
  • 236 Messages :
  • Configuration:Imac 27 - 2014 - Yosemite 10.10.3
  • Sexe:Masculin
  • Localisation:Marolles-sur-Zenne
  • Passions:Alexandre Dumas, l'Histoire, l'alchimie, le magnétisme, les plantes.

Posté 18 mai 2015 - 22:51

Est-ce correct de dire que les signes "< >" sont utilisés afin de définir le contenu d'un Array?

Array de string = Array<String>?

Mais alors, quelle différence y a-t-il entre [String] et Array<String>?

Est-ce syntaxique?


Ce message a été modifié par Fredo - 18 mai 2015 - 22:55 .


#29 jp

jp

    Touriste

  • Modérateurs
  • PipPipPipPipPipPipPipPipPip
  • 6 564 Messages :
  • Configuration:N/A
  • Sexe:Masculin
  • Localisation:Créteil

Posté 18 mai 2015 - 23:53

C'est exactement la même chose. C'est ce qu'on appelle du sucre syntaxique (syntactic sugar). Ici "Array<String>" est le type "canonique", et "[String]" est le sucre syntaxique.

 

C'est expliqué dans la documentation : https://developer.ap...uage/Types.html -> "Array Type"


La phrase suivante est fausse. La phrase précédente est vraie.

#30 Fredo

Fredo

    Grand(e) bavard(e)

  • Membres
  • PipPipPip
  • 236 Messages :
  • Configuration:Imac 27 - 2014 - Yosemite 10.10.3
  • Sexe:Masculin
  • Localisation:Marolles-sur-Zenne
  • Passions:Alexandre Dumas, l'Histoire, l'alchimie, le magnétisme, les plantes.

Posté 19 mai 2015 - 00:29

let someArray: Array<String> = ["Alex", "Brian", "Dave"]

  • let someArray: [String] = ["Alex", "Brian", "Dave"]

 

Merci pour l'info.







Also tagged with one or more of these keywords: swift, xcode 6, NSSharingServiceNameComposeEm, Yosemite

0 utilisateur(s) en train de lire ce sujet

0 membre(s), 0 invité(s), 0 utilisateur(s) anonyme(s)