Bildirimlerde Yapılan Değişikliklerle İlgili Bilgilendirme

Matt Gaunt

Öncelikle, bu berbat başlık için özür dilerim ancak olamadım.

Chrome 44'te Notfication.data ve ServiceWorkerRegistration.getNotifications() eklenmiştir ve push mesajlarıyla ilgili bildirimlerle ilgili bazı yaygın kullanım alanlarını basitleştirmektedir.

Bildirim Verileri

Notification.data, bir JavaScript nesnesini Bildirim ile ilişkilendirmenize olanak tanır.

Bunun temelinde ise push mesajı aldığınızda bazı veriler içeren bir bildirim oluşturabilirsiniz. Daha sonra, notificationclick etkinliğinde tıklanan bildirimi alabilir ve verilerini alabilirsiniz.

Örneğin, bir veri nesnesi oluşturup bu nesneyi bildirim seçeneklerinize ekleyebilirsiniz:

self.addEventListener('push', function(event) {
    console.log('Received a push message', event);

    var title = 'Yay a message.';
    var body = 'We have received a push message.';
    var icon = '/images/icon-192x192.png';
    var tag = 'simple-push-demo-notification-tag';
    var data = {
    doge: {
        wow: 'such amaze notification data'
    }
    };

    event.waitUntil(
    self.registration.showNotification(title, {
        body: body,
        icon: icon,
        tag: tag,
        data: data
    })
    );
});

Bu, Notificationclick etkinliğindeki bilgileri alabileceğimiz anlamına gelir:

self.addEventListener('notificationclick', function(event) {
    var doge = event.notification.data.doge;
    console.log(doge.wow);
});

Eskiden verileri IndexDB'de saklamanız veya simge URL'sinin sonuna bir şey koymanız gerekiyordu. Örneğin,

ServiceWorkerRegistration.getNotifications()

Push bildirimleri üzerinde çalışan geliştiricilerin yaygın isteklerinden biri, gösterilen bildirimler üzerinde daha fazla kontrol sahibi olmaktır.

Kullanım alanına, bir kullanıcının birden çok mesaj gönderdiği ve alıcının birden çok bildirim gösterdiği bir sohbet uygulaması verilebilir. İdeal olarak web uygulaması, görüntülenmemiş birden fazla bildiriminiz olduğunu fark edip bunları tek bir bildirime daraltabilir.

getBildirimler() olmadan yapabileceğiniz en iyi şey önceki bildirimi en son mesajla değiştirmektir. getBildirimler() ile, zaten bir bildirim görüntüleniyorsa bildirimleri "daraltabilirsiniz". Bu da çok daha iyi bir kullanıcı deneyimi sağlar.

Bildirimlerin bir arada gruplandırılmasını gösteren örnek.

Bunu yapmak için gereken kod nispeten basittir. Push etkinliğinizin içinde, bir dizi geçerli Bildirimler almak için ServiceWorkerRegistration.getBildirimler() öğesini çağırın ve buradan, tüm bildirimlerin daraltılması veya Notification.tag etiketinin kullanılması gibi doğru davranışa karar verin.

function showNotification(title, body, icon, data) {
    var notificationOptions = {
    body: body,
    icon: icon ? icon : 'images/touch/chrome-touch-icon-192x192.png',
    tag: 'simple-push-demo-notification',
    data: data
    };

    self.registration.showNotification(title, notificationOptions);
    return;
}

self.addEventListener('push', function(event) {
    console.log('Received a push message', event);

    // Since this is no payload data with the first version
    // of Push notifications, here we'll grab some data from
    // an API and use it to populate a notification
    event.waitUntil(
    fetch(API_ENDPOINT).then(function(response) {
        if (response.status !== 200) {
        console.log('Looks like there was a problem. Status Code: ' +
            response.status);
        // Throw an error so the promise is rejected and catch() is executed
        throw new Error();
        }

        // Examine the text in the response
        return response.json().then(function(data) {
        var title = 'You have a new message';
        var message = data.message;
        var icon = 'images/notification-icon.png';
        var notificationTag = 'chat-message';

        var notificationFilter = {
            tag: notificationTag
        };
        return self.registration.getNotifications(notificationFilter)
            .then(function(notifications) {
            if (notifications && notifications.length > 0) {
                // Start with one to account for the new notification
                // we are adding
                var notificationCount = 1;
                for (var i = 0; i < notifications.length; i++) {
                var existingNotification = notifications[i];
                if (existingNotification.data &&
                    existingNotification.data.notificationCount) {
                    notificationCount +=
existingNotification.data.notificationCount;
                } else {
                    notificationCount++;
                }
                existingNotification.close();
                }
                message = 'You have ' + notificationCount +
                ' weather updates.';
                notificationData.notificationCount = notificationCount;
            }

            return showNotification(title, message, icon, notificationData);
            });
        });
    }).catch(function(err) {
        console.error('Unable to retrieve data', err);

        var title = 'An error occurred';
        var message = 'We were unable to get the information for this ' +
        'push message';

        return showNotification(title, message);
    })
    );
});

self.addEventListener('notificationclick', function(event) {
    console.log('On notification click: ', event);

    if (Notification.prototype.hasOwnProperty('data')) {
    console.log('Using Data');
    var url = event.notification.data.url;
    event.waitUntil(clients.openWindow(url));
    } else {
    event.waitUntil(getIdb().get(KEY_VALUE_STORE_NAME,
event.notification.tag).then(function(url) {
        // At the moment you cannot open third party URL's, a simple trick
        // is to redirect to the desired URL from a URL on your domain
        var redirectUrl = '/redirect.html?redirect=' +
        url;
        return clients.openWindow(redirectUrl);
    }));
    }
});

Bu kod snippet'iyle vurgulanması gereken ilk şey, bir filtre nesnesini getBildirimler() öğesine ileterek bildirimlerimizi filtrelememizdir. Bu, belirli bir etiketle (bu örnekte belirli bir görüşme için) bildirim listesi alabileceğimiz anlamına gelir.

var notificationFilter = {
    tag: notificationTag
};
return self.registration.getNotifications(notificationFilter)

Ardından, görünür durumdaki bildirimleri gözden geçirir, bu bildirimle ilişkili bir bildirim sayısı olup olmadığını ve buna bağlı bir artış olup olmadığını kontrol ederiz. Bu şekilde, kullanıcıya iki okunmamış mesaj olduğunu bildiren bir bildirim varsa yeni bir aktarma geldiğinde üç okunmamış mesaj olduğunu belirtmek isteriz.

var notificationCount = 1;
for (var i = 0; i < notifications.length; i++) {
    var existingNotification = notifications[i];
    if (existingNotification.data && existingNotification.data.notificationCount) {
    notificationCount += existingNotification.data.notificationCount;
    } else {
    notificationCount++;
    }
    existingNotification.close();
}

Vurgulanması gereken bir nokta da bildirimin bildirim listesinden kaldırılması için bildirimde close() öğesini çağırmanız gerektiğidir. Aynı etiket kullanıldığı için her bildirimin yerini bir sonraki bildirim alması nedeniyle bu durum Chrome'daki bir hatadır. Şu anda bu değiştirme, getNotifications() tarafından döndürülen diziye yansıtılmıyor.

Bu, getBildirimler() işlevinin yalnızca bir örneğidir. Tahmin edebileceğiniz gibi bu API, bir dizi başka kullanım alanına da hizmet eder.

NotificationOptions.vibrate

Chrome 45 sürümünden itibaren, bildirim oluştururken titreşim deseni belirtebilirsiniz. Titreşim API'sini destekleyen cihazlarda (şu anda yalnızca Android için Chrome'da) bu, bildirim görüntülendiğinde kullanılacak titreşim kalıbını özelleştirmenize olanak tanır.

Titreşim kalıbı bir sayı dizisi veya bir sayı dizisi olarak ele alınan tek bir sayı olabilir. Dizideki değerler, zamanları milisaniye cinsinden temsil eder. Çift dizinler (0, 2, 4, ...) ne kadar süre titreşeceğini, tek endeksler ise bir sonraki titreşimden önce ne kadar süre duraklatılacağını gösterir.

self.registration.showNotification('Buzz!', {
    body: 'Bzzz bzzzz',
    vibrate: [300, 100, 400] // Vibrate 300ms, pause 100ms, then vibrate 400ms
});

Kalan Yaygın Özellik İstekleri

Geliştiricilerin diğer yaygın özellik isteklerinden diğeri, belirli bir süre sonra bildirimi kapatabilmek veya yalnızca görünür olduğunda bir bildirimi kapatmak amacıyla push bildirimi gönderebilmektir.

Şu anda bunu yapmanın bir yolu yoktur ve spesifikasyonda buna izin verecek hiçbir şey yoktur :( Ancak Chrome mühendislik ekibi bu kullanım alanının farkındadır.

Android Bildirimleri

Masaüstünde aşağıdaki kodla bildirim oluşturabilirsiniz:

new Notification('Hello', {body: 'Yay!'});

Bu özellik, platformun kısıtlamaları nedeniyle Android'de hiçbir zaman desteklenmiyordu: Özellikle Chrome, Bildirim nesnesindeki geri çağırmaları (ör. onclick) destekleyemiyordu. Ancak, masaüstünde o anda açık olan web uygulamalarıyla ilgili bildirimleri görüntülemek için kullanılır.

Başlangıçta aşağıdaki gibi basit bir özellik algılamanın masaüstünü desteklemenize yardımcı olacağını ve Android'de herhangi bir hataya yol açmayacağından bahsetmemin tek nedeni:

if (!'Notification' in window) {
    // Notifications aren't supported
    return;
}

Ancak Android için Chrome'da artık push bildirimi desteği de bulunduğundan bildirimler ServiceWorker'dan oluşturulabiliyor ancak web sayfasından oluşturulamıyor. Bu nedenle bu özellik algılama özelliği artık uygun değil. Android için Chrome'da bir bildirim oluşturmaya çalışırsanız şu hata mesajını alırsınız:

_Uncaught TypeError: Failed to construct 'Notification': Illegal constructor.
Use ServiceWorkerRegistration.showNotification() instead_

Şu anda Android ve masaüstünde özellik algılamanın en iyi yolu aşağıdakileri yapmaktır:

    function isNewNotificationSupported() {
        if (!window.Notification || !Notification.requestPermission)
            return false;
        if (Notification.permission == 'granted')
            throw new Error('You must only call this \*before\* calling
    Notification.requestPermission(), otherwise this feature detect would bug the
    user with an actual notification!');
        try {
            new Notification('');
        } catch (e) {
            if (e.name == 'TypeError')
                return false;
        }
        return true;
    }

Bu, aşağıdaki gibi kullanılabilir:

    if (window.Notification && Notification.permission == 'granted') {
        // We would only have prompted the user for permission if new
        // Notification was supported (see below), so assume it is supported.
        doStuffThatUsesNewNotification();
    } else if (isNewNotificationSupported()) {
        // new Notification is supported, so prompt the user for permission.
        showOptInUIForNotifications();
    }
'nin kullanımıyla ilgili en iyi uygulamalar da dahil olmak üzere tüm belgeleri incelemeyi unutmayın.