2016-11-01 2 views
2

У меня есть приложение с iOS 10 iMessage. Когда я прикрепляю свой файл к MSMessage, message.URL - (null). Я действительно не знаю, что вызывает это. Когда я проверяю журналы, я вижу правильный URL: URL: file:///thisuser/... и т. Д. Однако message.URL журналов (null).URL-адрес MSMessage nil после установки его в URL-адрес файла

Я создал класс Exporter, это сохраняет файл на диск и возвращает путь к нему.

+ (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; 
} 

Это будет возвращать что-то вроде: /Users/thisuses/Library/Developer/CoreSimulator/Devices/.../Documents/new-save.rst, где .rst является расширением пользовательского файла только для моего приложения. Это, в свою очередь, добавляется к 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: я добавил проверку на код, чтобы увидеть, если экспортер возвращает правильный путь к файлу и получается, что он делает.

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

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

вы называете «[экспортёр saveToDisk: [конвертер ToDictionary: массив ]] 'три ​​раза в этом фрагменте. Это заставляет меня спросить, сохраняется ли путь к файлу, который данные записывают, для всех трех этих вызовов, т. Е. Вы могли бы показать нам или подробнее о реализации '[self getExportFileName: withExtension:]'? –

+0

Два из них - это 'NSLog', которые были добавлены после замещения проблемы. Когда я их удаляю - и, таким образом, назову это только один раз, я получаю тот же результат. – user4992124

+0

Я еще не знаю, но для целей отладки вы можете добавить NSLog в 'if (gzData == nil) return FALSE;', т.е. 'if (gzData == nil) {NSLog (@" Архивирование не выполнено! ") ; return FALSE; } 'и вместо того, чтобы оставить результат' [gzData writeToFile: zippedPath atomically: YES]; 'unused, добавьте там также проверку, например' if (! [gzData writeToFile: zippedPath atomically: YES]) {NSLog (@ " Ошибка при записи в файл-путь% @ ", zippedPath)}'. В качестве побочного примечания, я думаю, лучше было бы возвращать нуль вместо FALSE в первом вызове. Если вам отчаянно нужен настоящий Bool, вы должны использовать NO, а не FALSE, я думаю, –

ответ

1

Посмотрев в docs и скользя this article, я думаю, что свойство URL не должен указывать на файл. Вместо этого он должен

[...] [кодировать] данные, которые будут переданы с сообщением.

Я предполагаю, что правильный путь заключается в

Кодировать данные вашего приложения в URL. Например, вы можете кодировать данные в виде пар ключ-значение в строке запроса в URL, как показано ниже:

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 

(код взят из документации, вы можете преобразовать его в ObjC ...)

Так вместо того, чтобы преобразовать свой словарь в NSData и записи его в файл, вы можете кодировать его в queryItems, возможно, как это:

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

Черт, вот какая странная документация.Они четко заявляют, что могут либо содержать «HTTP», «HTTPS» файловой схемы. В любом случае, слишком плохо, что вы не можете отправить файл через. – user4992124

+0

Они утверждают, что это относится только к macOS, хотя это не очевидно. Если бы прочитать его дважды, чтобы получить тонкий контекст-изменение ... -.- –

+0

(Также вы можете принять мой ответ, так как это технически правильно? Это было бы хорошо :)) –

Смежные вопросы