Skip to content

Commit 936e1ba

Browse files
1 parent 8441f34 commit 936e1ba

File tree

1 file changed

+65
-53
lines changed

1 file changed

+65
-53
lines changed

YOLOiOSApp/YOLOiOSApp/ViewController.swift

Lines changed: 65 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,16 @@ extension Result {
2929
// MARK: - ModelTableViewCell
3030
class ModelTableViewCell: UITableViewCell {
3131
static let identifier = "ModelTableViewCell"
32-
32+
3333
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
3434
super.init(style: .default, reuseIdentifier: reuseIdentifier)
3535
setupCell()
3636
}
37-
37+
3838
required init?(coder: NSCoder) {
3939
fatalError("init(coder:) has not been implemented")
4040
}
41-
41+
4242
private func setupCell() {
4343
backgroundColor = .clear
4444
selectionStyle = .default
@@ -47,17 +47,17 @@ class ModelTableViewCell: UITableViewCell {
4747
textLabel?.adjustsFontSizeToFitWidth = true
4848
textLabel?.minimumScaleFactor = 0.7
4949
textLabel?.textColor = .white
50-
50+
5151
let selectedBGView = UIView()
5252
selectedBGView.backgroundColor = UIColor(white: 1.0, alpha: 0.3)
5353
selectedBGView.layer.cornerRadius = 5
5454
selectedBackgroundView = selectedBGView
5555
}
56-
56+
5757
func configure(with modelName: String, isRemote: Bool, isDownloaded: Bool) {
5858
textLabel?.text = modelName
5959
textLabel?.textColor = (isRemote && !isDownloaded) ? .lightGray : .white
60-
60+
6161
if isRemote && !isDownloaded {
6262
let config = UIImage.SymbolConfiguration(pointSize: 14)
6363
imageView?.image = UIImage(systemName: "icloud.and.arrow.down", withConfiguration: config)
@@ -66,7 +66,7 @@ class ModelTableViewCell: UITableViewCell {
6666
imageView?.image = nil
6767
}
6868
}
69-
69+
7070
override func layoutSubviews() {
7171
super.layoutSubviews()
7272
selectedBackgroundView?.frame = bounds.insetBy(dx: 2, dy: 1)
@@ -98,7 +98,7 @@ class ViewController: UIViewController, YOLOViewDelegate {
9898
activityIndicator.startAnimating()
9999
view.isUserInteractionEnabled = false
100100
modelTableView.isUserInteractionEnabled = false
101-
101+
102102
if showOverlay {
103103
showLoadingOverlay()
104104
}
@@ -109,7 +109,7 @@ class ViewController: UIViewController, YOLOViewDelegate {
109109
hideLoadingOverlay()
110110
}
111111
}
112-
112+
113113
private func showLoadingOverlay() {
114114
guard loadingOverlayView == nil else { return }
115115
let overlay = UIView(frame: view.bounds)
@@ -141,7 +141,7 @@ class ViewController: UIViewController, YOLOViewDelegate {
141141
private var currentModelName: String = ""
142142

143143
private var isLoadingModel = false
144-
144+
145145
// MARK: - Constants
146146
private struct Constants {
147147
static let defaultTaskIndex = 2 // Detect
@@ -199,41 +199,44 @@ class ViewController: UIViewController, YOLOViewDelegate {
199199
super.viewWillAppear(animated)
200200
view.overrideUserInterfaceStyle = .dark
201201
}
202-
202+
203203
// MARK: - Setup Methods
204204
private func setupDownloadProgressViews() {
205205
downloadProgressView.isHidden = true
206206
downloadProgressLabel.textAlignment = .center
207207
downloadProgressLabel.textColor = .systemGray
208208
downloadProgressLabel.font = .systemFont(ofSize: 14)
209209
downloadProgressLabel.isHidden = true
210-
210+
211211
[downloadProgressView, downloadProgressLabel].forEach {
212212
$0.translatesAutoresizingMaskIntoConstraints = false
213213
view.addSubview($0)
214214
}
215-
215+
216216
NSLayoutConstraint.activate([
217217
downloadProgressView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
218-
downloadProgressView.topAnchor.constraint(equalTo: activityIndicator.bottomAnchor, constant: 8),
218+
downloadProgressView.topAnchor.constraint(
219+
equalTo: activityIndicator.bottomAnchor, constant: 8),
219220
downloadProgressView.widthAnchor.constraint(equalToConstant: Constants.progressViewWidth),
220221
downloadProgressView.heightAnchor.constraint(equalToConstant: 2),
221222
downloadProgressLabel.centerXAnchor.constraint(equalTo: downloadProgressView.centerXAnchor),
222-
downloadProgressLabel.topAnchor.constraint(equalTo: downloadProgressView.bottomAnchor, constant: 8)
223+
downloadProgressLabel.topAnchor.constraint(
224+
equalTo: downloadProgressView.bottomAnchor, constant: 8),
223225
])
224226
}
225-
227+
226228
private func setupLabels() {
227229
labelName.textColor = .white
228230
labelFPS.textColor = .white
229231
labelVersion.textColor = .white
230-
232+
231233
labelName.overrideUserInterfaceStyle = .dark
232234
labelFPS.overrideUserInterfaceStyle = .dark
233235
labelVersion.overrideUserInterfaceStyle = .dark
234-
236+
235237
if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String,
236-
let build = Bundle.main.infoDictionary?["CFBundleVersion"] as? String {
238+
let build = Bundle.main.infoDictionary?["CFBundleVersion"] as? String
239+
{
237240
labelVersion.text = "v\(version) (\(build))"
238241
}
239242
}
@@ -253,20 +256,22 @@ class ViewController: UIViewController, YOLOViewDelegate {
253256

254257
private func getModelFiles(in folderName: String) -> [String] {
255258
guard let folderURL = Bundle.main.url(forResource: folderName, withExtension: nil),
256-
let fileURLs = try? FileManager.default.contentsOfDirectory(
257-
at: folderURL, includingPropertiesForKeys: nil, options: [.skipsHiddenFiles]
258-
) else { return [] }
259-
260-
let modelFiles = fileURLs
259+
let fileURLs = try? FileManager.default.contentsOfDirectory(
260+
at: folderURL, includingPropertiesForKeys: nil, options: [.skipsHiddenFiles]
261+
)
262+
else { return [] }
263+
264+
let modelFiles =
265+
fileURLs
261266
.filter { ["mlmodel", "mlpackage"].contains($0.pathExtension) }
262267
.map { $0.lastPathComponent }
263-
268+
264269
return folderName == "DetectModels" ? reorderDetectionModels(modelFiles) : modelFiles.sorted()
265270
}
266271

267272
private func reorderDetectionModels(_ fileNames: [String]) -> [String] {
268273
let officialOrder: [Character: Int] = ["n": 0, "m": 1, "s": 2, "l": 3, "x": 4]
269-
274+
270275
let (official, custom) = fileNames.reduce(into: ([String](), [String]())) { result, fileName in
271276
let baseName = (fileName as NSString).deletingPathExtension.lowercased()
272277
if baseName.hasPrefix("yolo"), let lastChar = baseName.last, officialOrder[lastChar] != nil {
@@ -275,14 +280,15 @@ class ViewController: UIViewController, YOLOViewDelegate {
275280
result.1.append(fileName)
276281
}
277282
}
278-
279-
return custom.sorted() + official.sorted { fileA, fileB in
280-
let baseA = (fileA as NSString).deletingPathExtension.lowercased()
281-
let baseB = (fileB as NSString).deletingPathExtension.lowercased()
282-
let indexA = baseA.last.flatMap { officialOrder[$0] } ?? Int.max
283-
let indexB = baseB.last.flatMap { officialOrder[$0] } ?? Int.max
284-
return indexA < indexB
285-
}
283+
284+
return custom.sorted()
285+
+ official.sorted { fileA, fileB in
286+
let baseA = (fileA as NSString).deletingPathExtension.lowercased()
287+
let baseB = (fileB as NSString).deletingPathExtension.lowercased()
288+
let indexA = baseA.last.flatMap { officialOrder[$0] } ?? Int.max
289+
let indexB = baseB.last.flatMap { officialOrder[$0] } ?? Int.max
290+
return indexA < indexB
291+
}
286292
}
287293

288294
private func reloadModelEntriesAndLoadFirst(for taskName: String) {
@@ -330,14 +336,14 @@ class ViewController: UIViewController, YOLOViewDelegate {
330336
private func loadModel(entry: (name: String, url: URL?, isLocal: Bool), forTask task: String) {
331337
guard !isLoadingModel else { return }
332338
isLoadingModel = true
333-
339+
334340
yoloView.resetLayers()
335341
yoloView.setInferenceFlag(ok: false)
336342
setLoadingState(true, showOverlay: true)
337343
resetDownloadProgress()
338-
344+
339345
let yoloTask = convertTaskNameToYOLOTask(task)
340-
346+
341347
if entry.isLocal {
342348
loadLocalModel(entry: entry, task: task, yoloTask: yoloTask)
343349
} else if let remoteURL = entry.url {
@@ -346,29 +352,35 @@ class ViewController: UIViewController, YOLOViewDelegate {
346352
finishLoadingModel(success: false, modelName: entry.name)
347353
}
348354
}
349-
350-
private func loadLocalModel(entry: (name: String, url: URL?, isLocal: Bool), task: String, yoloTask: YOLOTask) {
355+
356+
private func loadLocalModel(
357+
entry: (name: String, url: URL?, isLocal: Bool), task: String, yoloTask: YOLOTask
358+
) {
351359
guard let folderURL = tasks.first(where: { $0.name == task })?.folder,
352-
let folderPathURL = Bundle.main.url(forResource: folderURL, withExtension: nil) else {
360+
let folderPathURL = Bundle.main.url(forResource: folderURL, withExtension: nil)
361+
else {
353362
finishLoadingModel(success: false, modelName: entry.name)
354363
return
355364
}
356-
365+
357366
let modelURL = folderPathURL.appendingPathComponent(entry.name + ".mlpackage")
358367
downloadProgressLabel.text = "Loading \(entry.name)"
359368
downloadProgressLabel.isHidden = false
360-
369+
361370
yoloView.setModel(modelPathOrName: modelURL.path, task: yoloTask) { [weak self] result in
362371
self?.finishLoadingModel(success: result.isSuccess, modelName: entry.name)
363372
}
364373
}
365-
366-
private func loadRemoteModel(url: URL, entry: (name: String, url: URL?, isLocal: Bool), yoloTask: YOLOTask) {
374+
375+
private func loadRemoteModel(
376+
url: URL, entry: (name: String, url: URL?, isLocal: Bool), yoloTask: YOLOTask
377+
) {
367378
let downloader = YOLOModelDownloader()
368379
downloadProgressView.isHidden = false
369380
downloadProgressLabel.isHidden = false
370-
371-
downloader.download(from: url, task: yoloTask,
381+
382+
downloader.download(
383+
from: url, task: yoloTask,
372384
progress: { [weak self] progress in
373385
DispatchQueue.main.async {
374386
self?.downloadProgressView.progress = Float(progress)
@@ -403,14 +415,14 @@ class ViewController: UIViewController, YOLOViewDelegate {
403415
self.setLoadingState(false)
404416
self.isLoadingModel = false
405417
self.resetDownloadProgress()
406-
418+
407419
self.modelTableView.reloadData()
408420
if let ip = self.selectedIndexPath {
409421
self.modelTableView.selectRow(at: ip, animated: false, scrollPosition: .none)
410422
}
411-
423+
412424
self.yoloView.setInferenceFlag(ok: success)
413-
425+
414426
if success {
415427
self.currentModelName = modelName
416428
self.labelName.text = processString(modelName)
@@ -501,11 +513,11 @@ class ViewController: UIViewController, YOLOViewDelegate {
501513
super.viewDidLayoutSubviews()
502514
layoutModelTableView()
503515
}
504-
516+
505517
private func layoutModelTableView() {
506518
let isLandscape = view.bounds.width > view.bounds.height
507519
let tableViewWidth = view.bounds.width * (isLandscape ? 0.2 : 0.4)
508-
520+
509521
if isLandscape {
510522
modelTableView.frame = CGRect(
511523
x: segmentedControl.frame.maxX + 20, y: 20, width: tableViewWidth, height: 200)
@@ -516,10 +528,10 @@ class ViewController: UIViewController, YOLOViewDelegate {
516528
width: tableViewWidth,
517529
height: 200)
518530
}
519-
531+
520532
updateTableViewBackground()
521533
}
522-
534+
523535
private func updateTableViewBackground() {
524536
tableViewBGView.frame = CGRect(
525537
x: modelTableView.frame.minX - 1,

0 commit comments

Comments
 (0)