update iOS app

This commit is contained in:
Maciej Czajka 2023-01-27 22:46:56 +01:00
parent 9a1762feb8
commit 90b44a6581
7 changed files with 159 additions and 324 deletions

View File

@ -87,101 +87,3 @@ struct CameraPicker: UIViewControllerRepresentable {
}
}
}
//struct CameraPicker: UIViewControllerRepresentable {
//
// var sourceType: UIImagePickerController.SourceType = .photoLibrary
//
// @Binding var selectedImage: [UIImage]
// @Environment(\.presentationMode) private var presentationMode
//
// func makeUIViewController(context: UIViewControllerRepresentableContext<CameraPicker>) -> UIImagePickerController {
//
// let imagePicker = UIImagePickerController()
// imagePicker.allowsEditing = false
// imagePicker.sourceType = sourceType
// imagePicker.delegate = context.coordinator
//
// return imagePicker
// }
//
// func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<CameraPicker>) {
//
// }
//
// func makeCoordinator() -> Coordinator {
// Coordinator(self)
// }
//
// final class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
//
// var parent: CameraPicker
//
// init(_ parent: CameraPicker) {
// self.parent = parent
// }
//
// func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
//
// if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
// parent.selectedImage.append(image)
// }
//
// parent.presentationMode.wrappedValue.dismiss()
// }
// }
//}
//
//struct ImagePicker: UIViewControllerRepresentable {
// func makeCoordinator() -> Coordinator {
// return ImagePicker.Coordinator(self)
// }
//
//
// @Binding var images: [UIImage]
// @Binding var picker: Bool
//
// func makeUIViewController(context: Context) -> PHPickerViewController {
// var config = PHPickerConfiguration()
// config.filter = .images
// config.selectionLimit = 0
// let picker = PHPickerViewController(configuration: config)
// picker.delegate = context.coordinator
// return picker
// }
//
// func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) {
// // nop
// }
//
// class Coordinator: NSObject, PHPickerViewControllerDelegate {
// let parent: ImagePicker
//
// init(_ parent1: ImagePicker) {
// self.parent = parent1
// }
//
// func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
// parent.picker.toggle()
// for img in results {
// if img.itemProvider.canLoadObject(ofClass: UIImage.self) {
// img.itemProvider.loadObject(ofClass: UIImage.self) { (image, error) in
// guard let image1 = image else {
// print(error)
// return
// }
//// DispatchQueue.main.async {
//// self.parent.images.append(image as! UIImage)
//// }
// self.parent.images.append(image as! UIImage)
//
// }
// } else {
// print("cannot be loaded")
// }
// }
// }
// }
//}

View File

@ -61,10 +61,6 @@ class Api {
ResponseData.shared.imageData = new_image
PlatesList.shared.imagesList.append(LicensePlateItem(image: new_image))
// using UserDefaults
// PlatesList.shared.imagesBase64List.append(myUIImage!.base64!)
// UserDefaults.standard.set(PlatesList.shared.imagesBase64List, forKey: "platesList")
ResponseData.shared.uiImageData = myUIImage!
self.getPlatsNumberResponse(image: image) { res in
if res == true {
@ -105,9 +101,6 @@ class Api {
let allReplies = try JSONDecoder().decode(PlatesNumberItem.self, from: jsonData!)
if allReplies.platesNumber != ["None"] {
// responseData = responseData.replacingOccurrences(of: "b'", with: "")
// responseData = String(responseData.replacingOccurrences(of: "\'", with: ""))
// responseData = responseData.fixedBase64Format
for n in allReplies.platesNumber {
PlatesList.shared.platesNumberList.append(n)
@ -115,17 +108,6 @@ class Api {
UserDefaults.standard.set(PlatesList.shared.platesNumberList, forKey: "platesList")
// let myUIImage = responseData.imageFromBase64
// let image = Image(uiImage: myUIImage!)
// ResponseData.shared.imageData = image
// PlatesList.shared.imagesList.append(LicensePlateItem(image: image))
// using UserDefaults
// PlatesList.shared.imagesBase64List.append(myUIImage!.base64!)
// UserDefaults.standard.set(PlatesList.shared.imagesBase64List, forKey: "platesList")
// ResponseData.shared.uiImageData = myUIImage!
completion(true)
} else {
completion(false)

View File

@ -12,8 +12,5 @@ class PlatesList : ObservableObject {
@Published var imagesList: [LicensePlateItem] = [LicensePlateItem]()
@Published var platesNumberList: [String] = UserDefaults.standard.stringArray(forKey: "platesList") ?? [String]()
// using UserDefaults
// @Published var imagesBase64List: [String] = UserDefaults.standard.stringArray(forKey: "platesList") ?? [String]()
static let shared = PlatesList()
}

View File

@ -26,130 +26,120 @@ struct ContentView: View {
private let apiManager = Api()
var body: some View {
ZStack {
NavigationView {
VStack {
NavigationLink(destination: ResultView(), tag: "Success", selection: $selection) { EmptyView() }
Spacer()
if image != nil {
HStack {
Spacer()
image?.resizable()
.scaledToFit()
.cornerRadius(10)
.padding(.bottom, 10)
.onTapGesture {
openCamera()
}
Image(systemName: "minus.circle")
.foregroundColor(Color(.red))
.padding(5)
.onTapGesture {
withAnimation(.easeOut) {
image = nil
inputImage = nil
disabledButton = true
}
}
Spacer()
}
} else {
HStack {
Spacer()
VStack {
Image(systemName: "plus.circle.fill")
.font(.system(size: 40))
.foregroundColor(Color(colorScheme == .dark ? .white : .black))
.padding(.top, 5)
.onTapGesture {
self.showingImagePicker = true
}
.padding()
Text("Choose a photo\n from the library")
.multilineTextAlignment(.center)
}
Spacer()
VStack {
Image(systemName: "camera.fill")
.font(.system(size: 40))
.foregroundColor(Color(colorScheme == .dark ? .white : .black))
.padding(.top, 5)
.onTapGesture {
isPresented.toggle()
}
.padding()
Text("Take a photo\n with a camera")
.multilineTextAlignment(.center)
}
Spacer()
}
.padding()
}
if disabledButton == false {
Button {
wait.wait = true
apiManager.getImageResponse(image: inputImage!.base64!) { res in
if res == true {
selection = "Success"
wait.wait = false
image = nil
inputImage = nil
disabledButton = true
} else {
wait.wait = false
notDetected.toggle()
image = nil
inputImage = nil
disabledButton = true
}
}
} label: {
Text("Detect license plate")
}
.disabled(disabledButton)
.padding(.horizontal, 30)
.padding(.vertical, 5)
// .background(Color(colorScheme == .dark ? .white : .black))
.cornerRadius(40)
.foregroundColor(Color(colorScheme == .dark ? .white : .black))
.padding(5)
.overlay(RoundedRectangle(cornerRadius: 40).stroke(Color(colorScheme == .dark ? .white : .black), lineWidth: 2.0))
.padding()
}
Spacer()
}
.alert("Please take a photo horizontally", isPresented: $isPresented) {
Button("OK", role: .cancel) {
NavigationView {
VStack {
NavigationLink(destination: ResultView(), tag: "Success", selection: $selection) { EmptyView() }
Spacer()
if image != nil {
HStack {
Spacer()
image?.resizable()
.scaledToFit()
.cornerRadius(10)
.padding(.bottom, 10)
.onTapGesture {
openCamera()
}
Image(systemName: "minus.circle")
.foregroundColor(Color(.red))
.padding(5)
.onTapGesture {
withAnimation(.easeOut) {
image = nil
inputImage = nil
disabledButton = true
}
}
Spacer()
}
} else {
HStack {
Spacer()
VStack {
Image(systemName: "plus.circle.fill")
.font(.system(size: 40))
.foregroundColor(Color(colorScheme == .dark ? .white : .black))
.padding(.top, 5)
.onTapGesture {
self.showingImagePicker = true
}
.padding()
Text("Choose a photo\n from the library")
.multilineTextAlignment(.center)
}
.alert("No license plate detected, find another photo", isPresented: $notDetected) {
Button("OK", role: .cancel) {
// do nothing
Spacer()
VStack {
Image(systemName: "camera.fill")
.font(.system(size: 40))
.foregroundColor(Color(colorScheme == .dark ? .white : .black))
.padding(.top, 5)
.onTapGesture {
isPresented.toggle()
}
.padding()
Text("Take a photo\n with a camera")
.multilineTextAlignment(.center)
}
Spacer()
}
.padding()
}
if disabledButton == false {
Button {
wait.wait = true
apiManager.getImageResponse(image: inputImage!.base64!) { res in
if res == true {
selection = "Success"
wait.wait = false
image = nil
inputImage = nil
disabledButton = true
} else {
wait.wait = false
notDetected.toggle()
image = nil
inputImage = nil
disabledButton = true
}
}
}
.sheet(isPresented: $showingImagePicker, onDismiss: loadImage) {
ImagePicker(image: self.$inputImage)
}
.sheet(isPresented: $showingCameraPicker, onDismiss: loadImage) {
CameraPicker(sourceType: .camera, selectedImage: self.$inputImage)
}
if wait.wait {
GeometryReader { _ in
LoaderView().frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
} label: {
Text("Detect license plate")
}
.disabled(disabledButton)
.padding(.horizontal, 30)
.padding(.vertical, 5)
// .background(Color(colorScheme == .dark ? .white : .black))
.cornerRadius(40)
.foregroundColor(Color(colorScheme == .dark ? .white : .black))
.padding(5)
.overlay(RoundedRectangle(cornerRadius: 40).stroke(Color(colorScheme == .dark ? .white : .black), lineWidth: 2.0))
.padding()
}
.background(Color.black.opacity(0.45))
.edgesIgnoringSafeArea(.all)
Spacer()
}
.alert("Please take a photo horizontally", isPresented: $isPresented) {
Button("OK", role: .cancel) {
openCamera()
}
}
.alert("No license plate detected, find another photo", isPresented: $notDetected) {
Button("OK", role: .cancel) {
// do nothing
}
}
}
.sheet(isPresented: $showingImagePicker, onDismiss: loadImage) {
ImagePicker(image: self.$inputImage)
}
.sheet(isPresented: $showingCameraPicker, onDismiss: loadImage) {
CameraPicker(sourceType: .camera, selectedImage: self.$inputImage)
}
}
@ -169,12 +159,6 @@ struct ContentView: View {
image = Image(uiImage: inputImage)
disabledButton = false
}
func convertImageToBase64String(inputImage: UIImage?) -> String {
guard let imageData = inputImage?.jpegData(compressionQuality: 0.3) else { return ""}
let res = imageData.base64EncodedString()
return res
}
}
struct ContentView_Previews: PreviewProvider {
@ -183,21 +167,6 @@ struct ContentView_Previews: PreviewProvider {
}
}
extension UIImage {
var base64: String? {
self.jpegData(compressionQuality: 1)?.base64EncodedString()
}
}
extension String {
var imageFromBase64: UIImage? {
guard let imageData = Data(base64Encoded: self, options: .ignoreUnknownCharacters) else {
return nil
}
return UIImage(data: imageData)
}
}
struct ImageOverlay: View {
var number: String
@ -217,3 +186,18 @@ struct ImageOverlay: View {
}
}
}
extension UIImage {
var base64: String? {
self.jpegData(compressionQuality: 1)?.base64EncodedString()
}
}
extension String {
var imageFromBase64: UIImage? {
guard let imageData = Data(base64Encoded: self, options: .ignoreUnknownCharacters) else {
return nil
}
return UIImage(data: imageData)
}
}

View File

@ -10,25 +10,37 @@ import SwiftUI
struct MenuView: View {
@Environment(\.colorScheme) var colorScheme
@ObservedObject var wait = Wait.shared
var body: some View {
TabView {
ContentView()
.tabItem {
Image(systemName: "camera")
.foregroundColor(Color(colorScheme == .dark ? .white : .black))
Text("Photo")
.foregroundColor(Color(colorScheme == .dark ? .white : .black))
}
PlatesListView()
.tabItem {
Image(systemName: "list.dash")
.foregroundColor(Color(colorScheme == .dark ? .white : .black))
Text("History")
.foregroundColor(Color(colorScheme == .dark ? .white : .black))
ZStack {
TabView {
ContentView()
.tabItem {
Image(systemName: "camera")
.foregroundColor(Color(colorScheme == .dark ? .white : .black))
Text("Photo")
.foregroundColor(Color(colorScheme == .dark ? .white : .black))
}
PlatesListView()
.tabItem {
Image(systemName: "list.dash")
.foregroundColor(Color(colorScheme == .dark ? .white : .black))
Text("History")
.foregroundColor(Color(colorScheme == .dark ? .white : .black))
}
}
.accentColor(Color(colorScheme == .dark ? .white : .black))
if wait.wait {
GeometryReader { _ in
LoaderView().frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
}
.background(Color.black.opacity(0.45))
.edgesIgnoringSafeArea(.all)
}
}
.accentColor(Color(colorScheme == .dark ? .white : .black))
}
}

View File

@ -25,16 +25,10 @@ struct PlatesListView: View {
.resizable()
.scaledToFit()
.overlay(ImageOverlay(item), alignment: .trailing)
// item.image
// .resizable()
// .scaledToFit()
// .padding()
}
.onDelete(perform: removeRows)
}
}
}
.toolbar {
@ -50,53 +44,17 @@ struct PlatesListView: View {
.alert(isPresented: $isPresented, content: {
Alert(title: Text("Do you want to delete the history?"),
primaryButton: .default(Text("No")){
},
},
secondaryButton:.default(Text("Yes")) {
UserDefaults.standard.set([String](), forKey: "platesList")
imagesList.platesNumberList = UserDefaults.standard.stringArray(forKey: "platesList") ?? [String]()
})
UserDefaults.standard.set([String](), forKey: "platesList")
imagesList.platesNumberList = UserDefaults.standard.stringArray(forKey: "platesList") ?? [String]()
})
})
// using UserDefaults
// VStack {
// if imagesList.imagesBase64List.isEmpty {
// Text("No history")
// } else {
// List {
// ForEach(imagesList.imagesBase64List, id: \.self) { item in
// Image(uiImage: item.imageFromBase64!)
// .resizable()
// .scaledToFit()
// .padding()
//
// }
// }
//
// }
// }
// using UserDefaults
// .toolbar {
// ToolbarItem(placement: .navigationBarLeading) {
// Button {
// isPresented.toggle()
// } label: {
// Image(systemName: "trash")
// }
// }
// }
}
// using UserDefaults
// .alert(isPresented: $isPresented, content: {
// Alert(title: Text("Do you want to delete the history?"),
// primaryButton: .default(Text("No")){
// },
// secondaryButton:.default(Text("Yes")) {
// UserDefaults.standard.set([String](), forKey: "platesList")
//// imagesList.imagesBase64List = UserDefaults.standard.stringArray(forKey: "platesList") ?? [String]()
// })
// })
}
func removeRows(at offsets: IndexSet) {
imagesList.platesNumberList.remove(atOffsets: offsets)
UserDefaults.standard.set(imagesList.platesNumberList, forKey: "platesList")
}
}