I want to change isIdleTimerDisabled when a specific view appears. In SwiftUI I use
.onAppear { UIApplication.shared.isIdleTimerDisabled = true } .onDisappear { UIApplication.shared.isIdleTimerDisabled = false }
but even with import UIKit I get the warning "Cannot find 'UIApplication' in scope". How can I fix that? I didn't find a solution after searching for more than an hour.
You should not need to import UIKit, it should work with SwiftUI.
The problem may be your target. Is the file used only on an iOS or iPadOS application target?
Or is it also used, for instance, in an extension, like ShareExtension, and so on?
If it is, you cannot access UIApplication within your code. If this code is shared between extensions and app, you should use conditional compilation to avoid this problem.
Related
I am trying to implement in-app purchases for my app.
import StoreKit
import UIKit
class BuyStoreViewController: UIViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver {
//code
}
However, It keeps giving me the errors "Cannot find type 'SKPaymentTransactionObserver' in scope" and "Cannot find type 'SKProductsRequestDelegate' in scope". I think it has something to do with the implementation of StoreKit, but I am not sure. Additionally, the "SKProductsRequestDelegate" and "SKPaymentTransactionObserver" are greyed out (it does not turn purple like the "UIViewController" does). Does anyone know what to do?
Thanks in advance!
Update: I just had to move all my files to a new project, that worked for me.
I need help understanding when to use #main vs #uiapplicationmain.
From what I know, #uiapplicationmain is an easier way of calling the uiapplicationmain(:::) where the class that is made after #uiapplicationmain is used as the App Delegate. I also know that it also creates an UIApplication.
I also know that app delegate becomes the entry point for the project.
From what I have read I was told that #main is also a entry point but it requires an main function.
What I want to know is what do they mean by the main entry point. Like what is Xcode doing to make it the "entry" point. And how does the whole #main thing work, as in how does it differ from #uiapplicationmain and what is it doing to the way Xcode runs the code.
All code has an entry point: the place where whoever calls that code actually calls. How does the whole program, comprising many Swift files, actually get started? We need an entry point for the whole program, which the runtime will call to launch us.
In Swift, this is the main.swift file. Its job is to call UIApplicationMain, which creates some instances including the app and the app delegate and gets the event loop running (and stays running for the rest of the time the app runs). A minimal main.swift file would have to look like this:
import UIKit
UIApplicationMain(
CommandLine.argc, CommandLine.unsafeArgv, nil,
NSStringFromClass(AppDelegate.self)
)
However, no one ever uses a main.swift file! It's boilerplate, so why bother? Instead, you say #main, and a main.swift file is generated for you behind the scenes. In particular, you put the attribute #main on your AppDelegate class, so the main.swift generator knows which class to instantiate as your application delegate.
Two more things to know:
Before Swift 5.3, #main was called #UIApplicationMain instead. From that point of view, they are identical, two names for the same thing.
New in Swift 5.3 and Xcode 12, you can designate one of your own types as #main and give it a static main function, where you do whatever you would have done in the main.swift file. That is something #UIApplicationMain cannot do:
#main
struct MyMain {
static func main() -> Void {
UIApplicationMain(
CommandLine.argc, CommandLine.unsafeArgv, nil, NSStringFromClass(AppDelegate.self)
)
}
}
#main is part of the new SwiftUI lifecycle, introduced in iOS 14.
#uiapplicationmain is the older version that's part of UISceneDelegate and UIApplicationDelegate, but is still in use. Both represent your app's lifecycle.
I am going nuts I want to use AppStorage only available in iOS 14 (to use it in Widgets)! But I get a Error:
Property wrappers are not yet supported on local properties
I want to integrate the widget in my UIKit App, will be property wrappers available in the future?
For now my nasty Workaround I am making the whole ViewController #available(iOS 14.0, *), but you guessed it now it runs only on iOS 14!
#AppStorage("incomeTotal", store: UserDefaults(suiteName: "group.de.davidkoenig.SimpleMoney"))
var incomeTotal: String = "0.0"
Above you see my code for the AppStorage.
Maybe you can help me!?
I found a way to do safe the object in UIKit:
UserDefaults(suiteName: "group.de.davidkoenig.SimpleMoney")!.set(String(format: "%.2f", sumBalance), forKey: "balanceTotal")
This works and in my SwiftUI file I use the code in my question!
I am developing a Mac app using Swift 4 which only runs as an Agent (it only has a menu in the tray). I'm completely new to Swift.
I want it to respond to keyboard shortcuts, but the basic shortcuts (see picture) only work when the app has focus (in my case, when the menu is being clicked).
So what I need is for my app to respond to system-wide keyboard shortcuts.
I've tried:
HotKey but it doesn't seem to be compatible with Swift 4, or perhaps I can't use Swift Package Manager
this answer but again Swift 4 raises several errors that I couldn't solve
Has anyone done it?
So I ended up getting it to work with HotKey:
by using Carthage as a package manager instead of SPM
and by not using HotKey's example code from their README, which for some reason didn't work for me, but the one in their example app.
It works great!
I made a Swift package that makes this very easy:
import KeyboardShortcuts
extension KeyboardShortcuts.Name {
static let startFiveRounds = Self("startFiveRounds", default: .init(.t, modifiers: [.command, .option]))
}
#main
final class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ notification: Notification) {
KeyboardShortcuts.onKeyUp(for: .startFiveRounds) {
// …
}
}
}
Even though you already solved your problem, I think this could be useful for other people having the same problem.
I would also recommend letting the user pick their own keyboard shortcut instead of hardcoding it. My package comes with a control where the user can set their preferred shortcut.
I have an application written in osx swift, and I need help with a particular behavior/issue. I have the application set to be above all other windows using this code:
self.window!.level = Int(CGWindowLevelForKey(Int32(kCGScreenSaverWindowLevelKey)))
A little issue with it, from what I've seen, is that it does work... but if I go to my launchpad applications menu, the window still shows up. That's exactly how I want the window to behave, but whenever I hit a button within the window, the application resets to the normal desktop to function properly. I have a link below demonstrating this:
https://gyazo.com/f4d05c10ad7b5dbf8b95f3bd2aa23cc4
See how I'm getting taken out of my launchpad and then reset to the normal desktop screen whenever I hit buttons within my application? I just really need to fix this issue.
Is there any info.plist property that I can use to prevent this from happening? Is there any piece of code I could use to make my window use-able everywhere without resetting it to the proper desktop environment? Thanks in advance!
NSFloatingWindowLevel might be a better choice:
import Cocoa
let kCGFloatingWindowLevel: CGWindowLevel =
CGWindowLevelForKey(CGWindowLevelKey.FloatingWindowLevelKey)
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
#IBOutlet weak var window: NSWindow!
func applicationDidFinishLaunching(aNotification: NSNotification) {
self.window!.level = Int(kCGFloatingWindowLevel)
}
}
The window level type you are currently using is primarily meant for screensaver windows. If you want a floating palette or window then using the above should give you the desired behavior.
↳ NSWindow : NSFloatingWindowLevel