I'm developing an App that it's data is from a URL, here's a sample code that I'm using
AppDelegate.swift
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var fromUrl: String!
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject)-> Bool {
print("Host: \(url.host!)")
self.fromUrl = url.host!
return true
}
ViewController.swift
import UIKit
class ViewController: UIViewController {
let appDelegate = AppDelegate()
override func viewDidLoad() {
super.viewDidLoad()
print(appDelegate.fromUrl)
}
It's is logging the url.host from app delegate. But when i try to log the value of fromUrl from the ViewController.swift it's returning nil. What do you think seems to be the problem? Thanks!
When you declare let appDelegate = AppDelegate() in ViewController you are actually instantiating another instance of AppDelegate. That is not the same instance that you are using as you actual ApplicationDelegate. Try getting that reference by using:
if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate {
print(appDelegate.fromUrl)
}
Related
I am creating a custom framework. I need a reference to the AppDelegate to perform operations e.g get window or some other delegates.
example code:
static var safeArea: UIEdgeInsets {
var padding: UIEdgeInsets = UIEdgeInsets.zero
if #available(iOS 11.0, *) {
if let b = appDel.window?.safeAreaInsets {
padding = b
}
}
return padding
}
The main issue I have is that I need the AppDelegate reference on multiple levels.
Any help regarding this should be appreciated.
Sample Source for comments below :). Create a sampleManager inside framework. Import the framework into appdelegate and set SampleManager.shared.delegate to self as weak reference.
public class SampleManager {
public static let shared = SampleManager()
public weak var delegate: UIApplicationDelegate?
func doWhateverYouWant() {
}
}
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
private let dependencyManager = DependencyManager()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
SampleManager.shared.delegate = self
startAppCoordinator()
return true
}
}
I have two test apps: App1 & App2.
App1 takes String from the text field and triggers method:
#IBAction func openApp(sender: AnyObject) {
let url1 = ("app2://com.application.started?displayText="+textToSend.text!)
let url2 = url1.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
UIApplication.sharedApplication().openURL(NSURL(string: url2!)!)
}
Which actually opens App2 which has only label which should change to the text sent through the url, code is within AppDelegate.swift:
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
let url = url.standardizedURL
let query = url?.query
ViewController().labelToDisplayResult.text = query
return true;
}
Unfortunately the line where I am trying to pass result of the URL to the actual label is giving me this error:
EXC_BAD_INSTRUCTION (CODE=EXC_I386_INVOP SUBCODE=0x0)
However I have all the data in the App2 for sure as I can see their values in debugger:
url NSURL "app2://com.application.started?displayText=564315712437124375" 0x00007fa4e3426320
query String? "displayText=564315712437124375"
Any idea why I am getting this error?
Thanks...
Your error
ViewController().labelToDisplayResult.text = query
ViewController() Create a new instance of ViewController,not the one loaded from storyboard.I guess labelToDisplayResult is an outlet, so it is nil,so you get EXC_BAD_INSTRUCTION (CODE=EXC_I386_INVOP SUBCODE=0x0)
This is what I usually do to handle openURL scheme,need to think about two states:
Target App is launched before,so when open url happen,the target app is in background or inactive state
Target App is not launched,so when open url happen,the target app is not running at all
In Appdelegate
class AppDelegate: UIResponder, UIApplicationDelegate {
var openUrl:NSURL? //This is used when to save state when App is not running before the url trigered
var window: UIWindow?
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
let url = url.standardizedURL
NSNotificationCenter.defaultCenter().postNotificationName("HANDLEOPENURL", object:url!)
self.openUrl = url
return true;
}
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
return true
}
}
Then in the ViewController handle openURL
class ViewController: UIViewController {
#IBOutlet weak var testLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleOpenURL:", name:"HANDLEOPENURL", object: nil)
let delegate = UIApplication.sharedApplication().delegate as? AppDelegate
if let url = delegate?.openUrl{
testLabel.text = url.description
delegate?.openUrl = nil
}
}
func handleOpenURL(notification:NSNotification){
if let url = notification.object as? NSURL{
testLabel.text = url.description
}
}
deinit{
NSNotificationCenter.defaultCenter().removeObserver(self, name: "HANDLEOPENURL", object:nil)
}
}
Using: XCode 7, iPhone 5 (iOS 8.3), WiFi, Reachability (check the internet connection).
While my app is in background and I click to open my app it checks the conncetion and load some functions and in 1 of the functions I try to sign:
imageView.image = UIImage(named: "imagename")
error: fatal error: unexpectedly found nil while unwrapping an Optional value
This happens only when my app change an IBOutlet value in applicationWillEnterForeground with function to primary view controller
self.viewController.functionName()
class AppDelegate: UIResponder, UIApplicationDelegate {
var viewController:ViewController = ViewController()
func applicationWillEnterForeground(application: UIApplication) {
self.viewController.checkConn()
}
}
checkConn() check the connection with Reachability and change IBOutlets values like .image and .text
Is there any way to fix it?
After a lot of tests I found this method which works great:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var viewController:ViewController?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
viewController = self.window!.rootViewController as? ViewController
return true
}
func applicationWillEnterForeground(application: UIApplication) {
viewController!.checkConn()
}
}
I am assuming that this is where your crash is happening.
imageView.image = UIImage(named: "imagename")
If you are using "Images.xcassets" to manage your image files. Make sure that "imagename" exists.
I am integrating chartboost into my sprite kit game and have successfully integrated bridging files into my swift code. Now in my app delegate I have the following:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
let kChartboostAppID = "5554c8680d60255c6a0f4af4"
let kChartboostAppSignature = "1d0e271cd054c9a63473d2f1212ca33a2922a19f"
Chartboost.startWithAppId(kChartboostAppID, appSignature: kChartboostAppSignature, delegate: self)
Chartboost.cacheMoreApps(CBLocationHomeScreen)
return true
}
class func showChartboostAds()
{
Chartboost.showInterstitial(CBLocationHomeScreen);
}
func didFailToLoadInterstitial(location: String!, withError error: CBLoadError) {
}
the startWithId line gives me an error that it cant invoke this method with these arguments ( String, String, AppDelegate). This used to work fine on my objective c code.. Anyone knows how to fix this?
class AppDelegate: UIResponder, UIApplicationDelegate, ChartboostDelegate
Edit (from Lalit's comment below)
In startWithAppId the delegate is set to self, so you have to set the class AppDelegate as the delegate, which is done using:
ChartboostDelegate(protocol)
I have an AVAudioPlayer set up in my AppDelegate to play on startup. It continues playing throughout the app, but when I try to stop or play the player in a different class, the app crashes with EXC_BAD_ACCESS on that line.
AppDelegate.swift
import AVFoundation
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var path = NSBundle.mainBundle().pathForResource("backgroundMusic", ofType: "wav")
var soundTrack = AVAudioPlayer()
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
soundTrack = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: path), error: nil)
soundTrack.numberOfLoops = -1
soundTrack.volume = 0.35
soundTrack.play()
return true
}
OtherClass.swift
func aFunction() {
let appDelegate = AppDelegate()
appDelegate.soundTrack.stop() //Here is where the app crashes. Same with .play()
}
Thanks for any help!
by doing AppDelegate() you are creating a new instance of app delegate; one which the variables haven't been initiated. You want to get the UiApplications shared delegate:
let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate