Skip to content
This repository was archived by the owner on Mar 7, 2026. It is now read-only.

Commit 6fdb3d3

Browse files
authored
Add duplicate name check logic
1 parent 3eb4199 commit 6fdb3d3

File tree

1 file changed

+34
-3
lines changed

1 file changed

+34
-3
lines changed

Sources/prostore/views/CertificateView.swift

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ class CertificateFileManager {
100100
try p12Data.write(to: folderURL.appendingPathComponent("certificate.p12"))
101101
try provData.write(to: folderURL.appendingPathComponent("profile.mobileprovision"))
102102
try password.data(using: .utf8)?.write(to: folderURL.appendingPathComponent("password.txt"))
103-
try displayName.data(using: .utf8)?.write(to: folderURL.appendingPathComponent("name.txt"))
103+
let displayToWrite = uniqueDisplayName(displayName, excludingFolder: nil)
104+
try displayToWrite.data(using: .utf8)?.write(to: folderURL.appendingPathComponent("name.txt"))
104105

105106
return finalName
106107
}
@@ -142,7 +143,8 @@ class CertificateFileManager {
142143
try p12Data.write(to: certificateFolder.appendingPathComponent("certificate.p12"))
143144
try provData.write(to: certificateFolder.appendingPathComponent("profile.mobileprovision"))
144145
try password.data(using: .utf8)?.write(to: certificateFolder.appendingPathComponent("password.txt"))
145-
try displayName.data(using: .utf8)?.write(to: certificateFolder.appendingPathComponent("name.txt"))
146+
let displayToWrite = uniqueDisplayName(displayName, excludingFolder: folderName)
147+
try displayToWrite.data(using: .utf8)?.write(to: certificateFolder.appendingPathComponent("name.txt"))
146148
}
147149

148150
func deleteCertificate(folderName: String) throws {
@@ -154,6 +156,35 @@ class CertificateFileManager {
154156
let invalidChars = CharacterSet(charactersIn: ":/\\?%*|\"<>")
155157
return name.components(separatedBy: invalidChars).joined(separator: "_")
156158
}
159+
160+
// Return a unique display name by appending " 2", " 3", ... if needed.
161+
// `excludingFolder` lets updateCertificate keep the current folder's name out of the conflict check.
162+
private func uniqueDisplayName(_ desired: String, excludingFolder: String? = nil) -> String {
163+
let base = desired.isEmpty ? "Custom Certificate" : desired
164+
var existingNames = Set<String>()
165+
if let folders = try? fileManager.contentsOfDirectory(at: certificatesDirectory, includingPropertiesForKeys: nil, options: [.skipsHiddenFiles]) {
166+
for folder in folders {
167+
if folder.lastPathComponent == excludingFolder { continue }
168+
let nameURL = folder.appendingPathComponent("name.txt")
169+
if let data = try? Data(contentsOf: nameURL), let s = String(data: data, encoding: .utf8) {
170+
existingNames.insert(s)
171+
} else {
172+
// fallback to folder name if name.txt missing
173+
existingNames.insert(folder.lastPathComponent)
174+
}
175+
}
176+
}
177+
178+
if !existingNames.contains(base) {
179+
return base
180+
}
181+
182+
var counter = 2
183+
while existingNames.contains("\(base) \(counter)") {
184+
counter += 1
185+
}
186+
return "\(base) \(counter)"
187+
}
157188
}
158189

159190
// MARK: - CertificateView (List + Add/Edit launchers)
@@ -440,7 +471,7 @@ struct AddCertificateView: View {
440471
displayName = nameStr
441472
}
442473
}
443-
474+
444475
private func saveCertificate() {
445476
guard let p12URL = p12File?.url, let provURL = provFile?.url else { return }
446477

0 commit comments

Comments
 (0)