mirror of
https://github.com/krille-chan/fluffychat.git
synced 2026-10-16 04:56:46 +02:00
refactor: deintegrate cocoapods and switch NSE to dynamic sqlcipher
This commit is contained in:
11 files changed
+435
-449
No files matched your search
@@ -1,2 +1 @@
|
||||
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
@@ -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
@@ -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
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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}"
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in new issue
Block a user