Замена пространства для URL в swift4 [duplicate]

Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.

Например, ниже - класс ученика, который будет использовать его в нашем коде.

public class Student {

    private int id;

    public int getId() {
        return this.id;
    }

    public setId(int newId) {
        this.id = newId;
    }
}

Приведенный ниже код дает вам исключение с нулевым указателем.

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}

Поскольку вы используете Obj_Student, но вы забыли инициализировать его, как в правильном коде, показанном ниже:

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student = new Student();
            obj_Student.setId(12);
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}
217
задан Bryan Chen 3 July 2014 в 11:57
поделиться

10 ответов

Swift 3

В Swift 3 есть addingPercentEncoding

var originalString = "test/test"
var escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
print(escapedString!)

Выход:

test% 2Ftest

< / blockquote>

Swift 1

В iOS 7 и выше есть stringByAddingPercentEncodingWithAllowedCharacters

var originalString = "test/test"
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())
println("escapedString: \(escapedString)")

Выход:

test% 2Ftest

Следующие полезные (инвертированные) наборы символов:

URLFragmentAllowedCharacterSet  "#%<>[\]^`{|}
URLHostAllowedCharacterSet      "#%/<>?@\^`{|}
URLPasswordAllowedCharacterSet  "#%/:<>?@[\]^`{|}
URLPathAllowedCharacterSet      "#%;<>?[\]^`{|}
URLQueryAllowedCharacterSet     "#%<>[\]^`{|}
URLUserAllowedCharacterSet      "#%/:<>?@[\]^`

Если вы хотите, чтобы другой набор символов был экранирован, создайте набор: Пример с добавлением " = "character:

var originalString = "test/test=42"
var customAllowedSet =  NSCharacterSet(charactersInString:"=\"#%/<>?@\\^`{|}").invertedSet
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(customAllowedSet)
println("escapedString: \(escapedString)")

Выход:

test% 2Ftest% 3D42

Пример проверки символов ascii не в set:

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)\'")
}
454
ответ дан Asa 19 August 2018 в 15:12
поделиться
  • 1
    Разве никто больше не ошеломлен тем, как долго этот код должен это делать? Я имею в виду, что имя метода уже ад длинное, даже не выбирая разрешенный набор символов. – thatidiotguy 30 September 2014 в 21:19
  • 2
    Нет, я предпочитаю понимать более короткие краткими именами. Автозаполнение снимает боль. stringByAddingPercentEncodingWithAllowedCharacters() оставляет мало сомнений в том, что он делает. Интересный комментарий, считающий, как долго слово: «ошеломленный» является. – zaph 30 September 2014 в 21:37
  • 3
    stringByAddingPercentEncodingWithAllowedCharacters (.URLHostAllowedCharacterSet ()) Не кодирует всех символов должным образом. Ответ Брайана Чена - лучшее решение. – Julio Garcia 30 January 2016 в 17:54
  • 4
    @zaph Я добавил & к набору символов URLQueryAllowedCharacterSet, и я получил каждый символ в кодировке. Проверено с iOS 9, похоже, глючит, я пошел с ответом @ bryanchen, он работает хорошо! – Akash Kava 2 March 2016 в 16:28
  • 5
    Ответ ниже, который использует URLComponents и URLQueryItem, намного чище IMO. – Aaron Brager 12 November 2017 в 18:05

Swift 3

let allowedQueryParamAndKey =  NSCharacterSet.urlQueryAllowed.remove(charactersIn: ";/?:@&=+$, ")
paramOrKey.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey)

Swift 2.2 (Заимствование из Zaph и исправление для ключа запроса и значений параметров)

var allowedQueryParamAndKey =  NSCharacterSet(charactersInString: ";/?:@&=+$, ").invertedSet
paramOrKey.stringByAddingPercentEncodingWithAllowedCharacters(allowedQueryParamAndKey)

Пример:

let paramOrKey = "https://some.website.com/path/to/page.srf?a=1&b=2#top"
paramOrKey.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey)
// produces:
"https%3A%2F%2Fsome.website.com%2Fpath%2Fto%2Fpage.srf%3Fa%3D1%26b%3D2%23top"

Это более короткая версия ответа Брайана Чена. Я предполагаю, что urlQueryAllowed позволяет управляющим символам, через которые прекрасно, если они не составляют часть ключа или значения в строке запроса, в какой момент они должны быть экранированы.

8
ответ дан AJP 19 August 2018 в 15:12
поделиться
  • 1
    Мне нравится решение Swift 3, но оно не работает для меня в Swift 4: «Нельзя использовать мутирующий элемент по неизменяемому значению:« urlQueryAllowed »- это свойство только для получения». – Marián Černý 9 March 2018 в 21:29
  • 2

Swift 3:

let allowedCharacterSet = (CharacterSet(charactersIn: "!*'();:@&=+$,/?%#[] ").inverted)

if let escapedString = originalString.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) {
//do something with escaped string
}
28
ответ дан AlBeebe 19 August 2018 в 15:12
поделиться

Swift 4:

Это зависит от правил кодирования, за которыми следует ваш сервер.

Apple предлагает этот метод класса, но не сообщает о том, какой вид протокола RCF следует .

var escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!

После этого полезного инструмента вы должны гарантировать кодирование этих символов для ваших параметров:

  • $ (знак доллара) становится % 24
  • & amp; (Амперсанд) становится% 26
  • + (Плюс) становится% 2B
  • , (Comma) становится% 2C
  • : (Colon) становится% 3A
  • ; (Полуколон) становится% 3B
  • = (Равно) становится% 3D
  • ? (Question Mark) становится% 3F
  • @ (Commercial A / At) становится% 40

Другими словами, говоря о кодировке URL, вы должны следовать за Протокол RFC 1738 .

И Swift не распространяется на кодировку символа +, но он хорошо работает с этими тремя @:? chars.

Итак, чтобы правильно кодировать каждый ваш параметр, параметра .urlHostAllowed недостаточно, вы также должны добавить специальные символы, например:

encodedParameter = parameter.replacingOccurrences(of: "+", with: "%2B")

Надеемся, что это помогает кому-то, кто сходит с ума, чтобы найти эту информацию.

4
ответ дан Alessandro Ornano 19 August 2018 в 15:12
поделиться
  • 1
    Ваша реализация совершенно неверна. Как бы параметр "věž" кодироваться? – Marián Černý 9 March 2018 в 20:38
  • 2
    Спасибо, я обновил свой ответ. – Alessandro Ornano 10 March 2018 в 08:37

Мне нужно это, поэтому я написал расширение String, которое позволяет использовать строки URLEncoding, а также более общую конечную цель - преобразовать словарь параметров в URL-адрес стиля стиля 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
    }
}

Наслаждайтесь!

3
ответ дан BadPirate 19 August 2018 в 15:12
поделиться
  • 1
    Это не кодирует '& amp;' знак. Использование '& amp;' в параметре будет f *** вверх по строке запроса – Sam 26 November 2015 в 15:34
  • 2
    Это неправильно, оно не кодирует & или = в параметрах. Проверьте мое решение. – Marián Černý 9 March 2018 в 21:20

Все одинаково

var str = CFURLCreateStringByAddingPercentEscapes(
    nil,
    "test/test",
    nil,
    "!*'();:@&=+$,/?%#[]",
    CFStringBuiltInEncodings.UTF8.rawValue
)

// test%2Ftest
11
ответ дан Bryan Chen 19 August 2018 в 15:12
поделиться
  • 1
    Вы не сделали .bridgeToOvjectiveC() второй аргумент и не получили & quot; Не можете преобразовать тип выражения 'CFString!' для ввода «CFString!» & quot; ? – Kreiri 3 July 2014 в 12:16
  • 2
    @Kreiri Почему это необходимо? И детская площадка, и REPL довольны моим кодом. – Bryan Chen 3 July 2014 в 12:55
  • 3
    Шахты не являются: / (бета 2) – Kreiri 3 July 2014 в 13:02
  • 4
    Это лучший ответ, поскольку он кодирует & amp; правильно. – Sam 26 November 2015 в 15:34

Swift 3:

let originalString = "http://www.ihtc.cc?name=htc&title=iOS开发工程师"

1. encodingQuery:

let escapedString = originalString.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)

результат:

"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)

результат:

"http:%2F%2Fwww.ihtc.cc%3Fname=htc&title=iOS%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88"
17
ответ дан cpburnz 19 August 2018 в 15:12
поделиться
  • 1
    Я использовал первое решение, но хочу вернуть текст, например, iOS 开发 工程师. – Akshay Phulare 2 January 2018 в 14:38

Этот работает для меня.

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
}

Я нашел выше функцию по этой ссылке: http://useyourloaf.com/blog/how-to-percent-encode-a -url строка / .

2
ответ дан Gaurav Singla 19 August 2018 в 15:12
поделиться

Вы можете использовать URLComponents, чтобы избежать необходимости вручную уклониться от строки запроса:

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, host: String, path: String, queryItems: [URLQueryItem]) {
        self.init()
        self.scheme = scheme
        self.host = host
        self.path = path
        self.queryItems = queryItems
    }
}

if let url = URLComponents(scheme: "https",
                             host: "www.google.com",
                             path: "/search",
                       queryItems: [URLQueryItem(name: "q", value: "Formula One")]).url {

    print(url)  // https://www.google.com/search?q=Formula%20One
}
34
ответ дан Leo Dabus 19 August 2018 в 15:12
поделиться
  • 1
    Этот ответ требует большего внимания, так как есть проблемы со всеми другими (хотя, честно говоря, они могли быть лучшей практикой в ​​то время). – Asa 18 May 2017 в 14:55
  • 2
    К сожалению, URLQueryItem не всегда правильно кодируется. Например, Formula+One будет закодирован до Formula+One, который будет декодирован до Formula One. Поэтому будьте осторожны со знаком «плюс». – Sulthan 10 March 2018 в 09:15
  • 3

Swift 4

Чтобы кодировать параметр в URL-адресе, я нахожу, что с помощью символа .alphanumerics задан самый простой вариант:

let encoded = parameter.addingPercentEncoding(withAllowedCharacters: .alphanumerics)
let url = "http://www.example.com/?name=\(encoded!)"

Использование любого из стандартных наборов символов для кодирования URL-адресов (например, URLQueryAllowedCharacterSet или URLHostAllowedCharacterSet) не будут работать, потому что они не исключают символы = или &.

Обратите внимание, что с помощью .alphanumerics он кодирует некоторые символы, которые делают не нужно кодировать (например, ., - или _). Я нахожу использование .alphanumerics проще, чем создание пользовательского набора символов, и не против некоторых дополнительных символов, которые нужно закодировать. Если это вас беспокоит, создайте пользовательский набор символов, как описано в . Как процитировать кодировку URL String , например, например:

var allowed = CharacterSet.alphanumerics
allowed.insert(charactersIn: ".-_")
let encoded = parameter.addingPercentEncoding(withAllowedCharacters: allowed)
let url = "http://www.example.com/?name=\(encoded!)"

Внимание: параметр encoded это сила, развернутая. Для недопустимой строки юникода может произойти сбой. См. . Почему возвращаемое значение String.addingPercentEncoding () необязательно? . Вместо развертывания силы encoded! вы можете использовать encoded ?? "" или использовать if let encoded = ....

10
ответ дан Marián Černý 19 August 2018 в 15:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: