Я должен начать эту статью с отказа от ответственности, она основана на iOS 13, Swift 5 и Xcode 11.x. Если вы читаете это и эти цифры выглядят устаревшими, будьте предупреждены.

Я также должен предупредить вас, что уведомления, в основном удаленные, связаны с инфраструктурой Apple, а это означает, что для их использования вам потребуется учетная запись Apple Developers.

Теперь, если вы только что добрались сюда, вам, возможно, следует сначала вернуться к Части I, Части II и Части III, если не читать дальше.

Хорошо, в части III мы в основном рассмотрели установку библиотеки IBM SwiftJWT и настроили наш веб-токен JSON. Следующим шагом будет создание самого поста. Добавьте этот код в файл RemoteNotifications.swift в вашем проекте Noob.

func postNotification() {
...
do {
let jwtString = try jwtEncoder.encodeToString(myJWT)
let content = "https://api.sandbox.push.apple.com/3/device/" + token
var loginRequest = URLRequest(url: URL(string: content)!)
loginRequest.allHTTPHeaderFields = ["apns-topic": "ch.cqd.noob",
"content-type": "application/json",
"apns-priority": "10",
"apns-push-type": "alert",
"authorization":"bearer " + jwtString]
let session = URLSession(configuration: .default, delegate: self, delegateQueue: OperationQueue.main)
loginRequest.httpMethod = "POST"
let data = try? JSONSerialization.data(withJSONObject: jsonObject, options:[])
loginRequest.httpBody = data
} catch {
print("failed to encode")
}
}

Импортируйте код здесь, URL-адрес для POST APN. Возьмите не это для песочницы, вам нужно использовать немного другой URL-адрес для производства. Также обратите внимание, что токен, упомянутый здесь, представляет собой строку из 64 символов, которую мы получили, когда регистрировали наш iDevice в Apple во второй части. Наконец, обратите внимание, что apns-topic — это идентификатор пакета вашего проекта, а jwtString — веб-токен JSON, который мы только что создали.

Вы заметите ошибку, когда будете копировать и вставлять это в свой проект. Ошибка в строке сеанса. Чтобы исправить это, сделайте RemoteNotifications URLSessionDelegate.

class PostController: NSObject,URLSessionDelegate {

Мы почти закончили. Теперь нам нужно вернуться к ContentView.swift. Полный код которого я показываю здесь.

import SwiftUI
let notify = LocalNotifications()
let poster = RemoteNotifications()
struct ContentView: View {
var body: some View {
VStack {
Button(action: {
notify.doNotification()
}) {
Text("local")
}
Button(action: {
poster.postNotification()
}) {
Text("remote")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

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

На тот случай, если вы допустили ошибку и получили на консоли другой код состояния, отличный от 200. Вот таблица, которая поможет вам понять, что происходит.

200 Успешно
400 Неверный запрос
403 Произошла ошибка с сертификатом или маркером аутентификации поставщика
405 В запросе использовалось неверное значение :method. Поддерживаются только POST-запросы.
410. Токен устройства больше не активен для темы.
413. Полезная нагрузка уведомления была слишком большой.
429. Сервер получил слишком много запросов на один и тот же токен устройства. .
500 Внутренняя ошибка сервера
503 Сервер отключается и недоступен.

Время для игры. Измените jsonObject, чтобы включить звук. Попробуйте скомпилировать приложение на втором устройстве и снова запустить его. Ваше удаленное уведомление появится только на первом, это тот 64-символьный идентификатор в игре. Чтобы удаленное уведомление работало на втором устройстве, вам нужно сделать второй вызов URL-адреса, публикующего его, со вторым идентификатором из 64 символов.

var jsonObject: [String: Any] = ["aps":["sound":"bingbong.aiff","badge":2,"alert":["title":"What, where, who, when, how","body":"You must be kidding"]]]

Если, конечно, прочитав все пять статей, вы наверняка задаетесь вопросом, нет ли более простого способа сделать это. Конечно есть, хотя и не в iOS. Если вам просто нужно быстрое решение, потому что у вас нет времени для более подробного изучения, вы можете просто использовать простой скрипт, подобный этому. Очевидно, вам нужно заполнить звездочки.

#!/bin/bash
deviceToken="*"
authKey="../AuthKey_*.p8"
authKeyId="*"
teamId=CWGS87U262
bundleId="*"
endpoint=https://api.development.push.apple.com
read -r -d '' payload <<-'EOF'
{
   "aps": {
      "alert": {
         "title": "my title",
         "body": "my body text message"
      }
   }
   }
}
EOF
# --------------------------------------------------------------------------
base64() {
   openssl base64 -e -A | tr -- '+/' '-_' | tr -d =
}
sign() {
   printf "$1" | openssl dgst -binary -sha256 -sign "$authKey" | base64
}
time=$(date +%s)
header=$(printf '{ "alg": "ES256", "kid": "%s" }' "$authKeyId" | base64)
claims=$(printf '{ "iss": "%s", "iat": %d }' "$teamId" "$time" | base64)
jwt="$header.$claims.$(sign $header.$claims)"
echo $time
curl --verbose \
   --header "content-type: application/json" \
   --header "authorization: bearer $jwt" \
   --header "apns-topic: $bundleId" \
   --data "$payload" \
   $endpoint/3/device/$deviceToken

Что будет работать, только хорошо… вы не можете публиковать это в магазине приложений.