sharedApplication() Doesn't working in Today Extension in swift - ios

i'm new to swift, i have created a today widget , and i added a button to that. in the Action of that button, i want to launch a url in safari, but "sharedApplication( )" doesn't working, i'm using this code in Normal view controller :
override func viewDidLoad() {
super.viewDidLoad()
UIApplication.sharedApplication().openURL(NSURL(string: "facetime:mahdi#gmail.com")!)
// Do any additional setup after loading the view, typically from a nib.
}
but its not working in Today App Extension.

You can't use sharedApplication from an app extension.
Today widgets can open urls using the openUrl:completionHandler: method on NSExtensionContext, so you could do:
extensionContext?.openURL(NSURL(string: "facetime:mahdi#gmail.com")!, completionHandler: nil)
You should be doing this in the tap handler for your button though, not in viewDidLoad.
But note that the apple documentation states:
IMPORTANT
Apple allows any Today widget to use the
openURL:completionHandler: method to open the widget’s own containing
app.
If you employ this method to open other apps from your Today widget,
your App Store submission might entail additional review to ensure
compliance with the intent of Today widgets.
To learn more, read App Store Review Guidelines and iOS Human
Interface Guidelines, linked to from Apple’s App Review Support page

This is well documented. There is no sharedApplication() in a Today extension; the code isn't running in your app. In this particular situation, you can communicate with the NSExtensionContext instead.

Related

How to Combine an Ionic App with native iOS app and behave like one app?

I have an ionic 3 app currently listed on the app store. I have created a native caller app using Swift and agora SDK, where I will have a video streaming using RTC. In the caller app, I need the channelID to initialize the streaming.
I have the functionality to get the call in the first app. My only job to while accepting the call in the first app I need to open the second app and pass the channelID. In the second app, I need to fetch the channelID and proceed with the streaming.
I can just make the second app a different app, open from the first app using Deepkinking. But in this case, the user needs to download two separate apps.
But I have heard the term Combined apps in iOS. Where the user needs to download the only main app and the second caller app will work as a shadow app. The caller app will not be visible in the app list in the device or not needed to download separately.
Please suggest me any solution for this,
how to combine these two apps?
How to parse the channelID from the first app to the caller app and how to catch the channelID in the caller app?
// caller app ViewController
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let storyBoard = UIStoryboard(name: "Main", bundle: Bundle.main)
let viewController = storyBoard.instantiateViewController(identifier:
"VideoChatViewController") as? VideoChatViewController
viewController?.channelID = "hello-video"
// I want to make this channelID to be dynamic which will come from the first app.
self.navigationController?.pushViewController(viewController!, animated: true)
// Do any additional setup after loading the view.
}
}
I have to make the caller app a native app as iOS 13 has stopped different APIs for webrtc. And ionic is reliable on web views. But I can not make the whole app in native now. So I have decided to make the caller part only in native and combine two related apps to One app.

Posting to correct Instagram Account with UIActivityViewController

I am using UIActivityViewController to post images to Instagram app from MY app.
Please note my app does not use Instagram API or log in to users' Instagram Account.
let sharingImage = button.backgroundImage(for: [])
let avc = UIActivityViewController(activityItems: [sharingImage as AnyObject], applicationActivities: nil)
avc.excludedActivityTypes = [.addToReadingList,.airDrop,.assignToContact,.copyToPasteboard,.openInIBooks,.postToFacebook,.postToFlickr,.postToTencentWeibo,.postToTwitter,.postToVimeo,.postToWeibo,.saveToCameraRoll,.message,.mail,.print]
if let wPPC = avc.popoverPresentationController {
wPPC.sourceView = followUsButton
}
self.present(avc, animated: true, completion: nil)
I am logged into my Instagram App with multiple accounts. Upon share from MY app, Instagram tries to post to the account 'A' which is currently logged in (inside the Instagram app). This makes sense.
However, if I now switch to the Instagram app and switch to account 'B' inside it, go back to MY app and then try to share again, it continues to try to post to Account 'A'.
The only way to fix it, is to kill MY app and start it again and then it loads the correct currently logged in account 'B'.
Is there a way to programmatically reload the correct Insta account while sharing?
This is only a workaround however might be your only choice at the moment as you see that even native Photos has the same issue so it is rather down to Apple to fix it.
In your application's Info.plist, add a boolean key UIApplicationExitsOnSuspend with the value YES. See the Information Property List Key Reference for more information.
This way the app is getting terminated when enters a background state and once you go back to it it will get reloaded. The user might not notice the difference.
Perhaps before killing the app you could add some interface state saving function in:
optional func applicationWillTerminate(_ application: UIApplication)
I don't know how your app is laid out but you could create a singleton class which could be implementing Codable and keep tracking all the app state variables which would have a save and load function. Saving would be triggered upon termination and loading when app is launching.
I hope it will help in some way.
EDIT1: Should work in iOS 13
Below this code should work and terminate your app however it is not recommended and you might face an issue when uploading to AppStore. I guess you can challenge the rejection with the Apple review team by explaining that they have a bug in the SDK and point them to the problem.
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
UIApplication.shared.perform(#selector(NSXPCConnection.suspend))
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
exit(0)
}
}
Short answer, I doubt.
UIActivityViewController doesn't give you control over the user's login status (which is why it's interesting to use). IMO, that's a bug on Apple side. So, unless there's a secret way to clear the authorisation tokens that the iOS runtime has stored within your app memory, I don't see how you could possibly achieve what you want.
Plus, if Photos app has the same behaviour, that's not a good sign...
Just in case, when you say that the problem occurs when switching accounts, do you mean
In MY app, you immediately try to post from the same ViewController?
You move to a parent View (hence destroying the old one)back , then to the same view as 1/?
Do you have the same result in both case? I am asking because when instantiating a new UIActivityViewController in a new view, the runtime might fetch the new user login profile, while if you instantiate it from the same view that was used to post from the old account, it might not do so (hence it'll use the old login)
This is iOS issue not specific to your app.

Open application on button tapped with Bundle Identifier (Without url scheme)

I'm currently developing an app and i'm trying to add a button which would open another app installed on my phone when the button is tapped
I've tried looking for the URL scheme for the app but i can't find it. Only thing i can find is the bundle ID. So i thought maybe there's a way to use the bundle ID to open the app through private APIs in Swift? My phone is jailbroken if that helps. Below is my code
#IBAction func openAppTapped(_ sender: Any) {
UIApplication.shared.openURL(NSURL(string: "itms-apps://itunes.apple.com/us/app/apspace/id1413678891?mt=8")! as URL)
}
I managed to upon the app on the appstore upon tapping the button but i want a way to open the app directly without using url schemes but instead using the bundle id and/or private APIs. Any help would be really really appreciated!
To open another app, you are either going to have to use some kind of extension provided by that app or figure out their URL scheme and reverse engineer it.
The first thing you could try is looking at the app's Info.plist and seeing if they have defined a URLScheme for their app. If not, and they haven't implemented an extension, then I think you're SOL.
If they did define it, try using it to open their app and see what happens, they might have some code that rejects or accepts a request to open their app based on the format of the URL after their scheme. If you can't figure it out with trial and error, you could use the fact that your phone is jailbroken to decompile their app and hunt down the URL parsing logic which is likely in their AppDelegate. From there you could try and build a URL that you can use to successfully open their app every time.

Share extension to share a number from recent calls

Working on the first swift app, and stuck in "share extension". Trying to share a phone number from recent calls log to an app for background task.
Thought to do it in this way, once user enter profile of a number from recent call log:
Will see the icon of my app:
Now want to get the phone number and the country code to do that task, current code is:
class ShareViewController: UIViewController {
override func viewDidLoad() {
// Want to get selected phone number only and print it on the console for testing
print("Test\n")
}
}
How to do that?
Thanks in advance
Your App's icon is used. From Apples documentation:
In iOS, a custom Action extension uses a template image version of its containing app’s icon, which you must provide.
iOS Share extensions automatically employ the containing app’s icon. If you provide a separate icon in your Share extension target, Xcode ignores it. For all other app extension types, you must provide an icon that matches the containing app’s icon.

Change Safari URL with App Extension

When the icon of my Safari app extension icon is touched, I want to change the URL without showing a new view. Doing this comes down to two issues:
How can I use an safari app extension without showing a new view? I just want to perform a background action when the extension icon is pressed.
How can I change the current URL in Safari?
Actually, you might be able to change the URL at the finalize function of your ExtensionPreprocessingJS file
// Note that the finalize function is only available in iOS.
finalize: function(arguments) {
// arguments contains the value the extension provides in
[NSExtensionContext completeRequestReturningItems:completion:].
// In this example, the extension provides a color as a returning item.
document.URL = arguments["newUrl"];
}
It seems like what you're describing is a bookmark, and not an app extension. I would highly doubt that app extensions would allow you to interface with Safari and update the URL, this would be wrong in many regards, including privacy and security. In short, not possible (sorry).

Resources