Skip to content

Commit ed3a4f9

Browse files
committed
Rich Notifications
1 parent 07258e3 commit ed3a4f9

File tree

5 files changed

+223
-0
lines changed

5 files changed

+223
-0
lines changed
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>CFBundleDevelopmentRegion</key>
6+
<string>$(DEVELOPMENT_LANGUAGE)</string>
7+
<key>CFBundleDisplayName</key>
8+
<string>NotificationServiceExtension</string>
9+
<key>CFBundleExecutable</key>
10+
<string>$(EXECUTABLE_NAME)</string>
11+
<key>CFBundleIdentifier</key>
12+
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
13+
<key>CFBundleInfoDictionaryVersion</key>
14+
<string>6.0</string>
15+
<key>CFBundleName</key>
16+
<string>$(PRODUCT_NAME)</string>
17+
<key>CFBundlePackageType</key>
18+
<string>XPC!</string>
19+
<key>CFBundleShortVersionString</key>
20+
<string>$(MARKETING_VERSION)</string>
21+
<key>CFBundleVersion</key>
22+
<string>$(CURRENT_PROJECT_VERSION)</string>
23+
<key>NSExtension</key>
24+
<dict>
25+
<key>NSExtensionPointIdentifier</key>
26+
<string>com.apple.usernotifications.service</string>
27+
<key>NSExtensionPrincipalClass</key>
28+
<string>$(PRODUCT_MODULE_NAME).NotificationService</string>
29+
</dict>
30+
</dict>
31+
</plist>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
//
2+
// NotificationService.swift
3+
// NotificationServiceExtension
4+
//
5+
// Created by Naman Jain on 10/09/19.
6+
// Copyright © 2019 Naman Jain. All rights reserved.
7+
//
8+
9+
import UserNotifications
10+
11+
class NotificationService: UNNotificationServiceExtension {
12+
13+
var contentHandler: ((UNNotificationContent) -> Void)?
14+
var bestAttemptContent: UNMutableNotificationContent?
15+
16+
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
17+
self.contentHandler = contentHandler
18+
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
19+
20+
guard let bestAttemptContent = bestAttemptContent,
21+
let attURLStringDict = bestAttemptContent.userInfo["fcm_options"] as? [String: String],
22+
let attURLString = attURLStringDict["image"],
23+
let attURL = URL(string: attURLString) else {
24+
print("Failed to get Image Url")
25+
return
26+
}
27+
request.content.setValue("hello", forKey: "categoryIdentifier")
28+
29+
print(request.content.categoryIdentifier)
30+
31+
downloadImageFrom(url: attURL) { (attachment) in
32+
if let attachment = attachment {
33+
bestAttemptContent.attachments = [attachment]
34+
contentHandler(bestAttemptContent)
35+
}
36+
}
37+
38+
}
39+
40+
override func serviceExtensionTimeWillExpire() {
41+
// Called just before the extension will be terminated by the system.
42+
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
43+
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
44+
contentHandler(bestAttemptContent)
45+
}
46+
}
47+
48+
private func downloadImageFrom(url: URL, with completionHandler: @escaping (UNNotificationAttachment?) -> Void){
49+
let task = URLSession.shared.downloadTask(with: url) { (downloadedUrl, response, error) in
50+
guard let downloadedUrl = downloadedUrl else {
51+
completionHandler(nil)
52+
return
53+
}
54+
55+
var urlPath = URL(fileURLWithPath: NSTemporaryDirectory())
56+
let uniqueURLEnding = ProcessInfo.processInfo.globallyUniqueString + ".jpg"
57+
urlPath = urlPath.appendingPathComponent(uniqueURLEnding)
58+
59+
try? FileManager.default.moveItem(at: downloadedUrl, to: urlPath)
60+
61+
do{
62+
let attachment = try UNNotificationAttachment(identifier: "picture", url: urlPath, options: nil)
63+
completionHandler(attachment)
64+
}
65+
catch{
66+
completionHandler(nil)
67+
}
68+
}
69+
task.resume()
70+
}
71+
72+
73+
74+
}
75+
76+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="M4Y-Lb-cyx">
3+
<device id="retina6_1" orientation="portrait">
4+
<adaptation id="fullscreen"/>
5+
</device>
6+
<dependencies>
7+
<deployment identifier="iOS"/>
8+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
9+
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
10+
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
11+
</dependencies>
12+
<scenes>
13+
<!--Notification View Controller-->
14+
<scene sceneID="cwh-vc-ff4">
15+
<objects>
16+
<viewController id="M4Y-Lb-cyx" userLabel="Notification View Controller" customClass="NotificationViewController" customModule="NotificationsContentExtention" customModuleProvider="target" sceneMemberID="viewController">
17+
<view key="view" contentMode="scaleToFill" simulatedAppContext="notificationCenter" id="S3S-Oj-5AN">
18+
<rect key="frame" x="0.0" y="0.0" width="320" height="320"/>
19+
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
20+
<subviews>
21+
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DB6-PI-dP3">
22+
<rect key="frame" x="48" y="96" width="232" height="128"/>
23+
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
24+
</imageView>
25+
</subviews>
26+
<color key="backgroundColor" red="0.45882353186607361" green="0.74901962280273438" blue="0.66666668653488159" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
27+
<viewLayoutGuide key="safeArea" id="2BE-c3-nQJ"/>
28+
</view>
29+
<extendedEdge key="edgesForExtendedLayout"/>
30+
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
31+
<size key="freeformSize" width="320" height="320"/>
32+
<connections>
33+
<outlet property="imageView" destination="DB6-PI-dP3" id="eTN-zO-McA"/>
34+
</connections>
35+
</viewController>
36+
<placeholder placeholderIdentifier="IBFirstResponder" id="vXp-U4-Rya" userLabel="First Responder" sceneMemberID="firstResponder"/>
37+
</objects>
38+
<point key="canvasLocation" x="137.68115942028987" y="85.714285714285708"/>
39+
</scene>
40+
</scenes>
41+
</document>
+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>CFBundleDevelopmentRegion</key>
6+
<string>$(DEVELOPMENT_LANGUAGE)</string>
7+
<key>CFBundleDisplayName</key>
8+
<string>NotificationsContentExtention</string>
9+
<key>CFBundleExecutable</key>
10+
<string>$(EXECUTABLE_NAME)</string>
11+
<key>CFBundleIdentifier</key>
12+
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
13+
<key>CFBundleInfoDictionaryVersion</key>
14+
<string>6.0</string>
15+
<key>CFBundleName</key>
16+
<string>$(PRODUCT_NAME)</string>
17+
<key>CFBundlePackageType</key>
18+
<string>XPC!</string>
19+
<key>CFBundleShortVersionString</key>
20+
<string>$(MARKETING_VERSION)</string>
21+
<key>CFBundleVersion</key>
22+
<string>$(CURRENT_PROJECT_VERSION)</string>
23+
<key>NSExtension</key>
24+
<dict>
25+
<key>NSExtensionAttributes</key>
26+
<dict>
27+
<key>UNNotificationExtensionCategory</key>
28+
<array>
29+
<string>image</string>
30+
</array>
31+
<key>UNNotificationExtensionDefaultContentHidden</key>
32+
<true/>
33+
<key>UNNotificationExtensionInitialContentSizeRatio</key>
34+
<integer>0</integer>
35+
</dict>
36+
<key>NSExtensionMainStoryboard</key>
37+
<string>MainInterface</string>
38+
<key>NSExtensionPointIdentifier</key>
39+
<string>com.apple.usernotifications.content-extension</string>
40+
</dict>
41+
</dict>
42+
</plist>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//
2+
// NotificationViewController.swift
3+
// NotificationsContentExtention
4+
//
5+
// Created by Naman Jain on 10/09/19.
6+
// Copyright © 2019 Naman Jain. All rights reserved.
7+
//
8+
9+
import UIKit
10+
import UserNotifications
11+
import UserNotificationsUI
12+
13+
class NotificationViewController: UIViewController, UNNotificationContentExtension {
14+
15+
@IBOutlet weak var imageView: UIImageView!
16+
17+
18+
override func viewDidLoad() {
19+
super.viewDidLoad()
20+
// Do any required interface initialization here.
21+
}
22+
23+
func didReceive(_ notification: UNNotification) {
24+
let attachments = notification.request.content.attachments
25+
for attachment in attachments{
26+
if attachment.identifier == "picture" {
27+
guard let data = try? Data(contentsOf: attachment.url) else { return }
28+
imageView.image = UIImage(data: data)
29+
}
30+
}
31+
}
32+
33+
}

0 commit comments

Comments
 (0)