about summary refs log tree commit diff
path: root/modules/expo-background-notification-handler/ios/ExpoBackgroundNotificationHandlerModule.swift
blob: 3845fe765cc40e11fb379534b8fe32031a2a9807 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import ExpoModulesCore

let APP_GROUP = "group.app.bsky"

let DEFAULTS: [String: Any] = [
  "playSoundChat": true,
  "playSoundFollow": false,
  "playSoundLike": false,
  "playSoundMention": false,
  "playSoundQuote": false,
  "playSoundReply": false,
  "playSoundRepost": false,
  "mutedThreads": [:] as! [String: [String]],
  "badgeCount": 0
]

/*
 * The purpose of this module is to store values that are needed by the notification service
 * extension. Since we would rather get and store values such as age or user mute state
 * while the app is foregrounded, we should use this module liberally. We should aim to keep
 * background fetches to a minimum (two or three times per hour) while the app is backgrounded
 * or killed
 */
public class ExpoBackgroundNotificationHandlerModule: Module {
  let userDefaults = UserDefaults(suiteName: APP_GROUP)

  public func definition() -> ModuleDefinition {
    Name("ExpoBackgroundNotificationHandler")

    OnCreate {
      DEFAULTS.forEach { p in
        if userDefaults?.value(forKey: p.key) == nil {
          userDefaults?.setValue(p.value, forKey: p.key)
        }
      }
    }

    AsyncFunction("getAllPrefsAsync") { () -> [String: Any]? in
      var keys: [String] = []
      DEFAULTS.forEach { p in
        keys.append(p.key)
      }
      return userDefaults?.dictionaryWithValues(forKeys: keys)
    }

    AsyncFunction("getBoolAsync") { (forKey: String) -> Bool in
      if let pref = userDefaults?.bool(forKey: forKey) {
        return pref
      }
      return false
    }

    AsyncFunction("getStringAsync") { (forKey: String) -> String? in
      if let pref = userDefaults?.string(forKey: forKey) {
        return pref
      }
      return nil
    }

    AsyncFunction("getStringArrayAsync") { (forKey: String) -> [String]? in
      if let pref = userDefaults?.stringArray(forKey: forKey) {
        return pref
      }
      return nil
    }

    AsyncFunction("setBoolAsync") { (forKey: String, value: Bool) in
      userDefaults?.setValue(value, forKey: forKey)
    }

    AsyncFunction("setStringAsync") { (forKey: String, value: String) in
      userDefaults?.setValue(value, forKey: forKey)
    }

    AsyncFunction("setStringArrayAsync") { (forKey: String, value: [String]) in
      userDefaults?.setValue(value, forKey: forKey)
    }

    AsyncFunction("addToStringArrayAsync") { (forKey: String, string: String) in
      if var curr = userDefaults?.stringArray(forKey: forKey),
         !curr.contains(string) {
        curr.append(string)
        userDefaults?.setValue(curr, forKey: forKey)
      }
    }

    AsyncFunction("removeFromStringArrayAsync") { (forKey: String, string: String) in
      if var curr = userDefaults?.stringArray(forKey: forKey) {
        curr.removeAll { s in
          return s == string
        }
        userDefaults?.setValue(curr, forKey: forKey)
      }
    }

    AsyncFunction("addManyToStringArrayAsync") { (forKey: String, strings: [String]) in
      if var curr = userDefaults?.stringArray(forKey: forKey) {
        strings.forEach { s in
          if !curr.contains(s) {
            curr.append(s)
          }
        }
        userDefaults?.setValue(curr, forKey: forKey)
      }
    }

    AsyncFunction("removeManyFromStringArrayAsync") { (forKey: String, strings: [String]) in
      if var curr = userDefaults?.stringArray(forKey: forKey) {
        strings.forEach { s in
          curr.removeAll(where: { $0 == s })
        }
        userDefaults?.setValue(curr, forKey: forKey)
      }
    }

    AsyncFunction("setBadgeCountAsync") { (count: Int) in
      userDefaults?.setValue(count, forKey: "badgeCount")
    }
  }
}