2016-11-01 1 views
2

J'ai une application avec une application iOS 10 iMessage. Lorsque j'attache mon URL de fichier à un MSMessagemessage.URL est (null). Je ne sais vraiment pas ce qui cause ça. Lorsque je vérifie les journaux, je vois une URL correcte: URL: file:///thisuser/... etc. Cependant, message.URL journaux (null).L'URL de MSMessage reste nulle après l'avoir définie sur l'URL d'un fichier.

J'ai construit une classe Exporter, cela enregistre le fichier sur le disque, puis renvoie le chemin pour cela.

+ (NSString *) saveToDisk:(NSDictionary *)dictionary { 
    // Figure out destination name (in public docs dir) 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *zippedName = [self getExportFileName:dictionary withExtension:YES]; 
    NSString *zippedPath = [documentsDirectory stringByAppendingPathComponent:zippedName]; 

    // Export to data buffer 
    NSData *gzData = [NSKeyedArchiver archivedDataWithRootObject:dictionary]; 

    if (gzData == nil) return FALSE; 

    // Write to disk 
    [gzData writeToFile:zippedPath atomically:YES]; 

    return zippedPath; 
} 

Cela renverra quelque chose comme: /Users/thisuses/Library/Developer/CoreSimulator/Devices/.../Documents/new-save.rst, où .rst est une extension de fichier personnalisé juste pour mon application. Ceci, à son tour, est ajouté au MSMessage.

MSConversation *conversation = [self activeConversation]; 

MSMessageTemplateLayout *layout = [[MSMessageTemplateLayout alloc] init]; 
layout.image = [UIImage imageNamed:@"test"]; 
layout.caption = url.host; 

MSMessage *message = [[MSMessage alloc] init]; 
message.layout = layout; 

NSLog(@"Converter: %@", [Converter toDictionary:array]); 
NSLog(@"Exporter: %@", [Exporter saveToDisk:[Converter toDictionary:array]]); 
NSLog(@"URL: %@", [NSURL fileURLWithPath:[Exporter saveToDisk:[Converter toDictionary:array]]]); 

message.URL = [NSURL fileURLWithPath:[Exporter saveToDisk:[Converter toDictionary:array]]]; 

NSLog(@"Message URL 1: %@", message.URL); 

[conversation insertMessage:message completionHandler:^(NSError * error) { 
    NSLog(@"MSConvo error: %@",error); 
}]; 

== Edit: J'ai ajouté un chèque au code pour voir si l'exportateur retourne un chemin de fichier valide et se trouve, il le fait.

NSURL *fileURL = [NSURL fileURLWithPath:[Exporter saveRequestToDisk:[Converter databaseToRequest:history]]]; 

if ([fileURL isFileURL]) { 
    NSLog(@"is File URL!"); 
    message.URL = fileURL; 
} 
+0

vous appelez « [Exportateur SaveToDisk: [Convertisseur ToDictionary: array ]] 'trois fois dans cet extrait. Cela m'amène à demander si le chemin de fichier dans lequel les données sont écrites reste le même pour tous ces trois appels, c'est-à-dire pourriez-vous nous montrer ou développer l'implémentation de '[self getExportFileName: withExtension:]'? –

+0

Deux d'entre eux sont des «NSLog» qui ont été ajoutés après avoir remarqué le problème. Quand je les enlève - et ne l'appelle donc qu'une seule fois -, j'obtiens le même résultat. – user4992124

+0

Je n'ai encore aucune idée, mais pour le débogage, vous pouvez ajouter un NSLog à 'if (gzData == nil) return FALSE;', ie 'if (gzData == nil) {NSLog (@" L'archivage a échoué! ") ; retourne FALSE; } 'et au lieu de laisser le résultat de' [gzData writeToFile: zippedPath atomiquement: YES]; 'inutilisé, ajoutez une vérification là aussi, comme' if (! [gzData writeToFile: zippedPath atomiquement: YES]) {NSLog (@ " Échec de l'écriture dans le chemin de fichier% @ ", zippedPath)}'. En guise de remarque, je pense qu'il pourrait être préférable de renvoyer zéro au lieu de FAUX dans l'ancien appel. Si vous avez désespérément besoin d'un vrai Bool, vous devez utiliser NO, pas FALSE, je suppose –

Répondre

1

Après avoir regardé dans le docs et l'écrémage this article, je pense que la propriété url n'est pas censé pointer vers un fichier. Au lieu de cela, il doit

[...] [encoder] les données à transmettre avec le message.

Je suppose que la bonne façon de faire est de

Encode les données de votre application dans l'URL. Par exemple, vous pouvez encoder des données sous forme de paires clé-valeur dans la chaîne de requête de l'URL, comme indiqué ci-dessous:

guard let components = NSURLComponents(string: myBaseURL) else { 
    fatalError("Invalid base url") 
} 

let size = NSURLQueryItem(name: "Size", value: "Large") 
let count = NSURLQueryItem(name: "Topping_Count", value: "2") 
let cheese = NSURLQueryItem(name: "Topping_0", value: "Cheese") 
let pepperoni = NSURLQueryItem(name: "Topping_1", value: "Pepperoni") 
components.queryItems = [size, count, cheese, pepperoni] 

guard let url = components.url else { 
    fatalError("Invalid URL components.") 
} 

message.url = url 

(code tiré de la documentation, vous pouvez le convertir en ObjC ...)

Ainsi, au lieu de convertir votre dictionnaire NSData et l'écrire dans un fichier, vous pouvez l'encoder en queryItems, peut-être comme ceci:

NSMutableArray *queryItems = [[NSMutableArray alloc] init]; // Or initWithCapacity for the sake of performance... 
NSDictionary *dict = [Converter toDictionary:array]; 

for (id key in dict) { 
    id value = queryDictionary[key]; 
    NSURLQueryItem *queryItem = [NSURLQueryItem queryItemWithName:key value:value]; 
    [queryItems addObject:queryItem]; 
} 

[url setQueryItems:queryItems]; 
+0

Merde, c'est une documentation étrange.Ils indiquent clairement qu'il peut contenir 'HTTP',' HTTPS' d'un schéma de fichiers. De toute façon, dommage que vous ne puissiez pas envoyer un fichier. – user4992124

+0

Ils déclarent que c'est le cas sur MacOS seulement, mais ce n'est pas évident. A dû le lire deux fois pour obtenir le subtil changement de contexte ... -.- –

+0

(Aussi, pourriez-vous accepter ma réponse, puisque c'est techniquement correct? Ce serait bien :)) –