I am usin swiftUI . I have one view name MyView. I want to call LoginViewModel class method which is in the another folder. When I try to call the class, it shows Cannot find 'LoginViewModel' in scope. But when I declare the class in MyView class, it is working fine.
Here is the image of MyView:
Here is the code LoginViewModel class code which is in view_model folder.
import Foundation
import UIKit
class LoginViewModel {
func doLogin(`var` parameters: [String: Any]){
...
}
}
What is the wrong with this?
grate ! you put you your class to another folder, I am sure the folder is not in same target where your MyView in .
include LoginViewModel.swift to same target as MyView or make a class on same folder .
Related
The execution of this code is confusing me:
class RecipeListViewModel: ObservableObject {
#Published var recipeList = [RecipeViewModel]()
init(){
RecipeRepository.$allRecipeVMs.map { recipes in
recipes.map { recipe in
recipe
}
}
.assign(to: &$recipeList)
}
}
My understanding was that SwiftUI publishers are uni-directional, meaning that when RecipeRepository.allRecipeVMs is modified recipeList is too. However, the behaviour I'm seeing is that When recipeList is updated, RecipeRepository.allRecipeVMs is also updated. I've tried to find documentation on this but can't seem to find anything.
Here is the RecipeViewModel class, not sure if it's useful:
class RecipeViewModel : Identifiable, ObservableObject, Hashable{
var id = UUID().uuidString
#Published var recipe: Recipe
init(recipe: Recipe){
self.recipe = recipe
}
}
It's not clear what "modifications" you are calling. #Published and SwiftUI views diff value types, whereas you've created an array of reference types. It will diff only when the instance of that object changes, not when the object itself fires its ObjectWillChange publisher.
Frankly, that's a pretty useful setup because you can have containers that distribute and manage dependencies in your app without causing the root view hierarchy to diff and rebuild constantly.
If you want some sort of two-way Delegate relationship, you can simply set a weak variable in the VMs to self.
I am running a SwiftUI app (Xcode 12.3) using the App approach:
#main
struct ThingsApp: App {
...
}
This works as expected both on simulators and my device. But it does not work in previews: There, I get the error of 'main' attribute cannot be used in a module that contains top-level code.
There must be something about my app that's causing it, since if I set up a project from scratch in Xcode, this approach works. But I don't quite know how to figure out what exactly would cause this. Fuller trace below:
'main' attribute cannot be used in a module that contains top-level code
----------------------------------------
CompileDylibError: Failed to build ThingsApp.swift
Compiling failed: 'main' attribute cannot be used in
a module that contains top-level code
/Users/cg/Library/Developer/Xcode/DerivedData/
Things-bkpepcogttixysdvumdszlfwxfix/Build/
Intermediates.noindex/
Previews/Things/Intermediates.noindex/Things.build/
Debug-iphonesimulator/Things.build/Objects-normal/x86_64/
ThingsApp.2.preview-thunk.swift:8:1: error: 'main'
attribute cannot be used in a module that contains top-level code
#main extension ThingsApp {
^
/Users/cg/Library/Developer/Xcode/DerivedData/
Things-bkpepcogttixysdvumdszlfwxfix/Build/
Intermediates.noindex/
Previews/Things/Intermediates.noindex/
Things.build/
Debug-iphonesimulator/Things.build/
Objects-normal/x86_64/
ThingsApp.2.preview-thunk.swift:1:1: note: top-level code defined in this source file
#_private(sourceFile: "ThingsApp.swift") import Things
For me it was a top level class type I created in the App extension:
#main
struct MyApp: App {
var body: some Scene {}
class AppDelegate: NSObject, UIApplicationDelegate {...}
}
Once I move it outside and did a clean build, previews worked again:
#main
struct MyApp: App {
var body: some Scene {...}
}
private class AppDelegate: NSObject, UIApplicationDelegate {...}
if you are using environment your code should look like this
#main
struct YourApp: App {
#StateObject private var someData = SomeData()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(someData)
}
}
}
'ContentView_Previews' does not compile if ContentView references an external object.
If I remove all references to #ObservedObject, preview compiles.
import SwiftUI
struct ContentView: View {
#ObservedObject var fancyTimer = FancyTimer()
var body: some View {
Text("\(fancyTimer.timerValue)")
.font(.largeTitle)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
import Foundation
import SwiftUI
import Combine
class FancyTimer: ObservableObject {
#Published var timerValue: Int = 0
init() {
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true)
{ timer in
self.timerValue += 1
}
}
}
Error is: 'ContentView' is not a member type of 'FancyTimer'
Often the problem is that you created a class, a struct, or enum that has the same name as the module you are in.
Here, odds are that "FancyTimer" is also the name of your project, which triggers the error.
Try to change the class name.
Changing display name and bundle identifier in general settings fixed this issue for me in Xcode 11.1.
I just ran into this, and clicking the "Diagnostics" button on the Preview panel showed me the problem. Is your project called "FancyTimer"? If so, what is happening is that the compiler is trying to reference FancyTimer.ContentView_Previews, and is failing because it's not a sub-type of that class. Basically you're getting a conflict between project name and class name.
My projectname was the same as one of the Foundation's classes. Changing the Projectname fixed the issue.
Issue seems to be gone in Xcode 11 GM Seed 2
According to wwdc 17 there is a way to observe cookies changes in WKWebView in iOs 11 (WebsiteDataStore.httpCookieStore).
Could you provide example how to do that?
I found that there is WKHTTPCookieStoreObserver and it has cookiesDidChange member.
So i put that protocol as following
class ActivitiesViewController: UIViewController, UIGestureRecognizerDelegate, WKNavigationDelegate, WKHTTPCookieStoreObserver {
and
func cookiesDidChange(in cookieStore: WKHTTPCookieStore) {
but cookiesDidChange not fires (
You must add the view controller as an observer of the web data store to trigger the cookiesDidChange(in:) method.
// These two lines occur in the viewDidLoad method of a UIViewController class
// This view controller conforms to the WKHTTPCookieStoreObserver protocol
WKWebsiteDataStore.default().httpCookieStore.add(self)
let webView = WKWebView()
// Configure and load the web view
Note: In iOS 11.3 a change occurred that requires the WKWebsiteDataStore.default().httpCookieStore.add(self) line to occur before the WKWebView object is created.
I'm trying to use unit test in swift to test some of the real application behaviour.
When i try to cast de UIApplicationDelegate to my AppDelegate from my test function i got and EXC_BAD_ACCESS exception. Below the test code:
func testGetAppDelegate(){
let someDelegate = UIApplication.sharedApplication().delegate
let appDelegate = someDelegate as AppDelegate //EXC_BAD_ACCESS here
XCTAssertNotNil(appDelegate, "failed to get cast pointer")
}
AppDelegate class is set to public so it is not a problem from access level.
Using objective-c in the same test target it works. Below the simple instruction:
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
The debuger says someDelegate is a Builtin.RawPointer. Don't know what that is, i am not familiar with low level details.
I think you added AppDelegate.swift to the tests target members.
When you do that, AppName.AppDelegate and AppNameTests.AppDelegate becomes different classes. Then, UIApplication.sharedApplication().delegate returns AppName.AppDelegate instance, but you are trying to cast it to AppNameTests.AppDelegate type. That causes EXC_BAD_ACCESS.
Instead of that, you have to import it from your application module.
import UIKit
import XCTest
import AppName // <- HERE
class AppNameTests: XCTestCase {
// tests, tests...
}
And, AppDelegate class and its methods and properties must be declared as public to be visible from test module.
import UIKit
#UIApplicationMain
public class AppDelegate: UIResponder, UIApplicationDelegate {
public var window: UIWindow?
public func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
return true
}
// ...
Again, Be sure to remove AppDelegate.swift from the Test target members.
With the Swift 2.0 update, keep using rintaro's solution. But you can simplify it by:
#testable import MyApp
Then you don't need to mark your AppDelegate class as public.
Make certain that your AppDelegate has "UIApplicationDelegate" in it's declaration. That is:
#UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate {
And if you're doing this for iOS, you might need to import UIKit at the top of this file.