Расширение станд.:: список

Согласно рекомендациям Apple, вы можете получать push-уведомления как для фона, так и для состояния переднего плана, но когда дело доходит до состояния завершения, яблоко не позволяет автоматически открывать приложение или выполнять какие-либо действия. операции, если вы не запустите приложение через уведомление.

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

Пример кодирования:

В вашей библиотеке импорта баз данных импорта AppDelegate.swift

import Firebase
import FirebaseInstanceID
import FirebaseMessaging
import UserNotifications

Всякий раз, когда запуск приложения регистрируется для push добавьте следующие строки кода в didFinishLaunchingWithOptions

func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    registerForPushNotifications(application: application)
    handleNotificationWhenAppIsKilled(launchOptions)
    return true
}

func handleNotificationWhenAppIsKilled(_ launchOptions: [UIApplicationLaunchOptionsKey: Any]?) {
    // Check if launched from the remote notification and application is close
    if let remoteNotification = launchOptions?[.remoteNotification] as?  [AnyHashable : Any] {
        // Handle your app navigation accordingly and update the webservice as per information on the app.
    }
}

Добавьте методы расширения appDelegate, чтобы зарегистрироваться для удаленного уведомления и получить токен устройства из APNS

//MARK: - Notifications related...
extension AppDelegate {
    func registerForPushNotifications(application: UIApplication) {
        if #available(iOS 10.0, *) {
            // For iOS 10 display notification (sent via APNS)
            UNUserNotificationCenter.current().delegate = self
            let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
            UNUserNotificationCenter.current().requestAuthorization(
                options: authOptions,
                completionHandler: {_, _ in })
            // For iOS 10 data message (sent via FCM
            Messaging.messaging().delegate = self
        } else {
            let settings: UIUserNotificationSettings =
                UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
            application.registerUserNotificationSettings(settings)
        }

        application.registerForRemoteNotifications()
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let token = deviceToken.map { String(format: "%02.2hhx", [112]) }.joined()
        let savedAPNSToken = UserDefaults.standard.object(forKey: "savedAPNSToken") as? String
        if savedAPNSToken != token {
            UserDefaults.standard.set(token, forKey: "savedAPNSToken")
            UserDefaults.standard.synchronize()
            Messaging.messaging().apnsToken = deviceToken
        }
    }

    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print(error.localizedDescription)
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                     fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        completionHandler(UIBackgroundFetchResult.newData)
    }

}

Используйте следующие методы центра уведомлений для обработки уведомлений в основном и фоновом состояниях:

// MARK: - UNUserNotificationCenterDelegate
@available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {

    // Receive displayed notifications for iOS 10 devices.
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        let userInfo = notification.request.content.userInfo
        completionHandler([.alert])
    }


    /// Handle tap on the notification banner
    ///
    /// - Parameters:
    ///   - center: Notification Center
    ///   - response: Notification response
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse,
                                withCompletionHandler completionHandler: @escaping () -> Void) {

        let userInfo = response.notification.request.content.userInfo
        completionHandler()
    }

Обновление токена Firebase:

extension AppDelegate : MessagingDelegate {
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
        // Note: This callback is fired at each app startup and whenever a new token is generated.
        let savedFCMToken = UserDefaults.standard.object(forKey: "savedFCMToken") as? String
        if savedFCMToken != fcmToken {
            UserDefaults.standard.set(fcmToken, forKey: "savedFCMToken")
            UserDefaults.standard.synchronize()
            // Update FCMToken to server by doing API call...
        }
    }
}
6
задан Ferruccio 14 December 2008 в 12:49
поделиться

8 ответов

Весь код шаблона должен быть помещен в заголовочный файл. Эта заливка решает соединение проблем (это - самый простой путь). Причина это происходит, состоит в том, потому что компиляторы компилируют каждый источник (.cc) файл отдельно из других файлов. С другой стороны, это должно знать то, что кодирует точно, это должно создать (т.е. что является T в шаблоне, заменен с), и это не имеет никакого другого способа знать это, если программист не говорит это явно или включает весь код, когда шаблонное инстанцирование происходит. Т.е. когда mylist.cc компилируется, он ничего не знает о mylist пользователях и какой код должен быть создан. С другой стороны, если listuser.cc компилируется, и весь код mylist присутствует, компилятор создает необходимый код mylist. Можно читать больше об этом в здесь или в Stroustrup.

Ваш код имеет проблемы, что, если пользователь запрашивает отрицательный или слишком большой (больше, чем сумма элементов в списке). И я не смотрел слишком много.

Кроме того, я не знаю, как u планируют использовать его, но Ваш оператор [] является O (N) время, которое, вероятно, легко приведет к O (N*N) циклы...

10
ответ дан 8 December 2019 в 02:00
поделиться

Учитывая Ваш исходный проблемный оператор,

Я должен использовать списки для своей программы и должен был решить, использую ли я станд.:: вектор или станд.:: список. Проблема с вектором состоит в том, что существует, не удаляют метод и со списком, что нет никакого оператора [].

нет никакой потребности создать Ваш собственный класс списка (это не мудрое проектное решение так или иначе, потому что std::list не имеет виртуального деструктора, который является верным признаком, что он не предназначается, чтобы использоваться в качестве базового класса).

Можно все еще достигнуть того, что Вы хотите использовать std::vector и std::remove функция. Если v a std::vector<T>, затем удалить значение value, можно просто записать:

#include <vector>
#include <algorithm>
T value = ...; // whatever
v.erase(std::remove(v.begin(), v.end(), value), v.end());
21
ответ дан 8 December 2019 в 02:00
поделиться

Векторы имеют метод стирания, который может удалить элементы. Разве это не достаточно?

6
ответ дан 8 December 2019 в 02:00
поделиться

В зависимости от Ваших потребностей необходимо использовать std::vector (если Вам нужно, часто добавляет/удаляет в конце и произвольном доступе), или std::deque (если Вам нужно, часто добавляет/удаляет в конце или вначале, и Ваш набор данных огромен, и все еще хотят произвольный доступ). Вот хорошее изображение, показывающее Вам, как принять решение:

Container Choice
(источник: adrinael.net)

53
ответ дан 8 December 2019 в 02:00
поделиться

В дополнение к другим превосходным комментариям лучший способ расширить стандартный контейнер не деривацией, но записью бесплатных функций. Например, посмотрите, как Строковые Алгоритмы Повышения могут использоваться для расширения std::string и другие строковые классы.

5
ответ дан 8 December 2019 в 02:00
поделиться

Необходимо переместить весь код шаблона в заголовок.

1
ответ дан 8 December 2019 в 02:00
поделиться

Очевидный материал был уже детально описан:

Но методы Вы принимаете решение реализовать??

  • Деструктор.
    • Не требуемый компилятор генерирует это для Вас.
  • Две различных версии оператора [] бессмысленны
    • Также необходимо использовать станд.:: список:: size_type как индекс
    • Если Вы не намереваетесь поддерживать отрицательные индексы.
  • Нет никаких версий константы оператора []
  • Если Вы собираетесь реализовать [], необходимо также сделать в ()
  • Вы пропустили все различные способы создать список.
  • Контейнеры должны определить несколько типов внутренне
1
ответ дан 8 December 2019 в 02:00
поделиться

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

0
ответ дан 8 December 2019 в 02:00
поделиться
Другие вопросы по тегам:

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