我创建了一个名为TermProtocol的协议,其中包含一个名为gotTerm的函数。每当用户按下“我的视图”(CategoryView)中的这个按钮时,委托就应该得到一个回调,并运行我设置的代码。在我的例子中,委托将是AppDelegate。我在app委托中放置了一个名为gotTerm的函数中的print语句,这样我就可以看到代码是否真的在运行,但是我从未在控制台中看到我放在print语句中的短语。我不认为我的代表会被召回。有人能帮我吗?
这是我的代码:
TermProtocol:
protocol TermProtocol: class{
func gotTerm()
}CategoryView.Swift
struct CategoryView: View {
var foodCategory: String
let appDelegate = UIApplication.shared.delegate as? AppDelegate
var delegate: TermProtocol?
var body: some View {
NavigationView {
NavigationLink(destination: RestrauntView()) {
Image("Find Button")
.renderingMode(.original)
}.simultaneousGesture(TapGesture().onEnded{
print("didtapallow 4")
self.appDelegate!.terms = self.foodCategory
self.delegate?.gotTerm()
})
Spacer()
}
}
}
struct CategoryView_Previews: PreviewProvider {
static var previews: some View {
CategoryView(foodCategory: "Chinese Food")
}
}AppDelegate.swift
import UIKit
import CoreData
import Moya
import Alamofire
import CoreLocation
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, TermProtocol {
func gotTerm() {
print("did get term")
let lat = self.locationService.setup(latOrLong: "lat")
let long = self.locationService.setup(latOrLong: "long")
self.locationService.lat = lat
self.locationService.long = long
self.loadBusinesses(lat: lat, long: long, theTerm: self.terms)
}
var theViewModels = [RestrauntListViewModel]()
let locationService = LocationService()
var terms = ""
var categoryView = CategoryView(foodCategory: "indian")
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
categoryView.delegate = self
let dataSource = DataSource()
print("this is the view models in appDelegate: \(theViewModels)")
locationService.didChangeStatus = { [weak self] success in
print("did tap allow 1")
if success {
self?.locationService.getLocation()
}
}
locationService.newLocation = { [weak self] result in
print("did tap allow 2")
switch result {
case .success(let location):
self?.loadBusinesses(lat: location.coordinate.latitude, long: location.coordinate.longitude, theTerm: "chinese")
case .failure(let error):
assertionFailure("Error getting the users location \(error)")
}
}
locationService.setup(latOrLong: "lat")
return true
}
func loadBusinesses (lat: Double, long: Double, theTerm: String) {
let service = MoyaProvider<YelpService.BusinessProvider>()
let jsonDecoder = JSONDecoder()
let restrauntView = RestrauntView()
let appDelegate = AppDelegate()
print("The latitude of u is \(lat) and the long of you is \(long)")
if CLLocationManager.locationServicesEnabled() {
switch CLLocationManager.authorizationStatus() {
case .notDetermined, .restricted, .denied:
print("No access")
case .authorizedAlways, .authorizedWhenInUse:
print("Access")
service.request(.search(lat: lat, long: long, term: theTerm)) { (result) in
switch result{
case.success(let response):
print("yaya")
let root = try? jsonDecoder.decode(Root.self, from: response.data)
let viewModels = root?.businesses.compactMap(RestrauntListViewModel.init)
let dataSource = DataSource()
dataSource.arrayOfImages.removeAll()
for image in viewModels! {
Alamofire.request(image.imageURL).responseImage { response in
if let image = response.result.value {
print("image downloadedline 59 appdelegate")
dataSource.arrayOfImages.append(image)
print(dataSource.arrayOfImages)
} else {
print("ERROR: image does not = response.result.value")
}
}
}
self.theViewModels = (root?.businesses.compactMap(RestrauntListViewModel.init))!
print(" restrauntView.theViewModels is here \(restrauntView.theViewModels)")
print("the constant theViewModels in the appdelegate has \(appDelegate.theViewModels.count) values")
case .failure(let error):
print("Error: \(error)")
}
}
@unknown default:
break
}
} else {
print("Location services are not enabled")
}
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentContainer = {
/*
The persistent container for the application. This implementation
creates and returns a container, having loaded the store for the
application to it. This property is optional since there are legitimate
error conditions that could cause the creation of the store to fail.
*/
let container = NSPersistentContainer(name: "Actrual_Food_Circle")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
// MARK: - Core Data Saving support
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
}发布于 2020-04-06 23:55:48
我将首先声明,您不应该在SwiftUI中以这种方式使用委托和闭包。下面是关于使用SwiftUI - https://nalexn.github.io/clean-architecture-swiftui/的干净的MVVM体系结构的很好的介绍。
我相信您希望添加ViewModel来处理应用程序中的这些状态。
回到回答您的问题--我认为在这种情况下,添加闭包是最快(不一定是正确的)解决方案:
struct ContentView: View {
var gotTermCallback: (()->())?
var body: some View {
NavigationView {
NavigationLink(destination: Text("test")) {
...
}.simultaneousGesture(TapGesture().onEnded{
...
self.gotTermCallback?()
})
...
}
}
}然后,您可以将它添加到某种处理程序或副作用处理程序中,只需调用以下代码:
var contentView: ContentView = ContentView()
contentView.gotTermCallback = {
print("[DEBUG] - terms callback")
}https://stackoverflow.com/questions/61068862
复制相似问题