Извлеките строку из `.dataTaskPublisher`

#ios #json #swift #combine #urlsession

Вопрос:

Я пытаюсь вернуть только строку из моего node.js Экспресс-сервер. Это базовый сервер, который возвращает «привет, мир!» но не как JSON объект, а как обычная строка. Вот мой код из моего запроса.

 URLSession
    .shared
    .dataTaskPublisher(for: request)
    .map(.data)
    .decode(type: String.self, decoder: decoder)
    .receive(on: DispatchQueue.main)
 

Я думаю, что делаю это правильно, но я понимаю это, но когда я запускаю его, я получаю эту ошибку: The data couldn't be read because it isn't in the correct format.

Обновить

Итак, согласно комментариям, я не возвращаюсь JSON , поэтому я не могу использовать JSONDecoder . Тем не менее, я хотел использовать это в общем виде, и некоторые API вернут JSON , некоторые вернут String s, а некоторые вернут Int s, а некоторые вернут Array<Codable> . Есть ли способ использовать combine, чтобы попытаться вернуть эти значения с моих различных конечных точек API?

Я знаю, что могу сделать что-то подобное:

 URLSession
    .shared
    .dataTaskPublisher(for: request)
    .map(.data)
    .compactMap { String(data: $0, encoding:. utf8) }
    .receive(on: DispatchQueue.main)
 

но я хочу иметь возможность вызывать каждую из моих конечных точек с помощью этой функции. Кто-нибудь может помочь?

Комментарии:

1. Что такое decoder ? А JSONDecoder ?

2. Что это такое? .декодирование(тип: String.self, декодер: декодер)

3. Где в этом мире находится Кармен Сандиего? Где в мире находится ваша модель данных?

4. Если он возвращается не как объект JSON , зачем вы его декодируете? И вместо error.localizedDescription того, чтобы просто читать error . Это точно говорит вам, что не так.

5. @El Tomato, я помню, как играл в эту игру в конце 80-х, это было здорово.

Ответ №1:

Вам не нужен декодер, просто преобразуйте данные в строку с помощью инициализатора строк.

 var cancels: Set<AnyCancellable> = []

func fetchData() {

    URLSession
        .shared
        .dataTaskPublisher(for: request)
        .map(.data)
        .compactMap { String(data: $0, encoding:. utf8) }
        .receive(on: DispatchQueue.main)
        .sink (
            receiveCompletion: {
                print("Completion: ($0)")
            },
            receiveValue: { result in
                print("String: (result)")
            })
        .store(in: amp;cancels)
}
 

Комментарии:

1. Спасибо за ответ, но я ищу способ сделать это с помощью этого .decode метода.

2. Как вы думаете, почему вам нужно использовать этот decode метод?

3. Ваш dataTaskPublisher не возвращает JSON, поэтому вы не можете использовать на нем JSONDecoder.

4. Спасибо, @DanielT. ЛОЛ, я был просто в ужасной панике и говорил себе compactMap String , что оставляю дыру, через которую могут пролезть побочные случаи, но на самом деле я могу JSON сначала обработать данные, если это не удастся, тогда я могу попробовать UTF-8 и так далее. Кто-нибудь думает, что это плохая идея?