Firebase或Swift没有检测到变音符号

时间:2016-08-18 19:41:04

标签: ios swift firebase firebase-realtime-database firebase-storage

我在Firebase数据库/存储中找到了一些奇怪的东西。问题是我不知道Firebase或Swift是否没有检测到变形虫,例如(ä,ö,ü)。

我使用Firebase做了一些简单的事情,比如将图片上传到Firebase存储,然后将它们下载到tableview。我的一些.png文件在标题中有变音符号(Röda.png)。

所以如果我下载它们就会出现问题。我下载url nil的唯一时间是文件名是否包含我正在讨论的变音符号。

所以我在HTML ö - ö尝试了一些其他选择。但这不起作用。你们能给我一些建议吗?我无法使用ö - oü - u等。

这是url nil尝试将某些值设置为 Firebase 时的代码:

FIRStorage.storage().reference()
          .child("\(productImageref!).png")
          .downloadURLWithCompletion({(url, error)in


FIRDatabase.database().reference()
           .child("Snuses").child(productImageref!).child("productUrl")
           .setValue(url!.absoluteString)

let resource = Resource(downloadURL: url!, cacheKey: productImageref)

2 个答案:

答案 0 :(得分:2)

花了相当多的时间研究你的问题后,差异归结为字符ö的编码方式,并将其追溯到Unicode规范化表格。

ö字母可以用两种方式书写,String / NSString认为它们相同:

let str1 = "o\u{308}" // decomposed : latin small letter o + combining diaeresis
let str2 = "\u{f6}"   // precomposed: latin small letter o with diaeresis

print(str1, str2, str1 == str2) // ö ö true

但是当你对它们进行百分比编码时,它们会产生不同的结果:

print(str1.stringByAddingPercentEncodingWithAllowedCharacters(.URLPathAllowedCharacterSet())!)
print(str2.stringByAddingPercentEncodingWithAllowedCharacters(.URLPathAllowedCharacterSet())!)

// o%CC%88
// %C3%B6

我的猜测是Google / Firebase选择了分解形式,而Apple更喜欢其他文本输入系统。您可以将文件名转换为其分解的表单以匹配Firebase:

let str3 = str2.decomposedStringWithCanonicalMapping
print(str3.stringByAddingPercentEncodingWithAllowedCharacters(.URLPathAllowedCharacterSet()))

// o%CC%88

这与ASCII范围的字符无关。 Unicode可能非常令人困惑。

参考文献:

答案 1 :(得分:2)

Horray for Unicode!

简短的回答是,不,我们实际上并没有做任何特别的事情。基本上我们所做的一切都是:

// This is the list at https://cloud.google.com/storage/docs/json_api/ without the & because query parameters
NSString *const kGCSObjectAllowedCharacterSet = 
    @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$'()*+,;=:@";

- (nullable NSString *)GCSEscapedString:(NSString *)string {
  NSCharacterSet *allowedCharacters =
      [NSCharacterSet characterSetWithCharactersInString:kGCSObjectAllowedCharacterSet];

  return [string stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacters];
}

让我感到震惊的是:

let str1 = "o\u{308}" // decomposed : latin small letter o + combining diaeresis
let str2 = "\u{f6}"   // precomposed: latin small letter o with diaeresis

print(str1, str2, str1 == str2) // ö ö true

返回true。在Objective-C(内置Firebase存储客户端)中,它完全不应该,因为它们是两个完全不同的字符(实际上,str1的长度是{{1}虽然在Obj-C中2的长度为str2,而在Swift中我假设两者的答案都是1

Apple必须在Swift中进行比较之前对字符串进行规范化(这可能是一件合理的事情,否则会导致像this这样的错误,其中字符串是"相同"但是比较不同)。事实证明,这正是他们所做的(参见"扩展字形集群"他们的docs部分)。

因此,当您在Swift中提供两个不同的字符时,它们将作为不同的字符传播到Obj-C,因此编码方式不同。这不是一个错误,只是Swift的1类型和Obj-C的String类型之间的众多差异之一。如果有疑问,请选择您期望的规范表示并坚持使用它,但作为图书馆开发人员,我们很难为您选择该表示。

因此,在命名包含Unicode字符的文件时,请确保选择标准表示(C,D,KC或KD)并在创建引用时始终使用它。

NSString