diff --git a/ChangeLog.md b/ChangeLog.md
index 094bdee..4788d8a 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -13,7 +13,7 @@ To opt out of data the sending of data click 'Opt out of analytics' at the botto
**v8.5.1**: 2026-01-04
Address issue removing jamf users/groups.
-Starting with version 8.5.1 the application will submit basic hardware, OS, and Replicator application usage to [TelemetryDeck](https://telemetrydeck.com). The data is sent anamously and used to aid in the development of the application. To opt out of data the sending of data click 'Opt out of analytics' at the bottom of the 'About Replicator' window.
+Starting with version 8.5.1 the application will submit basic hardware, OS, and Replicator application usage to [TelemetryDeck](https://telemetrydeck.com). The data is sent anonymously and used to aid in the development of the application. To opt out of data the sending of data click 'Opt out of analytics' at the bottom of the 'About Replicator' window.
**v8.4.1**: 2025-11-06
Address issue #128 - app is now notarized.
diff --git a/README.md b/README.md
index 6ed27fc..7d451f1 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ A tool to synchronize objects between Jamf Pro servers. Export objects and save

-By default the application will submit basic hardware, OS, and jamfCPR application usage to [TelemetryDeck](https://telemetrydeck.com). The data is sent anamously and used to aid in the development of the application. To opt out of data the sending of data click 'Opt out of analytics' at the bottom of the Settings --> app window.
+By default the application will submit basic hardware, OS, and jamfCPR application usage to [TelemetryDeck](https://telemetrydeck.com). The data is sent anonymously and used to aid in the development of the application. To opt out of data the sending of data click 'Opt out of analytics' at the bottom of the Settings --> app window.
Replicate items from one Jamf server, or XML file(s), to another. If an object (based on name) exists on both source and destination, the destination object will be updated with values from the source server.
diff --git a/Replicator.xcodeproj/project.pbxproj b/Replicator.xcodeproj/project.pbxproj
index 88d9eb5..f15728b 100755
--- a/Replicator.xcodeproj/project.pbxproj
+++ b/Replicator.xcodeproj/project.pbxproj
@@ -596,7 +596,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.5;
- MARKETING_VERSION = 8.6.0;
+ MARKETING_VERSION = "8.6.1-gio";
PRODUCT_BUNDLE_IDENTIFIER = "com.jamf.jamf-migrator";
PRODUCT_NAME = Replicator;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
@@ -625,7 +625,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.5;
- MARKETING_VERSION = 8.6.0;
+ MARKETING_VERSION = "8.6.1-gio";
PRODUCT_BUNDLE_IDENTIFIER = "com.jamf.jamf-migrator";
PRODUCT_NAME = Replicator;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
diff --git a/Replicator/CreateEndpoints.swift b/Replicator/CreateEndpoints.swift
index 9b80fe9..0cf2817 100644
--- a/Replicator/CreateEndpoints.swift
+++ b/Replicator/CreateEndpoints.swift
@@ -977,4 +977,8 @@ class CreateEndpoints: NSObject, URLSessionDelegate {
} // if !WipeData.state.on - end
} // SendQueue - end
}
+
+ func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping(URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
+ completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
+ }
}
diff --git a/Replicator/EndpointData.swift b/Replicator/EndpointData.swift
index c0b5683..508b854 100644
--- a/Replicator/EndpointData.swift
+++ b/Replicator/EndpointData.swift
@@ -319,7 +319,11 @@ class EndpointData: NSObject, URLSessionDelegate {
if LogLevel.debug { WriteToLog.shared.message("[getById] Returned from cleanupXml") }
}
// check progress
- Endpoints.countDict[endpoint]! -= 1
+ if let _ = Endpoints.countDict[endpoint] {
+ Endpoints.countDict[endpoint]! -= 1
+ } else {
+ Endpoints.countDict[endpoint] = 0
+ }
if Endpoints.countDict[endpoint] == 0 {
Endpoints.countDict[endpoint] = nil
@@ -364,5 +368,9 @@ class EndpointData: NSObject, URLSessionDelegate {
}
}
}
+
+ func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping(URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
+ completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
+ }
}
diff --git a/Replicator/EndpointXml.swift b/Replicator/EndpointXml.swift
index 24079f8..91bfa14 100644
--- a/Replicator/EndpointXml.swift
+++ b/Replicator/EndpointXml.swift
@@ -363,5 +363,9 @@ class EndpointXml: NSObject, URLSessionDelegate {
}
}
}
+
+ func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping(URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
+ completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
+ }
}
diff --git a/Replicator/ExistingObjects.swift b/Replicator/ExistingObjects.swift
index f6bc05c..5707f4c 100644
--- a/Replicator/ExistingObjects.swift
+++ b/Replicator/ExistingObjects.swift
@@ -424,4 +424,8 @@ class ExistingObjects: NSObject, URLSessionDelegate {
completion(("Current endpoints - export.saveOnly, not needed.","\(theDestEndpoint)"))
}
}
+
+ func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping(URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
+ completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
+ }
}
diff --git a/Replicator/IconDelegate.swift b/Replicator/IconDelegate.swift
index 5f71771..bfb44e0 100644
--- a/Replicator/IconDelegate.swift
+++ b/Replicator/IconDelegate.swift
@@ -617,5 +617,8 @@ class IconDelegate: NSObject, URLSessionDelegate {
} // while - end
} // DispatchQueue.main.async - end
}
-
+
+ func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping(URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
+ completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
+ }
}
diff --git a/Replicator/Info.plist b/Replicator/Info.plist
index a9a8803..c099900 100644
--- a/Replicator/Info.plist
+++ b/Replicator/Info.plist
@@ -19,7 +19,7 @@
CFBundleShortVersionString
$(MARKETING_VERSION)
CFBundleVersion
- 20260122-5EC
+ 20260909-8C6
LSApplicationCategoryType
public.app-category.utilities
LSMinimumSystemVersion
diff --git a/Replicator/Json.swift b/Replicator/Json.swift
index b620753..39cb5fe 100644
--- a/Replicator/Json.swift
+++ b/Replicator/Json.swift
@@ -131,5 +131,9 @@ class Json: NSObject, URLSessionDelegate {
}
return cleanPolicies as AnyObject
}
+
+ func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping(URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
+ completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
+ }
}
diff --git a/Replicator/ObjectDelegate.swift b/Replicator/ObjectDelegate.swift
index dcb3ae6..2aa175e 100644
--- a/Replicator/ObjectDelegate.swift
+++ b/Replicator/ObjectDelegate.swift
@@ -47,5 +47,9 @@ class ObjectDelegate: NSObject, URLSessionDelegate {
}
}
}
+
+ func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping(URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
+ completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
+ }
}
diff --git a/Replicator/PackagesDelegate.swift b/Replicator/PackagesDelegate.swift
index 973c890..b23b2f1 100644
--- a/Replicator/PackagesDelegate.swift
+++ b/Replicator/PackagesDelegate.swift
@@ -399,4 +399,8 @@ class PackagesDelegate: NSObject, URLSessionDelegate {
// WriteToLog.shared.message("[PackageDelegate.filenameIdDict] Duplicate references to the same package were found on \(theServer)\n\(message)")
}
}
+
+ func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping(URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
+ completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
+ }
}
diff --git a/Replicator/RemoveObjects.swift b/Replicator/RemoveObjects.swift
index d8260e7..95cbbe2 100644
--- a/Replicator/RemoveObjects.swift
+++ b/Replicator/RemoveObjects.swift
@@ -233,6 +233,7 @@ class RemoveObjects: NSObject, URLSessionDelegate {
defer { semaphore.signal() }
session.finishTasksAndInvalidate()
if let httpResponse = response as? HTTPURLResponse {
+ if LogLevel.debug { WriteToLog.shared.message("[RemoveObjects.process] response statusCode: \(httpResponse.statusCode)") }
if let _ = String(data: data!, encoding: .utf8) {
responseData = String(data: data!, encoding: .utf8)!
} else {
@@ -354,4 +355,8 @@ class RemoveObjects: NSObject, URLSessionDelegate {
semaphore.wait()
}
}
+
+ func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping(URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
+ completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
+ }
}