update iOS app
This commit is contained in:
parent
9a1762feb8
commit
90b44a6581
Binary file not shown.
@ -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")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user