Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HTML support to title and message fields #43

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
Change Log
==========
Version 0.3.0 (5 October, 2024)
-----------------------------------------------
- Added support for bold, italic, underline, and strikethrough HTML tags in title and message for rich push notifications.

Version 0.2.7 (17 April, 2024)
-----------------------------------------------
- Fixes a build error related to privacy manifests when statically linking the SDK using Cocoapods.
Expand Down
2 changes: 1 addition & 1 deletion CTNotificationContent.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "CTNotificationContent"
s.version = "0.2.7"
s.version = "0.3.0"
s.summary = "A Notification Content Extension class to display custom content interfaces for iOS 10 push notifications"
s.homepage = "https://github.com/CleverTap/CTNotificationContent"
s.license = "MIT"
Expand Down
4 changes: 4 additions & 0 deletions CTNotificationContent.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
0B0115BE2CAFFD8C00985815 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B0115BD2CAFFD8900985815 /* Extensions.swift */; };
3270BFDA28E4D80E003528ED /* CTProductDisplayVerticalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3270BFD328E4D80E003528ED /* CTProductDisplayVerticalViewController.swift */; };
3270BFDB28E4D80E003528ED /* CTProductDisplayLinearViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3270BFD428E4D80E003528ED /* CTProductDisplayLinearViewController.swift */; };
3270BFDC28E4D80E003528ED /* ProductDisplayProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3270BFD628E4D80E003528ED /* ProductDisplayProperties.swift */; };
Expand Down Expand Up @@ -46,6 +47,7 @@
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
0B0115BD2CAFFD8900985815 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = "<group>"; };
3270BFD328E4D80E003528ED /* CTProductDisplayVerticalViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CTProductDisplayVerticalViewController.swift; sourceTree = "<group>"; };
3270BFD428E4D80E003528ED /* CTProductDisplayLinearViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CTProductDisplayLinearViewController.swift; sourceTree = "<group>"; };
3270BFD628E4D80E003528ED /* ProductDisplayProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProductDisplayProperties.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -304,6 +306,7 @@
32DFD84328BCCCBB00E72588 /* Utility */ = {
isa = PBXGroup;
children = (
0B0115BD2CAFFD8900985815 /* Extensions.swift */,
32DFD84428BCCCBB00E72588 /* GlobalConstants.swift */,
32DFD84528BCCCBB00E72588 /* CTUtility.swift */,
);
Expand Down Expand Up @@ -484,6 +487,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0B0115BE2CAFFD8C00985815 /* Extensions.swift in Sources */,
488F31AF2817000200AE3AC8 /* CTCaptionedImageView.swift in Sources */,
32C575EE28F744E600BF0A3F /* CTRatingsViewController.swift in Sources */,
32DFD85128BCCCBB00E72588 /* CTUtility.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,24 +61,24 @@ import UserNotificationsUI
switch sender.view?.tag{
case 1:
self.bigImageView.image = smallImageBtn1.image
self.titleLabel.text = jsonContent?.pt_bt1
self.subTitleLabel.text = jsonContent?.pt_st1
self.titleLabel.setHTMLText(jsonContent?.pt_bt1 ?? "")
self.subTitleLabel.setHTMLText(jsonContent?.pt_st1 ?? "")
let priceText = "₹ " + (jsonContent?.pt_price1 ?? "")
self.priceLabel.text = priceText
self.deeplink = jsonContent?.pt_dl1 ?? ""
break
case 2:
self.bigImageView.image = smallImageBtn2.image
self.titleLabel.text = jsonContent?.pt_bt2
self.titleLabel.setHTMLText(jsonContent?.pt_bt2 ?? "")
let priceText = "₹ " + (jsonContent?.pt_price2 ?? "")
self.priceLabel.text = priceText
self.subTitleLabel.text = jsonContent?.pt_st2
self.subTitleLabel.setHTMLText(jsonContent?.pt_st2 ?? "")
self.deeplink = jsonContent?.pt_dl2 ?? ""
break
case 3:
self.bigImageView.image = smallImageBtn3.image
self.titleLabel.text = jsonContent?.pt_bt3
self.subTitleLabel.text = jsonContent?.pt_st3
self.titleLabel.setHTMLText(jsonContent?.pt_bt3 ?? "")
self.subTitleLabel.setHTMLText(jsonContent?.pt_st3 ?? "")
let priceText = "₹ " + (jsonContent?.pt_price3 ?? "")
self.priceLabel.text = priceText
self.deeplink = jsonContent?.pt_dl3 ?? ""
Expand All @@ -100,8 +100,8 @@ import UserNotificationsUI
preferredContentSize = CGSize(width: viewWidth, height: viewHeight)

self.deeplink = jsonContent.pt_dl1
self.titleLabel.text = jsonContent.pt_bt1
self.subTitleLabel.text = jsonContent.pt_st1
self.titleLabel.setHTMLText(jsonContent.pt_bt1)
self.subTitleLabel.setHTMLText(jsonContent.pt_st1)

CTUtiltiy.checkImageUrlValid(imageUrl: jsonContent.pt_img1) { [weak self] (imageData) in
DispatchQueue.main.async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,8 @@ import UIKit
templateBigImage = bigImage
}

self.titleLabel.text = templateCaption
self.subTitleLabel.text = templateSubcaption
self.titleLabel.setHTMLText(templateCaption)
self.subTitleLabel.setHTMLText(templateSubcaption)

if let bigImg = jsonContent.pt_big_img{
CTUtiltiy.checkImageUrlValid(imageUrl: bigImg) { [weak self] (imageData) in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,8 @@ import AVFoundation
func createBasicCaptionView() {
contentView.addSubview(captionLabel)
contentView.addSubview(subcaptionLabel)
captionLabel.text = caption
subcaptionLabel.text = subCaption
captionLabel.setHTMLText(caption)
subcaptionLabel.setHTMLText(subCaption)

NSLayoutConstraint.activate([
captionLabel.topAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -(CTUtiltiy.getCaptionHeight() - Constraints.kCaptionTopPadding)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ import UserNotificationsUI
contentView.addSubview(subcaptionLabel)
contentView.addSubview(timerLabel)

captionLabel.text = templateCaption
subcaptionLabel.text = templateSubcaption
captionLabel.setHTMLText(templateCaption)
subcaptionLabel.setHTMLText(templateSubcaption)

guard let jsonContent = jsonContent else {
return
Expand All @@ -91,13 +91,13 @@ import UserNotificationsUI
}

if let title = jsonContent.pt_title, !title.isEmpty {
captionLabel.text = title
captionLabel.setHTMLText(title)
}
if let msg = jsonContent.pt_msg, !msg.isEmpty {
subcaptionLabel.text = msg
subcaptionLabel.setHTMLText(msg)
}
if let msgSummary = jsonContent.pt_msg_summary, !msgSummary.isEmpty {
subcaptionLabel.text = msgSummary
subcaptionLabel.setHTMLText(msgSummary)
}
if let bg = jsonContent.pt_bg, !bg.isEmpty {
bgColor = bg
Expand Down Expand Up @@ -179,10 +179,10 @@ import UserNotificationsUI
func updateViewForExpiredTime() {
if let jsonContent = jsonContent {
if let title = jsonContent.pt_title_alt, !title.isEmpty {
captionLabel.text = title
captionLabel.setHTMLText(title)
}
if let msg = jsonContent.pt_msg_alt, !msg.isEmpty {
subcaptionLabel.text = msg
subcaptionLabel.setHTMLText(msg)
}
if let altImage = jsonContent.pt_big_img_alt, !altImage.isEmpty {
// Load expired image, if available.
Expand Down
26 changes: 26 additions & 0 deletions CTNotificationContent/Templates/Utility/Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Extensions.swift
// CTNotificationContent
//
// Created by Kushagra Mishra on 04/10/24.
// Copyright © 2024 CleverTap. All rights reserved.
//
import Foundation
import UIKit

extension UILabel {
func setHTMLText(_ htmlText: String) {
let modifiedFont = NSString(format: "<span style=\"font-family: '-apple-system', 'HelveticaNeue'; font-size: \(self.font!.pointSize)\">%@</span>" as NSString, htmlText) as String
guard let data = modifiedFont.data(using: .unicode) else { return }
do {
let attributedString = try NSAttributedString(data: data,
options: [.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue],
documentAttributes: nil)
self.attributedText = attributedString
} catch {
print("Error setting HTML text: \\(error.localizedDescription)")
self.text = htmlText
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ import UIKit
templateBigImage = bigImage
}

self.titleLabel.text = templateCaption
self.subTitleLabel.text = templateSubcaption
self.titleLabel.setHTMLText(templateCaption)
self.subTitleLabel.setHTMLText(templateSubcaption)

if let bigImg = jsonContent.pt_big_img{
CTUtiltiy.checkImageUrlValid(imageUrl: bigImg) { [weak self] (imageData) in
Expand Down
4 changes: 2 additions & 2 deletions CTNotificationContent/Views/CTCaptionedImageView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ class CTCaptionedImageView : UIView {
}
}
}
captionLabel.text = components.caption
subcaptionLabel.text = components.subcaption
captionLabel.setHTMLText(components.caption)
subcaptionLabel.setHTMLText(components.subcaption)
captionLabel.textColor = UIColor(hex: components.captionColor)
subcaptionLabel.textColor = UIColor(hex: components.subcaptionColor)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 52;
objectVersion = 54;
objects = {

/* Begin PBXBuildFile section */
Expand Down Expand Up @@ -693,7 +693,7 @@
repositoryURL = "https://github.com/CleverTap/clevertap-ios-sdk.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 3.10.0;
minimumVersion = 7.0.1;
};
};
496ED95227589CCC002174B7 /* XCRemoteSwiftPackageReference "CTNotificationService" */ = {
Expand All @@ -709,7 +709,7 @@
repositoryURL = "https://github.com/CleverTap/CTNotificationContent.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 0.2.0;
minimumVersion = 0.0.1;
};
};
/* End XCRemoteSwiftPackageReference section */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1600"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
buildArchitectures = "Automatic">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "496ED91027589B88002174B7"
BuildableName = "CTNotificationContentExampleSPM.app"
BlueprintName = "CTNotificationContentExampleSPM"
ReferencedContainer = "container:CTNotificationContentExampleSPM.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "496ED91027589B88002174B7"
BuildableName = "CTNotificationContentExampleSPM.app"
BlueprintName = "CTNotificationContentExampleSPM"
ReferencedContainer = "container:CTNotificationContentExampleSPM.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "496ED91027589B88002174B7"
BuildableName = "CTNotificationContentExampleSPM.app"
BlueprintName = "CTNotificationContentExampleSPM"
ReferencedContainer = "container:CTNotificationContentExampleSPM.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
Loading