Skip to content
This repository was archived by the owner on Dec 2, 2025. It is now read-only.

Commit 9cb3b04

Browse files
authored
Merge pull request #746 from oxen-io/dev
Release 2.2.4
2 parents 66ee136 + 8abe2a1 commit 9cb3b04

8 files changed

Lines changed: 72 additions & 36 deletions

File tree

Session.xcodeproj/project.pbxproj

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6032,7 +6032,7 @@
60326032
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
60336033
CODE_SIGN_STYLE = Automatic;
60346034
COPY_PHASE_STRIP = NO;
6035-
CURRENT_PROJECT_VERSION = 387;
6035+
CURRENT_PROJECT_VERSION = 389;
60366036
DEBUG_INFORMATION_FORMAT = dwarf;
60376037
DEVELOPMENT_TEAM = SUQ8J2PCT7;
60386038
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
@@ -6057,7 +6057,7 @@
60576057
"@executable_path/Frameworks",
60586058
"@executable_path/../../Frameworks",
60596059
);
6060-
MARKETING_VERSION = 2.2.2;
6060+
MARKETING_VERSION = 2.2.4;
60616061
MTL_ENABLE_DEBUG_INFO = YES;
60626062
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.ShareExtension";
60636063
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -6105,7 +6105,7 @@
61056105
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
61066106
CODE_SIGN_STYLE = Automatic;
61076107
COPY_PHASE_STRIP = NO;
6108-
CURRENT_PROJECT_VERSION = 387;
6108+
CURRENT_PROJECT_VERSION = 389;
61096109
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
61106110
DEVELOPMENT_TEAM = SUQ8J2PCT7;
61116111
ENABLE_NS_ASSERTIONS = NO;
@@ -6135,7 +6135,7 @@
61356135
"@executable_path/Frameworks",
61366136
"@executable_path/../../Frameworks",
61376137
);
6138-
MARKETING_VERSION = 2.2.2;
6138+
MARKETING_VERSION = 2.2.4;
61396139
MTL_ENABLE_DEBUG_INFO = NO;
61406140
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.ShareExtension";
61416141
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -6171,7 +6171,7 @@
61716171
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
61726172
CODE_SIGN_STYLE = Automatic;
61736173
COPY_PHASE_STRIP = NO;
6174-
CURRENT_PROJECT_VERSION = 387;
6174+
CURRENT_PROJECT_VERSION = 389;
61756175
DEBUG_INFORMATION_FORMAT = dwarf;
61766176
DEVELOPMENT_TEAM = SUQ8J2PCT7;
61776177
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
@@ -6194,7 +6194,7 @@
61946194
"@executable_path/Frameworks",
61956195
"@executable_path/../../Frameworks",
61966196
);
6197-
MARKETING_VERSION = 2.2.2;
6197+
MARKETING_VERSION = 2.2.4;
61986198
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
61996199
MTL_FAST_MATH = YES;
62006200
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.NotificationServiceExtension";
@@ -6245,7 +6245,7 @@
62456245
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
62466246
CODE_SIGN_STYLE = Automatic;
62476247
COPY_PHASE_STRIP = NO;
6248-
CURRENT_PROJECT_VERSION = 387;
6248+
CURRENT_PROJECT_VERSION = 389;
62496249
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
62506250
DEVELOPMENT_TEAM = SUQ8J2PCT7;
62516251
ENABLE_NS_ASSERTIONS = NO;
@@ -6273,7 +6273,7 @@
62736273
"@executable_path/Frameworks",
62746274
"@executable_path/../../Frameworks",
62756275
);
6276-
MARKETING_VERSION = 2.2.2;
6276+
MARKETING_VERSION = 2.2.4;
62776277
MTL_ENABLE_DEBUG_INFO = NO;
62786278
MTL_FAST_MATH = YES;
62796279
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.NotificationServiceExtension";
@@ -7173,7 +7173,7 @@
71737173
CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements;
71747174
CODE_SIGN_IDENTITY = "iPhone Developer";
71757175
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
7176-
CURRENT_PROJECT_VERSION = 388;
7176+
CURRENT_PROJECT_VERSION = 389;
71777177
DEVELOPMENT_TEAM = SUQ8J2PCT7;
71787178
FRAMEWORK_SEARCH_PATHS = (
71797179
"$(inherited)",
@@ -7212,7 +7212,7 @@
72127212
"$(SRCROOT)",
72137213
);
72147214
LLVM_LTO = NO;
7215-
MARKETING_VERSION = 2.2.3;
7215+
MARKETING_VERSION = 2.2.4;
72167216
OTHER_LDFLAGS = "$(inherited)";
72177217
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
72187218
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger";
@@ -7245,7 +7245,7 @@
72457245
CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements;
72467246
CODE_SIGN_IDENTITY = "iPhone Developer";
72477247
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
7248-
CURRENT_PROJECT_VERSION = 388;
7248+
CURRENT_PROJECT_VERSION = 389;
72497249
DEVELOPMENT_TEAM = SUQ8J2PCT7;
72507250
FRAMEWORK_SEARCH_PATHS = (
72517251
"$(inherited)",
@@ -7284,7 +7284,7 @@
72847284
"$(SRCROOT)",
72857285
);
72867286
LLVM_LTO = NO;
7287-
MARKETING_VERSION = 2.2.3;
7287+
MARKETING_VERSION = 2.2.4;
72887288
OTHER_LDFLAGS = "$(inherited)";
72897289
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger";
72907290
PRODUCT_NAME = Session;

Session/Settings/SettingsViewModel.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -561,9 +561,8 @@ class ImagePickerHandler: NSObject, UIImagePickerControllerDelegate & UINavigati
561561
// Check if the user selected an animated image (if so then don't crop, just
562562
// set the avatar directly
563563
guard
564-
let type: Any = try? imageUrl.resourceValues(forKeys: [.typeIdentifierKey])
565-
.allValues
566-
.first,
564+
let resourceValues: URLResourceValues = (try? imageUrl.resourceValues(forKeys: [.typeIdentifierKey])),
565+
let type: Any = resourceValues.allValues.first?.value,
567566
let typeString: String = type as? String,
568567
MIMETypeUtil.supportedAnimatedImageUTITypes().contains(typeString)
569568
else {

SessionMessagingKit/Jobs/Types/AttachmentUploadJob.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public enum AttachmentUploadJob: JobExecutor {
2020
) {
2121
guard
2222
let threadId: String = job.threadId,
23+
let interactionId: Int64 = job.interactionId,
2324
let detailsData: Data = job.details,
2425
let details: Details = try? JSONDecoder().decode(Details.self, from: detailsData),
2526
let (attachment, openGroup): (Attachment, OpenGroup?) = Storage.shared.read({ db in
@@ -36,11 +37,9 @@ public enum AttachmentUploadJob: JobExecutor {
3637

3738
// If the original interaction no longer exists then don't bother uploading the attachment (ie. the
3839
// message was deleted before it even got sent)
39-
if let interactionId: Int64 = job.interactionId {
40-
guard Storage.shared.read({ db in try Interaction.exists(db, id: interactionId) }) == true else {
41-
failure(job, StorageError.objectNotFound, true)
42-
return
43-
}
40+
guard Storage.shared.read({ db in try Interaction.exists(db, id: interactionId) }) == true else {
41+
failure(job, StorageError.objectNotFound, true)
42+
return
4443
}
4544

4645
// If the attachment is still pending download the hold off on running this job
@@ -55,6 +54,8 @@ public enum AttachmentUploadJob: JobExecutor {
5554
attachment.upload(
5655
queue: queue,
5756
using: { db, data in
57+
SNLog("[AttachmentUpload] Started for message \(interactionId) (\(attachment.byteCount) bytes)")
58+
5859
if let openGroup: OpenGroup = openGroup {
5960
return OpenGroupAPI
6061
.uploadFile(

SessionMessagingKit/Jobs/Types/MessageSendJob.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public enum MessageSendJob: JobExecutor {
9696
)
9797
)
9898
}
99-
.compactMap { stateInfo in
99+
.compactMap { stateInfo -> (jobId: Int64, job: Job)? in
100100
JobRunner
101101
.insert(
102102
db,
@@ -111,10 +111,9 @@ public enum MessageSendJob: JobExecutor {
111111
)
112112
),
113113
before: job
114-
)?
115-
.id
114+
)
116115
}
117-
.forEach { otherJobId in
116+
.forEach { otherJobId, _ in
118117
// Create the dependency between the jobs
119118
try JobDependencies(
120119
jobId: jobId,

SessionSnodeKit/Database/Models/SnodeReceivedMessageInfo.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ public struct SnodeReceivedMessageInfo: Codable, FetchableRecord, MutablePersist
4444

4545
// MARK: - Custom Database Interaction
4646

47-
public mutating func didInsert(with rowID: Int64, for column: String?) {
48-
self.id = rowID
47+
public mutating func didInsert(_ inserted: InsertionSuccess) {
48+
self.id = inserted.rowID
4949
}
5050
}
5151

SessionUtilitiesKit/Database/Models/Job.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,8 @@ public struct Job: Codable, Equatable, Identifiable, FetchableRecord, MutablePer
294294

295295
// MARK: - Custom Database Interaction
296296

297-
public mutating func didInsert(with rowID: Int64, for column: String?) {
298-
self.id = rowID
297+
public mutating func didInsert(_ inserted: InsertionSuccess) {
298+
self.id = inserted.rowID
299299
}
300300
}
301301

@@ -304,8 +304,8 @@ public struct Job: Codable, Equatable, Identifiable, FetchableRecord, MutablePer
304304
extension Job {
305305
internal static func filterPendingJobs(
306306
variants: [Variant],
307-
excludeFutureJobs: Bool = true,
308-
includeJobsWithDependencies: Bool = false
307+
excludeFutureJobs: Bool,
308+
includeJobsWithDependencies: Bool
309309
) -> QueryInterfaceRequest<Job> {
310310
var query: QueryInterfaceRequest<Job> = Job
311311
.filter(

SessionUtilitiesKit/JobRunner/JobRunner.swift

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ public final class JobRunner {
131131
SNLog("[JobRunner] Unable to add \(job.map { "\($0.variant)" } ?? "unknown") job")
132132
return
133133
}
134+
guard !canStartJob || updatedJob.id != nil else {
135+
SNLog("[JobRunner] Not starting \(job.map { "\($0.variant)" } ?? "unknown") job due to missing id")
136+
return
137+
}
134138

135139
queues.mutate { $0[updatedJob.variant]?.add(updatedJob, canStartJob: canStartJob) }
136140

@@ -150,6 +154,10 @@ public final class JobRunner {
150154
/// is in the future then the job won't be started
151155
public static func upsert(_ db: Database, job: Job?, canStartJob: Bool = true) {
152156
guard let job: Job = job else { return } // Ignore null jobs
157+
guard job.id != nil else {
158+
add(db, job: job, canStartJob: canStartJob)
159+
return
160+
}
153161

154162
queues.wrappedValue[job.variant]?.upsert(job, canStartJob: canStartJob)
155163

@@ -159,7 +167,7 @@ public final class JobRunner {
159167
}
160168
}
161169

162-
@discardableResult public static func insert(_ db: Database, job: Job?, before otherJob: Job) -> Job? {
170+
@discardableResult public static func insert(_ db: Database, job: Job?, before otherJob: Job) -> (Int64, Job)? {
163171
switch job?.behaviour {
164172
case .recurringOnActive, .recurringOnLaunch, .runOnceNextLaunch:
165173
SNLog("[JobRunner] Attempted to insert \(job.map { "\($0.variant)" } ?? "unknown") job before the current one even though it's behaviour is \(job.map { "\($0.behaviour)" } ?? "unknown")")
@@ -173,6 +181,10 @@ public final class JobRunner {
173181
SNLog("[JobRunner] Unable to add \(job.map { "\($0.variant)" } ?? "unknown") job")
174182
return nil
175183
}
184+
guard let jobId: Int64 = updatedJob.id else {
185+
SNLog("[JobRunner] Unable to add \(job.map { "\($0.variant)" } ?? "unknown") job due to missing id")
186+
return nil
187+
}
176188

177189
queues.wrappedValue[updatedJob.variant]?.insert(updatedJob, before: otherJob)
178190

@@ -181,7 +193,7 @@ public final class JobRunner {
181193
queues.wrappedValue[updatedJob.variant]?.start()
182194
}
183195

184-
return updatedJob
196+
return (jobId, updatedJob)
185197
}
186198

187199
public static func appDidFinishLaunching() {
@@ -499,6 +511,10 @@ private final class JobQueue {
499511
job.behaviour != .runOnceNextLaunch,
500512
job.nextRunTimestamp <= Date().timeIntervalSince1970
501513
else { return }
514+
guard job.id != nil else {
515+
SNLog("[JobRunner] Prevented attempt to add \(job.variant) job without id to queue")
516+
return
517+
}
502518

503519
queue.mutate { $0.append(job) }
504520
}
@@ -510,7 +526,7 @@ private final class JobQueue {
510526
/// is in the future then the job won't be started
511527
fileprivate func upsert(_ job: Job, canStartJob: Bool = true) {
512528
guard let jobId: Int64 = job.id else {
513-
add(job, canStartJob: canStartJob)
529+
SNLog("[JobRunner] Prevented attempt to upsert \(job.variant) job without id to queue")
514530
return
515531
}
516532

@@ -535,6 +551,11 @@ private final class JobQueue {
535551
}
536552

537553
fileprivate func insert(_ job: Job, before otherJob: Job) {
554+
guard job.id != nil else {
555+
SNLog("[JobRunner] Prevented attempt to insert \(job.variant) job without id to queue")
556+
return
557+
}
558+
538559
// Insert the job before the current job (re-adding the current job to
539560
// the start of the queue if it's not in there) - this will mean the new
540561
// job will run and then the otherJob will run (or run again) once it's
@@ -634,7 +655,12 @@ private final class JobQueue {
634655
let jobIdsAlreadyRunning: Set<Int64> = jobsCurrentlyRunning.wrappedValue
635656
let jobsAlreadyInQueue: Set<Int64> = queue.wrappedValue.compactMap { $0.id }.asSet()
636657
let jobsToRun: [Job] = Storage.shared.read { db in
637-
try Job.filterPendingJobs(variants: jobVariants)
658+
try Job
659+
.filterPendingJobs(
660+
variants: jobVariants,
661+
excludeFutureJobs: true,
662+
includeJobsWithDependencies: false
663+
)
638664
.filter(!jobIdsAlreadyRunning.contains(Job.Columns.id)) // Exclude jobs already running
639665
.filter(!jobsAlreadyInQueue.contains(Job.Columns.id)) // Exclude jobs already in the queue
640666
.fetchAll(db)
@@ -709,6 +735,11 @@ private final class JobQueue {
709735
handleJobFailed(nextJob, error: JobRunnerError.requiredInteractionIdMissing, permanentFailure: true)
710736
return
711737
}
738+
guard nextJob.id != nil else {
739+
SNLog("[JobRunner] \(queueContext) Unable to run \(nextJob.variant) job due to missing id")
740+
handleJobFailed(nextJob, error: JobRunnerError.jobIdMissing, permanentFailure: false)
741+
return
742+
}
712743

713744
// If the 'nextRunTimestamp' for the job is in the future then don't run it yet
714745
guard nextJob.nextRunTimestamp <= Date().timeIntervalSince1970 else {
@@ -787,7 +818,7 @@ private final class JobQueue {
787818
numJobsRunning = jobsCurrentlyRunning.count
788819
}
789820
detailsForCurrentlyRunningJobs.mutate { $0 = $0.setting(nextJob.id, nextJob.details) }
790-
SNLog("[JobRunner] \(queueContext) started job (\(executionType == .concurrent ? "\(numJobsRunning) currently running, " : "")\(numJobsRemaining) remaining)")
821+
SNLog("[JobRunner] \(queueContext) started \(nextJob.variant) job (\(executionType == .concurrent ? "\(numJobsRunning) currently running, " : "")\(numJobsRemaining) remaining)")
791822

792823
jobExecutor.run(
793824
nextJob,
@@ -809,7 +840,12 @@ private final class JobQueue {
809840
private func scheduleNextSoonestJob() {
810841
let jobIdsAlreadyRunning: Set<Int64> = jobsCurrentlyRunning.wrappedValue
811842
let nextJobTimestamp: TimeInterval? = Storage.shared.read { db in
812-
try Job.filterPendingJobs(variants: jobVariants, excludeFutureJobs: false)
843+
try Job
844+
.filterPendingJobs(
845+
variants: jobVariants,
846+
excludeFutureJobs: false,
847+
includeJobsWithDependencies: false
848+
)
813849
.select(.nextRunTimestamp)
814850
.filter(!jobIdsAlreadyRunning.contains(Job.Columns.id)) // Exclude jobs already running
815851
.asRequest(of: TimeInterval.self)

SessionUtilitiesKit/JobRunner/JobRunnerError.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ public enum JobRunnerError: Error {
66
case generic
77

88
case executorMissing
9+
case jobIdMissing
910
case requiredThreadIdMissing
1011
case requiredInteractionIdMissing
1112

0 commit comments

Comments
 (0)