ios - tool - tag manager is not found and thus will not be used
Firebase o Swift no detectan diéresis (2)
Encontré algo extraño en Firebase
Database / Storage. La cuestión es que no sé si Firebase o Swift no están detectando diéresis, por ejemplo (ä, ö, ü).
Hice algunas cosas fáciles con Firebase, como subir imágenes a Firebase Storage y luego descargarlas en la tableview
. Algunos de mis archivos .png
tenían diéresis en el título, por ejemplo ( Röda.png
).
Entonces el problema ocurre ahora si los descargo. La única vez que mi url
descarga es nil
es si el nombre del archivo contiene las diéresis de las que estaba hablando.
Así que probé algunas alternativas como en HTML
ö - ö
. Pero esto no está funcionando. ¿Pueden ustedes sugerirme algo? No puedo usar ö - o
, ü - u
etc.
Este es el código cuando la url
es nil
cuando intentas establecer algunos valores en 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)
Después de pasar un poco de tiempo investigando su problema, la diferencia se reduce a cómo se codifica el carácter ö
y lo remonté a formularios de normalización Unicode.
La letra ö
se puede escribir de dos maneras, y String
/ NSString
considera iguales:
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
Pero cuando los codifica porcentualmente, producen diferentes resultados:
print(str1.stringByAddingPercentEncodingWithAllowedCharacters(.URLPathAllowedCharacterSet())!)
print(str2.stringByAddingPercentEncodingWithAllowedCharacters(.URLPathAllowedCharacterSet())!)
// o%CC%88
// %C3%B6
Supongo que Google / Firebase elige la forma descompuesta mientras que Apple prefiere la otra en su sistema de entrada de texto. Puede convertir el nombre del archivo a su forma descompuesta para que coincida con Firebase:
let str3 = str2.decomposedStringWithCanonicalMapping
print(str3.stringByAddingPercentEncodingWithAllowedCharacters(.URLPathAllowedCharacterSet()))
// o%CC%88
Esto es irrelevante para los caracteres de rango ASCII. Unicode puede ser muy confuso.
Referencias
¡Horray para Unicode!
La respuesta corta es que no, en realidad no estamos haciendo nada especial aquí. Básicamente, todo lo que hacemos bajo el capó es:
// 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];
}
Lo que me sorprende es que:
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
devuelve true
. En Objective-C (en el que está integrado el cliente de Firebase Storage), no debería ser así, ya que son dos caracteres totalmente diferentes (en realidad, la longitud de str1
es 2
mientras que la longitud de str2
es 1
en Obj-C , mientras que en Swift supongo que la respuesta es 1
para ambos).
Apple debe estar normalizando las cadenas antes de la comparación en Swift (probablemente sea algo razonable de hacer, ya que de lo contrario lleva a errores como este donde las cadenas son "iguales" pero se comparan de manera diferente). Resulta que esto es exactamente lo que hacen (consulte la sección "Clústeres de Grafema extendidos" de sus documentos ).
Entonces, cuando proporciona dos caracteres diferentes en Swift, se propagan a Obj-C como diferentes caracteres y, por lo tanto, se codifican de manera diferente. No es un error, solo una de las muchas diferencias entre el tipo String
de Swift y el tipo NSString
Obj-C. En caso de duda, elija una representación canónica que espera y quédese con ella, pero como desarrollador de la biblioteca, es muy difícil para nosotros elegir esa representación para usted.
Por lo tanto, al nombrar archivos que contienen caracteres Unicode, asegúrese de elegir una representación estándar (C, D, KC o KD) y siempre utilícelos al crear referencias.
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