Skip to content

Commit

Permalink
Merge pull request #1879 from ably/ECO-4234
Browse files Browse the repository at this point in the history
[ECO-4234] Updates Push Example to include Channels
  • Loading branch information
umair-ably committed Mar 13, 2024
2 parents 5971d7c + 240e927 commit a237cea
Show file tree
Hide file tree
Showing 16 changed files with 397 additions and 41 deletions.
34 changes: 28 additions & 6 deletions Examples/AblyPush/AblyPushExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

/* Begin PBXBuildFile section */
219F937A2A4E0E44007DE767 /* LocationPushEventsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 219F93792A4E0E44007DE767 /* LocationPushEventsView.swift */; };
801880802B87E7BA00A698F0 /* PushButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8018807F2B87E7BA00A698F0 /* PushButton.swift */; };
801880822B87E80D00A698F0 /* StatelessButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 801880812B87E80D00A698F0 /* StatelessButton.swift */; };
801880872B87E8A300A698F0 /* VerticalLabelStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 801880862B87E8A300A698F0 /* VerticalLabelStyle.swift */; };
8405EE8427F0B06800C9E461 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8405EE8327F0B06800C9E461 /* App.swift */; };
8405EE8627F0B06800C9E461 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8405EE8527F0B06800C9E461 /* ContentView.swift */; };
8405EE8827F0B06C00C9E461 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8405EE8727F0B06C00C9E461 /* Assets.xcassets */; };
Expand Down Expand Up @@ -52,6 +55,9 @@
/* Begin PBXFileReference section */
219F93782A4DFE41007DE767 /* AblyLocationPush.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AblyLocationPush.entitlements; sourceTree = "<group>"; };
219F93792A4E0E44007DE767 /* LocationPushEventsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationPushEventsView.swift; sourceTree = "<group>"; };
8018807F2B87E7BA00A698F0 /* PushButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushButton.swift; sourceTree = "<group>"; };
801880812B87E80D00A698F0 /* StatelessButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatelessButton.swift; sourceTree = "<group>"; };
801880862B87E8A300A698F0 /* VerticalLabelStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerticalLabelStyle.swift; sourceTree = "<group>"; };
8405EE8027F0B06800C9E461 /* Ably Push.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Ably Push.app"; sourceTree = BUILT_PRODUCTS_DIR; };
8405EE8327F0B06800C9E461 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
8405EE8527F0B06800C9E461 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -95,6 +101,16 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
801880852B87E86600A698F0 /* Buttons */ = {
isa = PBXGroup;
children = (
801880812B87E80D00A698F0 /* StatelessButton.swift */,
8018807F2B87E7BA00A698F0 /* PushButton.swift */,
801880862B87E8A300A698F0 /* VerticalLabelStyle.swift */,
);
path = Buttons;
sourceTree = "<group>";
};
8405EE7727F0B06800C9E461 = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -122,6 +138,7 @@
8405EE8327F0B06800C9E461 /* App.swift */,
842F124927F0B29D0029692E /* AblyHelper.swift */,
8405EE8527F0B06800C9E461 /* ContentView.swift */,
801880852B87E86600A698F0 /* Buttons */,
219F93792A4E0E44007DE767 /* LocationPushEventsView.swift */,
842F124B27F0BFC10029692E /* Info.plist */,
84E3D1A32A6D886E0081E898 /* InfoLP.plist */,
Expand Down Expand Up @@ -300,7 +317,10 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
801880822B87E80D00A698F0 /* StatelessButton.swift in Sources */,
219F937A2A4E0E44007DE767 /* LocationPushEventsView.swift in Sources */,
801880872B87E8A300A698F0 /* VerticalLabelStyle.swift in Sources */,
801880802B87E7BA00A698F0 /* PushButton.swift in Sources */,
8405EE8627F0B06800C9E461 /* ContentView.swift in Sources */,
842F124A27F0B29D0029692E /* AblyHelper.swift in Sources */,
8405EE8427F0B06800C9E461 /* App.swift in Sources */,
Expand Down Expand Up @@ -458,10 +478,11 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = AblyPushExample/AblyPushExample.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"AblyPushExample/Preview Content\"";
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = XXY98AVDR6;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = AblyPushExample/Info.plist;
Expand Down Expand Up @@ -491,10 +512,11 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = AblyPushExample/AblyPushExample.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"AblyPushExample/Preview Content\"";
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = XXY98AVDR6;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = AblyPushExample/Info.plist;
Expand Down Expand Up @@ -526,7 +548,7 @@
CODE_SIGN_ENTITLEMENTS = AblyLocationPush/AblyLocationPush.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = XXY98AVDR6;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = AblyLocationPush/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = AblyLocationPush;
Expand Down Expand Up @@ -554,7 +576,7 @@
CODE_SIGN_ENTITLEMENTS = AblyLocationPush/AblyLocationPush.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = XXY98AVDR6;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = AblyLocationPush/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = AblyLocationPush;
Expand Down Expand Up @@ -585,7 +607,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"AblyPushExample/Preview Content\"";
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = XXY98AVDR6;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = AblyPushExample/InfoLP.plist;
Expand Down Expand Up @@ -621,7 +643,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"AblyPushExample/Preview Content\"";
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = XXY98AVDR6;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = AblyPushExample/InfoLP.plist;
Expand Down
75 changes: 74 additions & 1 deletion Examples/AblyPush/AblyPushExample/AblyHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Ably
import UIKit
import CoreLocation

class AblyHelper: NSObject {
class AblyHelper: NSObject, ObservableObject {

static let shared = AblyHelper()

Expand All @@ -18,6 +18,10 @@ class AblyHelper: NSObject {

var activatePushCallback: ((String?, String?, ARTErrorInfo?) -> ())?

@Published var isSubscribedToExampleChannel1 = false
@Published var isSubscribedToExampleChannel2 = false
@Published var isPushActivated = false

private override init() {
super.init()
guard key != "" else {
Expand Down Expand Up @@ -87,6 +91,64 @@ extension AblyHelper {
print("Publish result: \(error?.localizedDescription ?? "Success")")
}
}

func sendPushToChannel(_ channel: Channel) {
let message = ARTMessage(name: "example", data: "rest data")
message.extras = [
"push": [
"notification": [
"title": "Channel Push",
"body": "Sent push to \(channel.rawValue)"
],
"data": [
"foo": "bar",
"baz": "qux"
]
]
] as any ARTJsonCompatible

realtime.channels.get(channel.rawValue).publish([message]) { error in
if let error {
print("Error sending push to \(channel.rawValue) with error: \(error.localizedDescription)")
} else {
print("Sent push to \(channel.rawValue)")
}
}
}

func subscribeToChannel(_ channel: Channel) {
realtime.channels.get(channel.rawValue).push.subscribeDevice { error in
guard error == nil else {
print("Error subscribing to \(channel.rawValue) with error: \(error!.localizedDescription)")
return
}
print("Succesfully subscribed to \(channel.rawValue)")

switch channel {
case .exampleChannel1:
self.isSubscribedToExampleChannel1 = true
case .exampleChannel2:
self.isSubscribedToExampleChannel2 = true
}
}
}

func unsubscribeFromChannel(_ channel: Channel) {
realtime.channels.get(channel.rawValue).push.unsubscribeDevice { error in
guard error == nil else {
print("Error subscribing to \(channel.rawValue) with error: \(error!.localizedDescription)")
return
}

print("Succesfully unsubscribed from \(channel.rawValue)")
switch channel {
case .exampleChannel1:
self.isSubscribedToExampleChannel1 = false
case .exampleChannel2:
self.isSubscribedToExampleChannel2 = false
}
}
}
}

extension AblyHelper: ARTPushRegistererDelegate {
Expand All @@ -95,10 +157,16 @@ extension AblyHelper: ARTPushRegistererDelegate {
print("Push activation: \(error?.localizedDescription ?? "Success")")
activatePushCallback?(defaultDeviceToken, locationDeviceToken, error)
activateLocationPush()
if error == nil {
isPushActivated = true
}
}

func didDeactivateAblyPush(_ error: ARTErrorInfo?) {
print("Push deactivation: \(error?.localizedDescription ?? "Success")")
if error == nil {
isPushActivated = false
}
}

func didUpdateAblyPush(_ error: ARTErrorInfo?) {
Expand Down Expand Up @@ -141,3 +209,8 @@ extension AblyHelper : CLLocationManagerDelegate {
}
}
}

enum Channel: String {
case exampleChannel1
case exampleChannel2
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"images" : [
{
"filename" : "ably-brand-light-mode 1.pdf",
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"filename" : "ably-brand-light-mode.pdf",
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "ably-brand-dark-mode.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "push-disabled.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "push-enabled.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.
52 changes: 52 additions & 0 deletions Examples/AblyPush/AblyPushExample/Buttons/PushButton.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import SwiftUI

struct PushButton: View {
let systemImage: String
let activeTitle: String
let inactiveTitle: String
let action: () -> Void
let isButtonEnabled: Bool // is the button enabled
let isActive: Bool // is the action in it's on or off state

let activeColor = Color(red: 1.00, green: 0.33, blue: 0.09)
let inActiveColor = Color(red: 0.00, green: 0.56, blue: 0.02)

init(
isButtonEnabled: Bool,
systemImage: String,
activeTitle: String,
inactiveTitle: String,
isActive: Bool,
action: @escaping () -> Void
) {
self.isButtonEnabled = isButtonEnabled
self.systemImage = systemImage
self.activeTitle = activeTitle
self.inactiveTitle = inactiveTitle
self.isActive = isActive
self.action = action
}

var body: some View {
let button = Button {
action() // manage the toggling of isActive binding within the action.
} label: {
Label(isActive ? activeTitle : inactiveTitle,
systemImage: systemImage)
.frame(maxWidth: .infinity)
.labelStyle(VerticalLabelStyle())
.padding(EdgeInsets(top: 8, leading: 0, bottom: 8, trailing: 0))
}
.buttonStyle(.borderedProminent)
.buttonBorderShape(.roundedRectangle)
.tint(isActive ? activeColor : inActiveColor)
.disabled(!isButtonEnabled)
.animation(.easeInOut, value: isButtonEnabled)

if #available(iOS 17.0, *) {
return button.contentTransition(.symbolEffect(.replace))
}

return button
}
}
48 changes: 48 additions & 0 deletions Examples/AblyPush/AblyPushExample/Buttons/StatelessButton.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import SwiftUI

struct StatelessButton: View {
let isButtonEnabled: Bool
let systemImage: String
let title: String
let backgroundColor: Color
let action: () -> Void

@State var taps: Int = 0 // purely to trigger animation on every tap

init(
isButtonEnabled: Bool,
systemImage: String,
title: String,
backgroundColor: Color = Color(red: 0.00, green: 0.56, blue: 0.02),
action: @escaping () -> Void
) {
self.isButtonEnabled = isButtonEnabled
self.systemImage = systemImage
self.title = title
self.backgroundColor = backgroundColor
self.action = action
}

var body: some View {
let button = Button {
action()
taps += 1
} label: {
Label(title, systemImage: systemImage)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.labelStyle(VerticalLabelStyle())
.padding(EdgeInsets(top: 8, leading: 0, bottom: 8, trailing: 0))
}
.buttonStyle(.bordered)
.buttonBorderShape(.roundedRectangle)
.tint(backgroundColor)
.disabled(!isButtonEnabled)
.animation(.easeInOut, value: isButtonEnabled)

if #available(iOS 17.0, *) {
return button.symbolEffect(.bounce.down, value: taps)
}

return button
}
}

0 comments on commit a237cea

Please sign in to comment.