Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Firebase或Swift未检测到umlauts_Ios_Swift_Firebase_Firebase Realtime Database_Firebase Storage - Fatal编程技术网

Ios Firebase或Swift未检测到umlauts

Ios Firebase或Swift未检测到umlauts,ios,swift,firebase,firebase-realtime-database,firebase-storage,Ios,Swift,Firebase,Firebase Realtime Database,Firebase Storage,我在Firebase数据库/存储中发现了一些最奇怪的东西。问题是,我不知道Firebase或Swift是否没有检测到umlauts,例如(ä,ö,ü) 我用Firebase做了一些简单的事情,比如将图像上传到Firebase存储,然后下载到tableview。例如,我的一些.png文件的标题中有umlauts(Röda.png) 因此,如果我下载它们,问题就出现了。我唯一的下载url是nil的时间是文件名是否包含我所说的umlauts 所以我尝试了一些替代方法,比如在HTMLö-ö。但这

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

我用Firebase做了一些简单的事情,比如将图像上传到Firebase存储,然后下载到
tableview
。例如,我的一些
.png
文件的标题中有umlauts(
Röda.png

因此,如果我下载它们,问题就出现了。我唯一的下载
url
nil
的时间是文件名是否包含我所说的umlauts

所以我尝试了一些替代方法,比如在
HTML
ö-ö。但这是行不通的。你们能给我提个建议吗?我不能使用
ö-o
ü-u

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

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)

在花了相当多的时间研究您的问题之后,差异可以归结为字符
ö
的编码方式,我将其追溯到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在其文本输入系统中选择了分解形式,而苹果则更喜欢另一种。您可以将文件名转换为其分解形式以匹配Firebase:

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

// o%CC%88
这与ASCII范围字符无关。Unicode可能非常令人困惑

参考资料:

  • (强烈推荐)
    • 用于Unicode的Horray

      简单的回答是不,我们实际上没有做任何特别的事情。基本上,我们在引擎盖下所做的就是:

      // 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 Storage client内置)中,它完全不应该这样做,因为它们是两个完全不同的字符(实际上,
      str1
      的长度是
      2
      ,而在Obj-C中
      str2
      的长度是
      1
      ,而在Swift中,我假设两者的答案都是
      1

      苹果必须在使用Swift进行比较之前对字符串进行规范化(这可能是一个合理的做法,因为否则会导致诸如字符串“相同”但比较不同之类的错误)。事实证明,这正是他们所做的(请参阅他们文章中的“扩展石墨烯簇”一节)

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

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

      let imageName = "smorgasbörd.jpg"
      let path = "images/\(imageName)"
      let decomposedPath = path.decomposedStringWithCanonicalMapping // Unicode Form D
      let ref = FIRStorage.storage().reference().child(decomposedPath)
      // use this ref and you'll always get the same objects
      

      您是否检查过URL是否已转义
      Röda.png
      应该成为URL路径中的
      R%C3%B6da.png
      。@code不同的是Firebase存储中实际的URL路径是
      Ro%CC%88da
      那么我的选项是什么?据我所知,没有必要像回答“Code Different”那样再次这样做,因为您已经在“您的引擎盖下”这样做了。您的选择是选择一个Unicode规范化(我将答案编辑为显示D),并在所有操作中都坚持使用它。快速和客观-C处理事情的方式不同,所以使用哪一种方式很重要。复制和粘贴随机Unicode字符可能不起作用,因为它们将被不同的对待(很可能)。非常感谢:)这么多混乱,但现在它工作得很好。我只想说,这并不是问题的结束。对于分解的路径,这些是唯一没有缓存的图像。所以我想我得把它们去掉。