refactor: deintegrate cocoapods and switch NSE to dynamic sqlcipher

This commit is contained in:
Christian Kußowski committed 2026-10-08 07:58:12 +02:00
1 parent 6914c2323e
commit dda7ab1a42
11 files changed
+435 -449

No files matched your search

-1
View File
@@ -1,2 +1 @@
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
-1
View File
@@ -1,2 +1 @@
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
@@ -5,7 +5,6 @@
// Created by Christian Pauly on 26.08.25.
//
import FMDB
import Foundation
import UserNotifications
import os
@@ -74,21 +73,14 @@ class NotificationService: UNNotificationServiceExtension {
),
let clientName = devices.first?.data.client_name
else {
os_log(
"[FluffyChatPushHelper] No client_name found in Push Notification!"
)
bestAttemptContent.userInfo["error"] = "No client_name found in Push Notification!"
contentHandler(bestAttemptContent)
return
}
bestAttemptContent.threadIdentifier = "\(clientName)_\(roomId)"
// Open database:
guard let key = getDatabaseKey() else {
os_log("[FluffyChatPushHelper] Unable to get database key!")
contentHandler(bestAttemptContent)
return
}
// Create database path:
guard let containerPath = FileManager.default.containerURL(
forSecurityApplicationGroupIdentifier: "group.im.fluffychat.app"
) else {
@@ -97,9 +89,14 @@ class NotificationService: UNNotificationServiceExtension {
return
}
let databasePath = containerPath.appendingPathComponent("\(clientName).sqlite").path
guard let database = getDatabase(key: key, path: databasePath) else {
// getDatabase already logged the concrete SQLite error
os_log("[FluffyChatPushHelper] Unable to open database!")
// Open database:
let database: SqlCipherDatabase
do {
database = try getDatabase(path: databasePath)
} catch {
os_log("[FluffyChatPushHelper] Unable to open database: %{public}@", type: .error, String(describing: error))
bestAttemptContent.userInfo["error"] = String(describing: error)
contentHandler(bestAttemptContent)
return
}
@@ -139,7 +136,7 @@ class NotificationService: UNNotificationServiceExtension {
}
if let roomAvatarUrl = roomAvatarUrl {
bestAttemptContent.userInfo["room_avatar"] = roomName
bestAttemptContent.userInfo["room_avatar"] = roomAvatarUrl
do {
let attachment = try downloadAttachment(url: roomAvatarUrl, containerPath: containerPath)
bestAttemptContent.attachments = [attachment]
@@ -149,7 +146,6 @@ class NotificationService: UNNotificationServiceExtension {
}
contentHandler(bestAttemptContent)
database.close()
}
override func serviceExtensionTimeWillExpire() {
@@ -162,7 +158,7 @@ class NotificationService: UNNotificationServiceExtension {
}
}
func getDatabaseKey() -> String? {
func getDatabase(path: String) throws -> SqlCipherDatabase {
// Fetch database key
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
@@ -179,183 +175,100 @@ class NotificationService: UNNotificationServiceExtension {
let data = item as? Data,
let key = String(data: data, encoding: .utf8)
else {
return nil
throw DatabaseKeyError.keychain(status)
}
return key
}
func getDatabase(key: String, path: String) -> FMDatabase? {
guard FileManager.default.fileExists(atPath: path) else { return nil }
let database = FMDatabase(path: "file:\(path)?immutable=1")
// Open Database in read only mode:
guard database.open(withFlags: 0x0000_0001) else {
os_log(
"[FluffyChatPushHelper] sqlite open failed: %{public}@",
database.lastErrorMessage()
)
return nil
}
// Match Flutter / matrix-dart-sdk: PRAGMA KEY='…' (passphrase), not raw key bytes.
let escapedKey = key.replacingOccurrences(of: "'", with: "''")
guard database.executeStatements("PRAGMA key = '\(escapedKey)';") else {
os_log(
"[FluffyChatPushHelper] PRAGMA key failed: %{public}@",
database.lastErrorMessage()
)
database.close()
return nil
}
guard database.goodConnection else {
os_log(
"[FluffyChatPushHelper] bad connection after key: %{public}@",
database.lastErrorMessage()
)
database.close()
return nil
}
return database
return try SqlCipherDatabase.open(path: path, key: key)
}
func getUserFromDatabase(
database: FMDatabase,
database: SqlCipherDatabase,
userId: String,
roomId: String
) -> UserEventJson? {
do {
let roomMemberDatabaseKey = [roomId, userId].joined(separator: "|")
let roomMemberResult = try database.executeQuery(
"SELECT * FROM box_room_members WHERE k=?",
values: [roomMemberDatabaseKey]
)
if roomMemberResult.next(),
let event = roomMemberResult.string(forColumn: "v")
{
let userEvent = try! JSONDecoder().decode(
UserEventJson.self,
from: event.data(using: .utf8)!
)
return userEvent
}
} catch {
os_log(
"[FluffyChatPushHelper] DB query failed: %{public}@",
log: .default,
type: .error,
error.localizedDescription
)
let roomMemberDatabaseKey = [roomId, userId].joined(separator: "|")
guard let event = try? database.scalar(
query: "SELECT v FROM box_room_members WHERE k=?",
args: [roomMemberDatabaseKey]
) else {
return nil
}
return nil
return try? JSONDecoder().decode(
UserEventJson.self,
from: Data(event.utf8),
)
}
func getRoomAvatarFromDatabase(database: FMDatabase, roomId: String)
func getRoomAvatarFromDatabase(database: SqlCipherDatabase, roomId: String)
-> String?
{
do {
// Database key format: "roomId|eventType|stateKey"
let roomAvatarDatabaseKey = [roomId, "m.room.avatar", ""].joined(
separator: "|"
)
let roomAvatarResult = try database.executeQuery(
"SELECT * FROM box_preload_room_states WHERE k=?",
values: [roomAvatarDatabaseKey]
)
if roomAvatarResult.next(),
let event = roomAvatarResult.string(forColumn: "v")
{
let roomAvatarEvent = try! JSONDecoder().decode(
RoomAvatarEventJson.self,
from: event.data(using: .utf8)!
)
if let avatarUrl = roomAvatarEvent.content.url, !avatarUrl.isEmpty {
return avatarUrl
}
}
} catch {
os_log(
"[FluffyChatPushHelper] DB query failed: %{public}@",
log: .default,
type: .error,
error.localizedDescription
)
// Database key format: "roomId|eventType|stateKey"
let roomAvatarDatabaseKey = [roomId, "m.room.avatar", ""].joined(
separator: "|"
)
guard let event = try? database.scalar(
query: "SELECT v FROM box_preload_room_states WHERE k=?",
args: [roomAvatarDatabaseKey]
) else {
return nil
}
let roomAvatarEvent = try? JSONDecoder().decode(
RoomAvatarEventJson.self,
from: event.data(using: .utf8)!
)
if let avatarUrl = roomAvatarEvent?.content.url, !avatarUrl.isEmpty {
return avatarUrl
}
return nil
}
func getRoomNameFromDatabase(database: FMDatabase, roomId: String)
func getRoomNameFromDatabase(database: SqlCipherDatabase, roomId: String)
-> String?
{
do {
// Database key format: "roomId|eventType|stateKey"
let roomNameDatabaseKey = [roomId, "m.room.name", ""].joined(
separator: "|"
)
let roomNameResult = try database.executeQuery(
"SELECT * FROM box_preload_room_states WHERE k=?",
values: [roomNameDatabaseKey]
)
if roomNameResult.next(),
let event = roomNameResult.string(forColumn: "v")
{
let roomNameEvent = try! JSONDecoder().decode(
RoomNameEventJson.self,
from: event.data(using: .utf8)!
)
if let name = roomNameEvent.content.name, !name.isEmpty {
return name
}
}
} catch {
os_log(
"[FluffyChatPushHelper] DB query failed: %{public}@",
log: .default,
type: .error,
error.localizedDescription
)
// Database key format: "roomId|eventType|stateKey"
let roomNameDatabaseKey = [roomId, "m.room.name", ""].joined(
separator: "|"
)
guard let event = try? database.scalar(
query: "SELECT v FROM box_preload_room_states WHERE k=?",
args: [roomNameDatabaseKey]
) else {
return nil
}
let roomNameEvent = try? JSONDecoder().decode(
RoomNameEventJson.self,
from: event.data(using: .utf8)!
)
if let name = roomNameEvent?.content.name, !name.isEmpty {
return name
}
return nil
}
func getRoomheroesFromDatabase(database: FMDatabase, roomId: String)
func getRoomheroesFromDatabase(database: SqlCipherDatabase, roomId: String)
-> [UserEventJson]?
{
do {
let roomResult = try database.executeQuery(
"SELECT * FROM box_rooms WHERE k=?",
values: [roomId]
)
if roomResult.next(),
let roomJson = roomResult.string(forColumn: "v")
{
let room = try JSONDecoder().decode(
RoomJson.self,
from: roomJson.data(using: .utf8)!
)
let heroes = room.summary.heroes.map { hero in
return getUserFromDatabase(
database: database,
userId: hero,
roomId: roomId
)
}.compactMap { $0 }
return heroes
} else {
return nil
}
} catch is DecodingError {
return []
} catch {
os_log(
"[FluffyChatPushHelper] DB query failed: %{public}@",
log: .default,
type: .error,
error.localizedDescription
)
guard let event = try? database.scalar(
query: "SELECT v FROM box_rooms WHERE k=?",
args: [roomId]
) else {
return nil
}
return []
let room = try? JSONDecoder().decode(
RoomJson.self,
from: event.data(using: .utf8)!
)
let heroes = room?.summary.heroes.map { hero in
return getUserFromDatabase(
database: database,
userId: hero,
roomId: roomId
)
}.compactMap { $0 }
return heroes
}
func downloadAttachment(url: String, containerPath: URL) throws -> UNNotificationAttachment {
@@ -416,3 +329,5 @@ struct NotificationDevice: Decodable {
struct NotificationCounts: Decodable {
let unread: Int?
}
enum DatabaseKeyError: Error { case keychain(OSStatus), invalidData }
@@ -0,0 +1,111 @@
//
// SqlCipherDatabase.swift
// Runner
//
// Created by Christian Kußowski on 07.10.26.
//
import Foundation
final class SqlCipherDatabase {
private let handle: UnsafeMutableRawPointer
private let dbPointer: OpaquePointer
private var isClosed = false
private init(handle: UnsafeMutableRawPointer, dbPointer: OpaquePointer) {
self.handle = handle
self.dbPointer = dbPointer
}
static func open(path: String, key: String) throws -> SqlCipherDatabase {
let libURL = Bundle.main.bundleURL.deletingLastPathComponent().deletingLastPathComponent().appendingPathComponent("Frameworks/sqlcipher.framework/sqlcipher")
guard let handle = dlopen(libURL.path, RTLD_NOW) else {
throw SqlCipherError.libraryNotLoaded(dlerror().map { String(cString: $0) } ?? "unknown dlopen error")
}
let openV2 = try symbol(handle, "sqlite3_open_v2", as: OpenV2Fn.self)
var dbPointer: OpaquePointer?
let rc = openV2(path, &dbPointer, SQLITE_OPEN_READONLY, nil)
guard rc == SQLITE_OK, let dbPointer = dbPointer else {
throw SqlCipherError.sqlite(code: rc, message: "Failed to open")
}
let database = SqlCipherDatabase(handle: handle, dbPointer: dbPointer)
_ = try database.execute(query: "PRAGMA key = '\(key)'")
_ = try database.execute(query: "SELECT count(*) FROM sqlite_master")
return database
}
func scalar(query: String, args: [String] = []) throws -> String? {
try execute(query: query, args: args).first?.first ?? nil
}
func execute(query: String, args: [String] = []) throws -> [[String?]] {
guard !isClosed else { throw SqlCipherError.sqlite(code: Self.SQLITE_MISUSE, message: "Database is closed") }
let prepareV2 = try Self.symbol(handle, "sqlite3_prepare_v2", as: PrepareV2Fn.self)
let bindText = try Self.symbol(handle, "sqlite3_bind_text", as: BindTextFn.self)
let step = try Self.symbol(handle, "sqlite3_step", as: StepFn.self)
let columnCountFn = try Self.symbol(handle, "sqlite3_column_count", as: ColumnCountFn.self)
let columnText = try Self.symbol(handle, "sqlite3_column_text", as: ColumnTextFn.self)
let finalize = try Self.symbol(handle, "sqlite3_finalize", as: FinalizeFn.self)
let errmsg = try Self.symbol(handle, "sqlite3_errmsg", as: ErrmsgFn.self)
let fail = { (rc: Int32) in SqlCipherError.sqlite(code: rc, message: errmsg(self.dbPointer).map { String(cString: $0) } ?? "unknown error") }
var stmt: OpaquePointer?
let rc = prepareV2(dbPointer, query, -1, &stmt, nil)
guard rc == Self.SQLITE_OK, let stmt = stmt else { throw fail(rc) }
defer { _ = finalize(stmt) }
for (index, arg) in args.enumerated() {
let rc = bindText(stmt, Int32(index + 1), arg, -1, Self.SQLITE_TRANSIENT)
guard rc == Self.SQLITE_OK else { throw fail(rc) }
}
let columnCount = columnCountFn(stmt)
var rows: [[String?]] = []
var stepRc = step(stmt)
while stepRc == Self.SQLITE_ROW {
rows.append((0..<columnCount).map { columnText(stmt, $0).map { String(cString: $0) } })
stepRc = step(stmt)
}
guard stepRc == Self.SQLITE_DONE else { throw fail(stepRc) }
return rows
}
func close() throws {
guard !isClosed else { return }
let closeV2 = try Self.symbol(handle, "sqlite3_close_v2", as: CloseV2Fn.self)
let rc = closeV2(dbPointer)
isClosed = true
guard rc == Self.SQLITE_OK else { throw SqlCipherError.sqlite(code: rc, message: "Failed to close") }
}
deinit { try? close() }
private static func symbol<T>(_ handle: UnsafeMutableRawPointer, _ name: String, as type: T.Type) throws -> T {
guard let sym = dlsym(handle, name) else { throw SqlCipherError.symbolNotFound(name) }
return unsafeBitCast(sym, to: type)
}
private typealias OpenV2Fn = @convention(c) (UnsafePointer<CChar>?, UnsafeMutablePointer<OpaquePointer?>?, Int32, UnsafePointer<CChar>?) -> Int32
private typealias CloseV2Fn = @convention(c) (OpaquePointer?) -> Int32
private static let SQLITE_OK: Int32 = 0
private static let SQLITE_MISUSE: Int32 = 21
private static let SQLITE_OPEN_READONLY: Int32 = 1
private static let SQLITE_ROW: Int32 = 100
private static let SQLITE_DONE: Int32 = 101
private static let SQLITE_TRANSIENT: Int = -1
enum SqlCipherError: Error { case libraryNotLoaded(String), symbolNotFound(String), sqlite(code: Int32, message: String) }
private typealias PrepareV2Fn = @convention(c) (OpaquePointer?, UnsafePointer<CChar>?, Int32, UnsafeMutablePointer<OpaquePointer?>?, UnsafeMutablePointer<UnsafePointer<CChar>?>?) -> Int32
private typealias BindTextFn = @convention(c) (OpaquePointer?, Int32, UnsafePointer<CChar>?, Int32, Int) -> Int32
private typealias StepFn = @convention(c) (OpaquePointer?) -> Int32
private typealias ColumnCountFn = @convention(c) (OpaquePointer?) -> Int32
private typealias ColumnTextFn = @convention(c) (OpaquePointer?, Int32) -> UnsafePointer<UInt8>?
private typealias FinalizeFn = @convention(c) (OpaquePointer?) -> Int32
private typealias ErrmsgFn = @convention(c) (OpaquePointer?) -> UnsafePointer<CChar>?
}
-66
View File
@@ -1,66 +0,0 @@
# Uncomment this line to define a global platform for your project
platform :ios, '15.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end
# SQLCipher for the NSE only:
target 'Notification Service Extension' do
use_frameworks! :linkage => :static
use_modular_headers!
pod 'FMDB/SQLCipher'
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
# ensure all dependencies are using SQLCipher instead of SQLite
xcconfig_path = config.base_configuration_reference.real_path
xcconfig = File.read(xcconfig_path)
new_xcconfig = xcconfig.sub(' -l"sqlite3"', '')
File.open(xcconfig_path, "w") { |file| file << new_xcconfig }
config.build_settings['ENABLE_BITCODE'] = 'NO'
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.0'
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
# dart: PermissionGroup.microphone
'PERMISSION_MICROPHONE=1',
]
end
end
flutter_post_install(installer) if defined?(flutter_post_install)
end
+7 -118
View File
@@ -11,11 +11,9 @@
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; };
7E19CFC25FF149C1EB25035F /* Pods_Notification_Service_Extension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4688A2BF4AFDF1CB2B66829A /* Pods_Notification_Service_Extension.framework */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
AB0F2865DE230DE37373E0E0 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50DEFC207B70632D9C56ED78 /* Pods_Runner.framework */; };
C1005C45261071B5002F4F32 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1005C44261071B5002F4F32 /* ShareViewController.swift */; };
C1005C48261071B5002F4F32 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C1005C46261071B5002F4F32 /* MainInterface.storyboard */; };
C1005C4C261071B5002F4F32 /* FluffyChat Share.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = C1005C42261071B5002F4F32 /* FluffyChat Share.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
@@ -73,13 +71,9 @@
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3A645598796C232804C116FE /* Pods-Notification Service Extension.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Notification Service Extension.profile.xcconfig"; path = "Target Support Files/Pods-Notification Service Extension/Pods-Notification Service Extension.profile.xcconfig"; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
4688A2BF4AFDF1CB2B66829A /* Pods_Notification_Service_Extension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Notification_Service_Extension.framework; sourceTree = BUILT_PRODUCTS_DIR; };
50DEFC207B70632D9C56ED78 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
76737C9A857D5FD6D2634A3F /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
@@ -89,7 +83,6 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9DB2F3524376810E74C799A8 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
C1005C42261071B5002F4F32 /* FluffyChat Share.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "FluffyChat Share.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
C1005C44261071B5002F4F32 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = "<group>"; };
C1005C47261071B5002F4F32 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = "<group>"; };
@@ -100,9 +93,6 @@
C14695652E642E450075F2F7 /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = "<group>"; };
C149567B25C7274F00A16396 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
C149567D25C7276200A16396 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
E5089CBCB1AF704A168E41B5 /* Pods-Notification Service Extension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Notification Service Extension.release.xcconfig"; path = "Target Support Files/Pods-Notification Service Extension/Pods-Notification Service Extension.release.xcconfig"; sourceTree = "<group>"; };
EA246783222E02DD03959891 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
F0540869D5C42F400AD7F460 /* Pods-Notification Service Extension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Notification Service Extension.debug.xcconfig"; path = "Target Support Files/Pods-Notification Service Extension/Pods-Notification Service Extension.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
@@ -132,7 +122,6 @@
buildActionMask = 2147483647;
files = (
78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */,
AB0F2865DE230DE37373E0E0 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -148,22 +137,12 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
7E19CFC25FF149C1EB25035F /* Pods_Notification_Service_Extension.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
075EE1BE25359E34308E0B78 /* Frameworks */ = {
isa = PBXGroup;
children = (
50DEFC207B70632D9C56ED78 /* Pods_Runner.framework */,
4688A2BF4AFDF1CB2B66829A /* Pods_Notification_Service_Extension.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
@@ -185,8 +164,7 @@
C1005C43261071B5002F4F32 /* FluffyChat Share */,
C14695532E642D400075F2F7 /* Notification Service Extension */,
97C146EF1CF9000F007C117D /* Products */,
E89DCAC000D371640E94E65B /* Pods */,
075EE1BE25359E34308E0B78 /* Frameworks */,
C107717D3075192600D0BA63 /* Frameworks */,
);
sourceTree = "<group>";
};
@@ -229,17 +207,11 @@
path = "FluffyChat Share";
sourceTree = "<group>";
};
E89DCAC000D371640E94E65B /* Pods */ = {
C107717D3075192600D0BA63 /* Frameworks */ = {
isa = PBXGroup;
children = (
76737C9A857D5FD6D2634A3F /* Pods-Runner.debug.xcconfig */,
EA246783222E02DD03959891 /* Pods-Runner.release.xcconfig */,
9DB2F3524376810E74C799A8 /* Pods-Runner.profile.xcconfig */,
F0540869D5C42F400AD7F460 /* Pods-Notification Service Extension.debug.xcconfig */,
E5089CBCB1AF704A168E41B5 /* Pods-Notification Service Extension.release.xcconfig */,
3A645598796C232804C116FE /* Pods-Notification Service Extension.profile.xcconfig */,
);
path = Pods;
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
@@ -249,14 +221,12 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
8C9CCA7C5C45651F90C7BFDD /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
C1005C4D261071B5002F4F32 /* Embed App Extensions */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
F9C8EE392B9AB471149C306E /* [CP] Embed Pods Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
);
buildRules = (
@@ -297,11 +267,9 @@
isa = PBXNativeTarget;
buildConfigurationList = C146955E2E642D400075F2F7 /* Build configuration list for PBXNativeTarget "Notification Service Extension" */;
buildPhases = (
972C64C37AF8EB03956BFEF5 /* [CP] Check Pods Manifest.lock */,
C146954E2E642D400075F2F7 /* Sources */,
C146954F2E642D400075F2F7 /* Frameworks */,
C14695502E642D400075F2F7 /* Resources */,
254B215AA45F099306397F04 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -311,6 +279,8 @@
C14695532E642D400075F2F7 /* Notification Service Extension */,
);
name = "Notification Service Extension";
packageProductDependencies = (
);
productName = "Notification Service Extension";
productReference = C14695522E642D400075F2F7 /* Notification Service Extension.appex */;
productType = "com.apple.product-type.app-extension";
@@ -347,7 +317,7 @@
);
mainGroup = 97C146E51CF9000F007C117D;
packageReferences = (
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */,
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */,
);
preferredProjectObjectVersion = 77;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
@@ -396,23 +366,6 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
254B215AA45F099306397F04 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Notification Service Extension/Pods-Notification Service Extension-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Notification Service Extension/Pods-Notification Service Extension-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Notification Service Extension/Pods-Notification Service Extension-resources.sh\"\n";
showEnvVarsInLog = 0;
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
@@ -429,50 +382,6 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n";
};
8C9CCA7C5C45651F90C7BFDD /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
972C64C37AF8EB03956BFEF5 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Notification Service Extension-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
@@ -488,23 +397,6 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
};
F9C8EE392B9AB471149C306E /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -948,7 +840,6 @@
};
C146955A2E642D400075F2F7 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = F0540869D5C42F400AD7F460 /* Pods-Notification Service Extension.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
@@ -991,7 +882,6 @@
};
C146955B2E642D400075F2F7 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = E5089CBCB1AF704A168E41B5 /* Pods-Notification Service Extension.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
@@ -1031,7 +921,6 @@
};
C146955C2E642D400075F2F7 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3A645598796C232804C116FE /* Pods-Notification Service Extension.profile.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
@@ -1115,7 +1004,7 @@
/* End XCConfigurationList section */
/* Begin XCLocalSwiftPackageReference section */
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */ = {
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = {
isa = XCLocalSwiftPackageReference;
relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage;
};
@@ -1,5 +1,23 @@
{
"pins" : [
{
"identity" : "abseil-cpp-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/abseil-cpp-binary.git",
"state" : {
"revision" : "bbe8b69694d7873315fd3a4ad41efe043e1c07c5",
"version" : "1.2024072200.0"
}
},
{
"identity" : "app-check",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/app-check.git",
"state" : {
"revision" : "97f7d74dd0e8f3d0fe5fc75cc8957aa73bdc948a",
"version" : "11.3.2"
}
},
{
"identity" : "cryptoswift",
"kind" : "remoteSourceControl",
@@ -8,6 +26,105 @@
"revision" : "f2a627b84c1ff96f21ac2fcb623ab36142dd5512",
"version" : "1.10.0"
}
},
{
"identity" : "firebase-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/firebase-ios-sdk",
"state" : {
"revision" : "27eaab3918e0bf78711cf1abf240577176326432",
"version" : "12.19.0"
}
},
{
"identity" : "google-ads-on-device-conversion-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/googleads/google-ads-on-device-conversion-ios-sdk",
"state" : {
"revision" : "0208e2681ec81f8a9c81084696f60fcce26cb7ee",
"version" : "3.7.0"
}
},
{
"identity" : "googleappmeasurement",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleAppMeasurement.git",
"state" : {
"revision" : "b8455dd2ff55cc269fda7a4f9eac6c1e3588c53f",
"version" : "12.19.2"
}
},
{
"identity" : "googledatatransport",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleDataTransport.git",
"state" : {
"revision" : "ba3358d3c3dbae8ef230b58a46b97ad65e84e974",
"version" : "10.1.1"
}
},
{
"identity" : "googleutilities",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleUtilities.git",
"state" : {
"revision" : "cc31f5ed464b111f877ce8554cbef4455d410d91",
"version" : "8.1.4"
}
},
{
"identity" : "grpc-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/grpc-binary.git",
"state" : {
"revision" : "75b31c842f664a0f46a2e590a570e370249fd8f6",
"version" : "1.69.1"
}
},
{
"identity" : "gtm-session-fetcher",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/gtm-session-fetcher.git",
"state" : {
"revision" : "724a52eea6329b7e12d3ad8300d76ca9f3895fcc",
"version" : "5.3.1"
}
},
{
"identity" : "interop-ios-for-google-sdks",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/interop-ios-for-google-sdks.git",
"state" : {
"revision" : "040d087ac2267d2ddd4cca36c757d1c6a05fdbfe",
"version" : "101.0.0"
}
},
{
"identity" : "leveldb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/leveldb.git",
"state" : {
"revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1",
"version" : "1.22.5"
}
},
{
"identity" : "nanopb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/nanopb.git",
"state" : {
"revision" : "3851d94a41890dea16dc3db34caf60e585cb4163",
"version" : "2.30910.1"
}
},
{
"identity" : "promises",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/promises.git",
"state" : {
"revision" : "f4a19a3c313dc2616c70bb49d29a799fb16be837",
"version" : "2.4.1"
}
}
],
"version" : 2
-3
View File
@@ -4,7 +4,4 @@
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>
@@ -1,5 +1,23 @@
{
"pins" : [
{
"identity" : "abseil-cpp-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/abseil-cpp-binary.git",
"state" : {
"revision" : "bbe8b69694d7873315fd3a4ad41efe043e1c07c5",
"version" : "1.2024072200.0"
}
},
{
"identity" : "app-check",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/app-check.git",
"state" : {
"revision" : "97f7d74dd0e8f3d0fe5fc75cc8957aa73bdc948a",
"version" : "11.3.2"
}
},
{
"identity" : "cryptoswift",
"kind" : "remoteSourceControl",
@@ -8,6 +26,105 @@
"revision" : "f2a627b84c1ff96f21ac2fcb623ab36142dd5512",
"version" : "1.10.0"
}
},
{
"identity" : "firebase-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/firebase-ios-sdk",
"state" : {
"revision" : "27eaab3918e0bf78711cf1abf240577176326432",
"version" : "12.19.0"
}
},
{
"identity" : "google-ads-on-device-conversion-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/googleads/google-ads-on-device-conversion-ios-sdk",
"state" : {
"revision" : "0208e2681ec81f8a9c81084696f60fcce26cb7ee",
"version" : "3.7.0"
}
},
{
"identity" : "googleappmeasurement",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleAppMeasurement.git",
"state" : {
"revision" : "b8455dd2ff55cc269fda7a4f9eac6c1e3588c53f",
"version" : "12.19.2"
}
},
{
"identity" : "googledatatransport",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleDataTransport.git",
"state" : {
"revision" : "ba3358d3c3dbae8ef230b58a46b97ad65e84e974",
"version" : "10.1.1"
}
},
{
"identity" : "googleutilities",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleUtilities.git",
"state" : {
"revision" : "cc31f5ed464b111f877ce8554cbef4455d410d91",
"version" : "8.1.4"
}
},
{
"identity" : "grpc-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/grpc-binary.git",
"state" : {
"revision" : "75b31c842f664a0f46a2e590a570e370249fd8f6",
"version" : "1.69.1"
}
},
{
"identity" : "gtm-session-fetcher",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/gtm-session-fetcher.git",
"state" : {
"revision" : "724a52eea6329b7e12d3ad8300d76ca9f3895fcc",
"version" : "5.3.1"
}
},
{
"identity" : "interop-ios-for-google-sdks",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/interop-ios-for-google-sdks.git",
"state" : {
"revision" : "040d087ac2267d2ddd4cca36c757d1c6a05fdbfe",
"version" : "101.0.0"
}
},
{
"identity" : "leveldb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/leveldb.git",
"state" : {
"revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1",
"version" : "1.22.5"
}
},
{
"identity" : "nanopb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/nanopb.git",
"state" : {
"revision" : "3851d94a41890dea16dc3db34caf60e585cb4163",
"version" : "2.30910.1"
}
},
{
"identity" : "promises",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/promises.git",
"state" : {
"revision" : "f4a19a3c313dc2616c70bb49d29a799fb16be837",
"version" : "2.4.1"
}
}
],
"version" : 2
-84
View File
@@ -1,84 +0,0 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2019-Present Christian Kußowski
# SPDX-FileCopyrightText: 2019-Present Contributors to FluffyChat
#
# SPDX-License-Identifier: AGPL-3.0-or-later
git apply ./scripts/enable-android-google-services.patch
FLUFFYCHAT_ORIG_GROUP="im.fluffychat"
FLUFFYCHAT_ORIG_TEAM="4NXF6Z997G"
#FLUFFYCHAT_NEW_GROUP="com.example.fluffychat"
#FLUFFYCHAT_NEW_TEAM="ABCDE12345"
# In some cases (ie: running beta XCode releases) some pods haven't updated their minimum version
# but XCode will reject the package for using too old of a minimum version.
# This will fix that, but. Well. Use at your own risk.
# export I_PROMISE_IM_REALLY_SMART=1
# If you want to automatically install the app
# export FLUFFYCHAT_INSTALL_IPA=1
### Rotate IDs ###
[ -n "${FLUFFYCHAT_NEW_GROUP}" ] && {
# App group IDs
sed -i "" "s/group.${FLUFFYCHAT_ORIG_GROUP}.app/group.${FLUFFYCHAT_NEW_GROUP}.app/g" "ios/FluffyChat Share/FluffyChat Share.entitlements"
sed -i "" "s/group.${FLUFFYCHAT_ORIG_GROUP}.app/group.${FLUFFYCHAT_NEW_GROUP}.app/g" "ios/Runner/Runner.entitlements"
sed -i "" "s/group.${FLUFFYCHAT_ORIG_GROUP}.app/group.${FLUFFYCHAT_NEW_GROUP}.app/g" "ios/Runner.xcodeproj/project.pbxproj"
# Bundle identifiers
sed -i "" "s/${FLUFFYCHAT_ORIG_GROUP}.app/${FLUFFYCHAT_NEW_GROUP}.app/g" "ios/Runner.xcodeproj/project.pbxproj"
}
[ -n "${FLUFFYCHAT_NEW_TEAM}" ] && {
# Code signing team
sed -i "" "s/${FLUFFYCHAT_ORIG_TEAM}/${FLUFFYCHAT_NEW_TEAM}/g" "ios/Runner.xcodeproj/project.pbxproj"
}
cat << EOHELP
If something later in the build explodes, and looks possibly related to App IDs:
1. Ask Xcode nicely
- Open ios/Runner.xcodeproj in Xcode
- Go to the Signing & Capabilities tab
- Ask it to repair the certificates/register app IDs/etc
2. Fix it yourself
- Go to https://developer.apple.com/account/resources/identifiers/list
- Ensure that Xcode created the App ID successfully (for fluffychat.app and fluffychat.app.FluffyChat-Share)
- Under "App Groups", make sure it registered your group
- Back "App IDs", check that the App Group was added to each App ID's entitlements
EOHELP
### [optional] override pods minimum iphoneos deployment target ###
[ -n "${I_PROMISE_IM_REALLY_SMART}" ] && {
# 1. I'm sorry about the indentation't ;_; heredocs are weird about it
# 2. The patch basically just removes any preference on target iOS version
# This lets our default from ios/Flutter/AppFrameworkInfo.plist take precendence
cat << EOPATCH | patch --forward --reject-file=apple_please_fix_your_coreutils --silent ios/Podfile
diff --git a/ios/Podfile b/ios/Podfile
index 9411102b..0446120a 100644
--- a/ios/Podfile
+++ b/ios/Podfile
@@ -37,5 +37,8 @@ end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
+ target.build_configurations.each do |config|
+ config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
+ end
end
end
EOPATCH
rm -f apple_please_fix_your_coreutils
}
### Make release build ###
flutter build ipa --release
### [optional] Install release build ###
[ -n "${FLUFFYCHAT_INSTALL_IPA}" ] && {
TMPDIR=$(mktemp -d)
# 1. Turn the xcarchive that flutter created into a dev-signed IPA
echo '{"compileBitcode":false,"method":"development"}' | plutil -convert xml1 -o "${TMPDIR}/options.plist" -
xcodebuild -exportArchive -archivePath ./build/ios/archive/Runner.xcarchive -exportPath "${TMPDIR}" -exportOptionsPlist "${TMPDIR}/options.plist"
# 2. ...and install it on your connected devices
cfgutil --foreach install-app "${TMPDIR}/fluffychat.ipa"
rm -rf "${TMPDIR}"
}
-8
View File
@@ -11,14 +11,6 @@ sed -i '' 's,//<GOOGLE_SERVICES>,,g' lib/utils/background_push.dart
flutter clean
flutter pub get
# Reload all cocoapods
(
cd ios
rm -rf Pods Podfile.lock
pod install
pod update
)
# Compile release build
flutter build ipa