Se eu codificar uma string como esta:
var escapedString = originalString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
não escapa das barras /.
Eu pesquisei e encontrei este código Objective C:
NSString *encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)unencodedString,
NULL,
(CFStringRef)@"!*'();:@&=+$,/?%#[]",
kCFStringEncodingUTF8 );
Existe uma maneira mais fácil de codificar uma URL e se não, como faço para escrever isso em Swift?
No Swift 3 existe addingPercentEncoding
let originalString = "test/test"
let escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
print(escapedString!)
Resultado:
teste% 2Ftest
No iOS 7 e superior, há stringByAddingPercentEncodingWithAllowedCharacters
var originalString = "test/test"
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())
println("escapedString: \(escapedString)")
Resultado:
teste% 2Ftest
Os seguintes são conjuntos de caracteres úteis (invertidos):
URLFragmentAllowedCharacterSet "#%<>[\]^`{|}
URLHostAllowedCharacterSet "#%/<>?@\^`{|}
URLPasswordAllowedCharacterSet "#%/:<>?@[\]^`{|}
URLPathAllowedCharacterSet "#%;<>?[\]^`{|}
URLQueryAllowedCharacterSet "#%<>[\]^`{|}
URLUserAllowedCharacterSet "#%/:<>?@[\]^`
Se você quiser que um conjunto diferente de caracteres tenha escape, crie um conjunto:
Exemplo com o caractere "=" adicionado:
var originalString = "test/test=42"
var customAllowedSet = NSCharacterSet(charactersInString:"=\"#%/<>?@\\^`{|}").invertedSet
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(customAllowedSet)
println("escapedString: \(escapedString)")
Resultado:
teste% 2Ftest% 3D42
Exemplo para verificar caracteres ASCII que não estão no conjunto:
func printCharactersInSet(set: NSCharacterSet) {
var characters = ""
let iSet = set.invertedSet
for i: UInt32 in 32..<127 {
let c = Character(UnicodeScalar(i))
if iSet.longCharacterIsMember(i) {
characters = characters + String(c)
}
}
print("characters not in set: \'\(characters)\'")
}
Você pode usar URLComponents para evitar a codificação percentual manual de sua string de consulta:
let scheme = "https"
let host = "www.google.com"
let path = "/search"
let queryItem = URLQueryItem(name: "q", value: "Formula One")
var urlComponents = URLComponents()
urlComponents.scheme = scheme
urlComponents.host = host
urlComponents.path = path
urlComponents.queryItems = [queryItem]
if let url = urlComponents.url {
print(url) // "https://www.google.com/search?q=Formula%20One"
}
extension URLComponents {
init(scheme: String = "https",
host: String = "www.google.com",
path: String = "/search",
queryItems: [URLQueryItem]) {
self.init()
self.scheme = scheme
self.host = host
self.path = path
self.queryItems = queryItems
}
}
let query = "Formula One"
if let url = URLComponents(queryItems: [URLQueryItem(name: "q", value: query)]).url {
print(url) // https://www.google.com/search?q=Formula%20One
}
let originalString = "http://www.ihtc.cc?name=htc&title=iOS开发工程师"
1. encodingQuery:
let escapedString = originalString.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)
resultado:
"http://www.ihtc.cc?name=htc&title=iOS%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88"
2. encodingURL:
let escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
resultado:
"http:%2F%2Fwww.ihtc.cc%3Fname=htc&title=iOS%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88"
Swift 3:
let allowedCharacterSet = (CharacterSet(charactersIn: "!*'();:@&=+$,/?%#[] ").inverted)
if let escapedString = originalString.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) {
//do something with escaped string
}
Para codificar um parâmetro em URL, acho que usar o .alphanumericsconjunto de caracteres é a opção mais fácil:
let encoded = parameter.addingPercentEncoding(withAllowedCharacters: .alphanumerics)
let url = "http://www.example.com/?name=\(encoded!)"
Usar qualquer um dos conjuntos de caracteres padrão para codificação de URL (como URLQueryAllowedCharacterSetou URLHostAllowedCharacterSet) não funcionará, porque eles não excluem caracteres =ou &.
Nota que, usando .alphanumericsele vai codificar alguns personagens que não precisam de ser codificados (como -, ., _ou ~- ver 2.3 Caracteres não-reservados. Em RFC 3986). Acho que usar é .alphanumericsmais simples do que construir um conjunto de caracteres personalizados e não me importo com alguns caracteres adicionais a serem codificados. Se isso incomodar você, construa um conjunto de caracteres personalizados conforme descrito em Como codificar por cento uma string de URL , como por exemplo:
var allowed = CharacterSet.alphanumerics
allowed.insert(charactersIn: "-._~") // as per RFC 3986
let encoded = parameter.addingPercentEncoding(withAllowedCharacters: allowed)
let url = "http://www.example.com/?name=\(encoded!)"
Aviso: O encodedparâmetro é desembrulhado à força. Para string Unicode inválida, ele pode falhar. Consulte Por que o valor de retorno de String.addingPercentEncoding () é opcional? . Em vez de forçar o desembrulhamento, encoded!você pode usar encoded ?? ""ou usar if let encoded = ....
Swift 4 e 5 (Obrigado @sumizome pela sugestão. Obrigado @FD_ e @derickito pelo teste)
var allowedQueryParamAndKey = NSCharacterSet.urlQueryAllowed
allowedQueryParamAndKey.remove(charactersIn: ";/?:@&=+$, ")
paramOrKey.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey)
Swift 3
let allowedQueryParamAndKey = NSCharacterSet.urlQueryAllowed.remove(charactersIn: ";/?:@&=+$, ")
paramOrKey.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey)
Swift 2.2 (pegando emprestado do Zaph's e corrigindo a chave de consulta do url e os valores dos parâmetros)
var allowedQueryParamAndKey = NSCharacterSet(charactersInString: ";/?:@&=+$, ").invertedSet
paramOrKey.stringByAddingPercentEncodingWithAllowedCharacters(allowedQueryParamAndKey)
Exemplo:
let paramOrKey = "https://some.website.com/path/to/page.srf?a=1&b=2#top"
paramOrKey.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey)
// produces:
"https%3A%2F%2Ffanyv88.com%3A443%2Fhttps%2Fsome.website.com%2Fpath%2Fto%2Fpage.srf%3Fa%3D1%26b%3D2%23top"
Esta é uma versão mais curta da resposta de Bryan Chen. Eu acho que isso urlQueryAllowedé permitir os caracteres de controle através do qual está bom, a menos que eles façam parte da chave ou valor em sua string de consulta em que ponto eles precisam ser escapados.
Tudo é igual
var str = CFURLCreateStringByAddingPercentEscapes(
nil,
"test/test",
nil,
"!*'();:@&=+$,/?%#[]",
CFStringBuiltInEncodings.UTF8.rawValue
)
// test%2Ftest
Depende das regras de codificação seguidas pelo seu servidor.
A Apple oferece este método de classe, mas não informa que tipo de protocolo RCF segue.
var escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!
Seguindo esta ferramenta útil , você deve garantir a codificação desses caracteres para seus parâmetros:
Em outras palavras, falando sobre codificação de URL, você deve seguir o protocolo RFC 1738 .
E o Swift não cobre a codificação do + char, por exemplo , mas funciona bem com estes três @:? chars.
Então, para codificar corretamente cada um dos seus parâmetros, a .urlHostAllowedopção não é suficiente, você deve adicionar também os caracteres especiais como por exemplo:
encodedParameter = parameter.replacingOccurrences(of: "+", with: "%2B")
Espero que isso ajude alguém que enlouquece a pesquisar essas informações.
Uma solução rápida de uma linha. Substitua originalStringpela String que você deseja codificar.
var encodedString = originalString.addingPercentEncoding(withAllowedCharacters: CharacterSet(charactersIn: "!*'();:@&=+$,/?%#[]{} ").inverted)
Eu mesmo precisava disso, então escrevi uma extensão de String que permite URLEncoding strings, bem como o objetivo final mais comum, converter um dicionário de parâmetro em Parâmetros de URL do estilo "GET":
extension String {
func URLEncodedString() -> String? {
var escapedString = self.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
return escapedString
}
static func queryStringFromParameters(parameters: Dictionary<String,String>) -> String? {
if (parameters.count == 0)
{
return nil
}
var queryString : String? = nil
for (key, value) in parameters {
if let encodedKey = key.URLEncodedString() {
if let encodedValue = value.URLEncodedString() {
if queryString == nil
{
queryString = "?"
}
else
{
queryString! += "&"
}
queryString! += encodedKey + "=" + encodedValue
}
}
}
return queryString
}
}
Aproveitar!
Para Swift 5 para endcode string
func escape(string: String) -> String {
let allowedCharacters = string.addingPercentEncoding(withAllowedCharacters: CharacterSet(charactersIn: ":=\"#%/<>?@\\^`{|}").inverted) ?? ""
return allowedCharacters
}
Como usar ?
let strEncoded = self.escape(string: "http://www.edamam.com/ontologies/edamam.owl#recipe_e2a1b9bf2d996cbd9875b80612ed9aa4")
print("escapedString: \(strEncoded)")
Este está trabalhando para mim.
func stringByAddingPercentEncodingForFormData(plusForSpace: Bool=false) -> String? {
let unreserved = "*-._"
let allowed = NSMutableCharacterSet.alphanumericCharacterSet()
allowed.addCharactersInString(unreserved)
if plusForSpace {
allowed.addCharactersInString(" ")
}
var encoded = stringByAddingPercentEncodingWithAllowedCharacters(allowed)
if plusForSpace {
encoded = encoded?.stringByReplacingOccurrencesOfString(" ", withString: "+")
}
return encoded
}
Encontrei a função acima neste link: http://useyourloaf.com/blog/how-to-percent-encode-a-url-string/ .
let Url = URL(string: urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "")
SWIFT 4.2
Às vezes, isso acontecia apenas porque há espaço no slug OU ausência de codificação de URL para parâmetros que passam pelo URL da API.
let myString = self.slugValue
let csCopy = CharacterSet(bitmapRepresentation: CharacterSet.urlPathAllowed.bitmapRepresentation)
let escapedString = myString!.addingPercentEncoding(withAllowedCharacters: csCopy)!
//always "info:hello%20world"
print(escapedString)
NOTA: Não se esqueça de explorar bitmapRepresentation.
Isso está funcionando para mim no Swift 5 . O caso de uso é pegar um URL da área de transferência ou similar que já pode ter caracteres de escape, mas que também contém caracteres Unicode que podem causar URLComponentsou URL(string:)falhar.
Primeiro, crie um conjunto de caracteres que inclua todos os caracteres legais para URL:
extension CharacterSet {
/// Characters valid in at least one part of a URL.
///
/// These characters are not allowed in ALL parts of a URL; each part has different requirements. This set is useful for checking for Unicode characters that need to be percent encoded before performing a validity check on individual URL components.
static var urlAllowedCharacters: CharacterSet {
// Start by including hash, which isn't in any set
var characters = CharacterSet(charactersIn: "#")
// All URL-legal characters
characters.formUnion(.urlUserAllowed)
characters.formUnion(.urlPasswordAllowed)
characters.formUnion(.urlHostAllowed)
characters.formUnion(.urlPathAllowed)
characters.formUnion(.urlQueryAllowed)
characters.formUnion(.urlFragmentAllowed)
return characters
}
}
Em seguida, estenda Stringcom um método para codificar URLs:
extension String {
/// Converts a string to a percent-encoded URL, including Unicode characters.
///
/// - Returns: An encoded URL if all steps succeed, otherwise nil.
func encodedUrl() -> URL? {
// Remove preexisting encoding,
guard let decodedString = self.removingPercentEncoding,
// encode any Unicode characters so URLComponents doesn't choke,
let unicodeEncodedString = decodedString.addingPercentEncoding(withAllowedCharacters: .urlAllowedCharacters),
// break into components to use proper encoding for each part,
let components = URLComponents(string: unicodeEncodedString),
// and reencode, to revert decoding while encoding missed characters.
let percentEncodedUrl = components.url else {
// Encoding failed
return nil
}
return percentEncodedUrl
}
}
Que pode ser testado como:
let urlText = "https://www.example.com/폴더/search?q=123&foo=bar&multi=eggs+and+ham&hangul=한글&spaced=lovely%20spam&illegal=<>#top"
let url = encodedUrl(from: urlText)
Valor de urlno final:https://www.example.com/%ED%8F%B4%EB%8D%94/search?q=123&foo=bar&multi=eggs+and+ham&hangul=%ED%95%9C%EA%B8%80&spaced=lovely%20spam&illegal=%3C%3E#top
Observe que ambos %20e o +espaçamento são preservados, os caracteres Unicode são codificados, o %20no original urlTextnão é duplamente codificado e a âncora (fragmento ou #) permanece.
Editar: agora verificando a validade de cada componente.
Nenhuma dessas respostas funcionou para mim. Nosso aplicativo estava travando quando um url continha caracteres não ingleses.
let unreserved = "-._~/?%$!:"
let allowed = NSMutableCharacterSet.alphanumeric()
allowed.addCharacters(in: unreserved)
let escapedString = urlString.addingPercentEncoding(withAllowedCharacters: allowed as CharacterSet)
Dependendo dos parâmetros do que você está tentando fazer, você pode querer apenas criar seu próprio conjunto de caracteres. O acima permite caracteres ingleses, e-._~/?%$!:
O que me ajudou foi que criei um separado NSCharacterSete o usei em uma string codificada em UTF-8, ou seja, textToEncode para gerar o resultado necessário:
var queryCharSet = NSCharacterSet.urlQueryAllowed
queryCharSet.remove(charactersIn: "+&?,:;@+=$*()")
let utfedCharacterSet = String(utf8String: textToEncode.cString(using: .utf8)!)!
let encodedStr = utfedCharacterSet.addingPercentEncoding(withAllowedCharacters: queryCharSet)!
let paramUrl = "https://api.abc.eu/api/search?device=true&query=\(escapedStr)"
Jana Duggar foi aberta sobre sua busca pelo amor. Aqui está tudo o que ela disse sobre o assunto e sua janela de cinco anos para o casamento.
O astro de 'Outlander', Sam Heughan, revelou recentemente o que vai levar do set para relembrar Jamie Fraser, o papel que o tornou uma estrela.
'She Loves You' foi escrita em uma hora, gravada em um dia, e foi a música dos Beatles com uma de suas melhores apresentações de sua carreira.
Dolly Parton e sua avó Bessie tiveram um relacionamento especial. Vovó Parton estava muito doente, mas isso não impediu Dolly de pregar uma peça nela.
Você pode achar que o carvalho ou a nogueira são madeiras resistentes, mas quando se trata da madeira mais dura do mundo, elas nem chegam perto.
O oceano é repleto de beleza, mas também esconde algumas das criaturas marinhas mais assustadoras do planeta. Muitos desses animais espreitam nas profundezas do oceano, no mundo escuro e de alta pressão do fundo do mar.
Se você está enfrentando criaturas hostis ou se preparando para cenários PvP, conhecer os melhores encantamentos de espada no Minecraft pode te dar uma grande vantagem. Encantar espadas permite causar mais dano, aumentar a quantidade de itens obtidos de criaturas e prolongar a durabilidade da sua espada.
Quando as pessoas falam sobre países socialistas, geralmente imaginam o controle total do governo e a ausência de propriedade privada. Mas, na prática, as economias socialistas variam muito.
“Children” traz uma participação especial de grande nome e algumas notícias devastadoras
Este RAV4 está em excelentes condições e está preparado para um jogo de cadeiras musicais.
Imagens de drone capturaram bombeiros parecendo lutar para apagar o incêndio.
Eyes of Wakanda está diretamente relacionado ao MCU, além de atualizações sobre X-Men '97, What If..., Demolidor e muito mais.
O anel de noivado de Kate Middleton pertenceu à Princesa Diana antes do Príncipe William pedi-la em casamento. Descubra tudo o que há para saber sobre a peça histórica aqui.
John Cleese se casou com sua esposa, Jennifer Wade, em 2012. Aqui está tudo o que você precisa saber sobre a esposa de John Cleese, Jennifer Wade.
Patton Oswalt se casou com sua esposa, a também atriz Meredith Salenger, em 2017. Aqui está tudo o que você precisa saber sobre a esposa de Patton Oswalt, Meredith Salenger.
Mena Suvari é casada com o marido Michael Hope desde 2018. Aqui está tudo o que você precisa saber sobre o marido de Mena Suvari.
Isso me atinge De repente, como tantas vezes acontece É o meio do caminho tudo de novo <Não, não aquele no Pacífico, seu marrom, aquele no carnaval> Todas as manchetes em voz alta…..
Em 2022, com o lançamento do GPT-3, a habilidade de escrita parece se tornar menos importante. Com a IA, pessoas com redação ruim também podem gerar funcionários de qualidade.
No mundo acelerado e competitivo de hoje, a carreira desempenha um papel significativo no crescimento pessoal, na estabilidade financeira e na satisfação geral com a vida. No entanto, muitos indivíduos encontram-se presos em um ciclo implacável de estagnação e insatisfação, definhando gradualmente em suas vidas profissionais.
Na semana passada, notei um comunicado de imprensa, enviado via PressGazette (um site de notícias da mídia britânica). O artigo anunciava que a Acast, a empresa de publicidade e hospedagem de podcast Scandi, lideraria um consórcio de "provavelmente os editores mais influentes" em podcasting.