2016-08-18 8 views
2

Firebaseデータベース/ストレージには何か奇妙なことがあります。 FirebaseやSwiftがウムラウトを検出していないかどうかわかりません(ä、ö、ü)。ウムラウトを検出していないFirebaseまたはSwift

FirebaseではFirebase Storageに画像をアップロードしてから、tableviewにダウンロードするのが簡単でした。私の.pngファイルの中には、タイトルにウムラウト(例:Röda.png)がありました。

これで、ダウンロードした場合に問題が発生します。唯一の私のダウンロードurlnilです唯一の時間は私が話していたウムラウトがファイル名に含まれている場合です。

だから私はHTMLö - öのようないくつかの選択肢を試しました。しかし、これは動作していません。みんなが私に何かを提案できますか?あなたの問題を調査時間の公平なビットを過ごした後

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) 
+1

URLがエスケープされていることを確認しましたか? 'Röda.png'はURLパスで' R%C3%B6da.png'になります。 –

+0

@Code Firebase Storageの実際のURLパスは 'Ro%CC%88da' –

答えて

2

Horray!

短い答えは、いいえ、私たちは実際にここで特別なことをしていないということです。基本的に我々はボンネットの下に行うすべては次のとおりです。

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:私の心を吹く

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

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

    return [string stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacters]; 
} 

何しても、そのです。Objectbase-C(Firebase Storageクライアントが組み込まれています)では、完全に異なる2文字のため、完全に異なるはずがありません(実際には、str1の長さは2ですが、str2の長さはObj-Cの1です) Swiftでは答えは両方とも1と仮定しています)。

アップリュはSwiftで比較する前に文字列を正規化する必要があります(そうでなければ、文字列が「同じ」だが異なって比較されるthisのようなバグにつながるため)。これはまさに彼らがやっていることです(docsの "Extended Grapheme Clusters"セクションを参照)。

したがって、Swiftで2つの異なる文字を入力すると、それらは異なる文字としてObj-Cに伝播され、したがって異なるエンコードが行われます。バグではなく、SwiftのStringタイプとObj-CのNSStringタイプの多くの違いの1つです。疑問がある場合は、期待通りの標準表現を選択してください。しかし、図書館の開発者として、その表現を選択することは非常に難しいです。

したがって、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 
+0

です。私のオプションは何ですか?私が理解しているように、あなたはすでにあなたのフードの下でそれをやっているので、「Code Different」のように再び同じことをする必要はありません。 –

+0

あなたの選択は1つのUnicode正規化を選択することです(私はDを表示するために私の答えを編集しました)。 SwiftとObjective-Cは物事を違ったものにするので、どちらを使うかは重要です。ランダムなUnicode文字をコピーして貼り付けるのは、多分扱われる(おそらく)ため、おそらく動作しません。 –

+0

本当にありがとうございました:)とても混乱していますが、今は完全に機能しています。 –

2

:私はFirebaseにいくつかの値を設定しようとしたときurlnilときにこれがコードですö - oü - uなど

を使用することはできませんその違いは、文字öがどのようにコード化されているのか、そしてそれをUnicodeの正規化フォームまで追跡したところまで遡ります。

ö次の2つの方法で記述することができ、文字、およびString/NSStringは、それらが等しいと考える:

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

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

マイ:

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 

しかし、ときにそれらをパーセントエンコードし、それらは異なる結果を生成Google/Firebaseが分解されたフォームを選択しているのに対し、Appleはテキスト入力システムでもう一方を優先していると推測している。

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

// o%CC%88 

これは、ASCII範囲の文字とは無関係です。ファイル名をFirebaseと一致するように分解した形式に変換することができます。 Unicodeは非常に混乱する可能性があります。

参考文献:Unicodeの

関連する問題