How to implement Firebase Google Analytics in custom keyboard? - ios

I want to implement Firebase google analytics in my custom keyboard for button click event.
Anyone please tell me how I can do this in swift.

Add firebase sdk and GoogleService-Info.plist file to keyboard extension target. Import firebase and configure it. FIRApp.configure() must be called only once per session:
import Firebase
class FirebaseConfigurator: NSObject {
static var onceToken: dispatch_once_t = 0
static func configure() {
dispatch_once(&onceToken) {
FIRApp.configure()
}
}
and
FirebaseConfigurator.configure()
FIRAnalytics.logEventWithName("button click event", parameters: nil).

Related

Delegate methods not being called in swift class

I'm integrating an SDK that tracks location points.
The SDK demo app has the SDK framework loaded, and then a UIViewController that extends the SDK delegate. The SDK calls certain delegate functions as the user moves around - these all work fine in the demo app from the SDK provider. All the delegate callback functions, like processStart are inside the TripsViewController: UIViewController, TheSDKSwiftDelegate
Example:
import TheSDKSwift
final class TripsViewController: UIViewController, TheSDKSwiftDelegate {
...
TheSDKSwift.setup(with: configuration, delegate: self, completionHandler: {success, error in
if success {
successBlock()
} else {
failureBlock(error)
}
})
...
// TheSDK Delegate callbacks
func processStart(ofDrive startInfo: DriveStartInfo) {
self.driveStatusLabel.text = "Driving"
if self.isAccidentEnabled() {
self.mockAccidentButton.isEnabled = true
}
let dateString = DateFormatter.shortStyleFormatter.string(from: Date(timeIntervalSince1970: TimeInterval(startInfo.startTimestamp/1000 )))
NotificationManager.displayNotification(message: "Trip Started: \(dateString)")
}
}
So during the normal running of the SDK, it then calls back to the processStart method to provide info on what's happening.
Now, in my own app, I can't have these functions/delegates in UIViewController. I need to have them in a separate Swift file and call the functions from another controller. When I do that, my SDK initializes, but the delegate methods don't get called by the SDK while it's running, whereas the delegate methods DO get called when everything is in on UIViewController extending the delegate. Just not when I put it in my own swift file.
Here's a short snippet of what I'm doing:
import Foundation
import Capacitor
#objc(TheSDKPlugin)
public class TheSDKPlugin: CAPPlugin {
#objc func SetupSDK(_ call: CAPPluginCall) {
TheSDKPluginWrapper().StartSDK()
}
So TheSDKPluginiWrapper().StartSDK() gets called.
import Foundation
import TheSDKSwift
import Capacitor
class TheSDKPluginWrapper: NSObject, TheSDKSwiftDelegate {
...
TheSDKSwift.setup(with: configuration, delegate: self, completionHandler: {success, error in
if success {
successBlock()
} else {
failureBlock(error)
}
})
...
// TheSDK Delegate callbacks
func processStart(ofDrive startInfo: DriveStartInfo) {
self.driveStatusLabel.text = "Driving"
if self.isAccidentEnabled() {
self.mockAccidentButton.isEnabled = true
}
let dateString = DateFormatter.shortStyleFormatter.string(from: Date(timeIntervalSince1970: TimeInterval(startInfo.startTimestamp/1000 )))
NotificationManager.displayNotification(message: "Trip Started: \(dateString)")
}
}
Again, SDK initializes successfully. But now, SDK never calls the delegate method in TheSDKPluginiWrapper().
How do I retain the delegate throughout, so that SDK delegate methods get called in my swift file, same way it gets called when everything is in UIViewController?
If you want the delegate methods in a separate file, you can just define them as an extension to the class:
extension TripsViewController: TheSDKSwiftDelegate {
// TheSDK Delegate callbacks
func processStart(ofDrive startInfo: DriveStartInfo) {
}
...
}

How can I set up Amazon Amplify iOS in Objective-C?

The docs show Swift code only. When trying to use Objective-C, I can't access any of the Amplify libraries. Am I missing an installation step?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
do {
try Amplify.add(plugin: AWSCognitoAuthPlugin())
try Amplify.add(plugin: AWSPinpointAnalyticsPlugin())
try Amplify.configure()
print("Amplify configured with Auth and Analytics plugins")
} catch {
print("Failed to initialize Amplify with \(error)")
}
return true
}
How to do the equivalent in Objective-C?
Yes, crusty old Objective C apps still exist. And they have to be maintained. It really isn't reasonable to expect developers to rewrite them in Swift just so they can use Amplify. I was recently asked to add Amplify to an app built in early 2015 before Swift existed. (Gosh -- are there really apps out there that are over 5 years old?!)
Fortunately, if you can bite the bullet and add Swift support to your Objective C project, it isn't so hard to make a Swift wrapper class that you use from Objective C. Here's one I created for free. It would be nice if the highly paid folks at Amazon would be kind enough to help us out with examples like this.
import Amplify
import AmplifyPlugins
#objc
class AmplifyWrapper: NSObject {
override init() {
super.init()
}
#objc
public func initialize() {
do {
try Amplify.add(plugin: AWSCognitoAuthPlugin())
try Amplify.add(plugin: AWSPinpointAnalyticsPlugin())
try Amplify.configure()
print("Amplify configured with Auth and Analytics plugins")
} catch {
print("Failed to initialize Amplify with \(error)")
}
}
#objc
public func recordEvent(name: String, category: String, accountId: String) {
let properties: AnalyticsProperties = [ "category": category, "accountId": accountId]
let event = BasicAnalyticsEvent(name: name, properties: properties)
Amplify.Analytics.record(event: event)
}
}
Use form Objective C like this:
#import "PutYourAppNameHere-Swift.h"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[[AmplifyWrapper alloc] init] initialize];
...
}
Then later on you can do this:
[[[AmplifyWrapper alloc] init] recordEventWithName:#"App Opened" category:#"Counts" accountId:""];
Am I missing an installation step?
You're not missing anything. Unfortunately there's no Objective-C support on Amplify for iOS. Amplify was built in Swift using its full capabilities and Objective-C support is not currently being considered unless there's a strong demand from the community.
Out of curiosity: are you starting a new app in Objective-C? If so I would be curious to understand why not going with Swift given Apple's investment on Swift lately (Combine, SwiftUI, Swift language updates, etc).
If you're trying to integrate Amplify in an existing Objective-C app, then I'm afraid it won't be possible.

How to handle shared image in my iOS application?

I am building a social networking app just like instagram. In this app you can take a photo and share inside the app.
I wanted to add my app to "share with..." menu inside the gallery.
Currently I added an app extension, and my app appears on that menu.
However what I want to do is, send the selected image to main application and handle it there. (If user is logged in go to post create screen, if not first login then go create screen.)
How to achieve this goal? I tried launching the app with URL schemes but wasn't able to pass selected image.
Here is code so far:
import UIKit
import Social
import MobileCoreServices
class ShareViewController: SLComposeServiceViewController {
let MAX_SHARE_TEXT_LENGTH = 25
override func isContentValid() -> Bool {
// Do validation of contentText and/or NSExtensionContext attachments here
//Validate text.
if let currentMessage = contentText {
let currentMessageLength = currentMessage.characters.count
charactersRemaining = MAX_SHARE_TEXT_LENGTH - currentMessageLength
if Int(charactersRemaining) < 0 {
return false
}
}
return true
}
override func didSelectPost() {
// This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments.
// Inform the host that we're done, so it un-blocks its UI. Note: Alternatively you could call super's -didSelectPost, which will similarly complete the extension context.
self.extensionContext!.completeRequestReturningItems([], completionHandler: nil)
}
override func configurationItems() -> [AnyObject]! {
// To add configuration options via table cells at the bottom of the sheet, return an array of SLComposeSheetConfigurationItem here.
print(extensionContext)
return []
}
}

Unable to get INSendPaymentIntent work with SiriKit on watchOS (3.2 and 4)

I need to finish watchOS sirikit payment app (as a companion app for the iPhone app obviously).
The same framework, logic for intent and handler are working on iOS.
I developed the intent and handler. When I ask Siri the below sentence,
using MyApp send Albert $40
Siri replies...
Sorry I can't do that. and give a button Open MyApp
I saw some posts saying Payment Intent for Siri is not available on watchOS. But I see this in SDK.
Please give pointers.
#available(watchOS 3.2, *)
open class INSendPaymentIntent : INIntent {
public init(payee: INPerson?, currencyAmount: INCurrencyAmount?, note: String?)
#NSCopying open var payee: INPerson? { get }
#NSCopying open var currencyAmount: INCurrencyAmount? { get }
open var note: String? { get }
}
The Plists and projects have right permissions and capabilities.
Payment Intent Plist has the below keys.
Image Link for Plist Keys for Payment Intent
// WatchIntentsExtension.swift
import Intents
import PaymentsFrameworkWatchOS
class WatchIntentsExtension: INExtension {
let paymentProvider = PaymentProvider()
let contactLookup = ContactLookup()
override func handler(for intent: INIntent) -> Any? {
print("Watch Overriding")
guard intent is INSendPaymentIntent else { fatalError("Unhandled intent type \(intent)") }
return WatchSendPaymentIntentHandler(paymentProvider: paymentProvider, contactLookup: contactLookup)
}
}
I cannot post code for Handler as I have compliance issues. And... I do not do much on there.
The same code works for iPhone Siri though.

Cannot call value of non-function type UIApplication when trying to open google maps URL

I'm new to swift programming and I stumbled upon a problem which can't seem to find a solution after searching the web.
What i'm trying to do is when a button is tapped in my application I want the Google maps app to launch but after implementing the code I get the error: Cannot call value of non-function type UIApplication
Am I missing something?
import UIKit
import GoogleMaps
class MapDisplayViewController: UIViewController, GMSMapViewDelegate, CLLocationManagerDelegate, UIApplicationDelegate {
#IBOutlet weak var openDirections: UIButton!
#IBAction func openMapsDirection(_ sender: UIButton!) {
if (UIApplication.sharedApplication().canOpenURL(NSURL(string:"comgooglemaps://")!)) {
UIApplication.sharedApplication().openURL(NSURL(string:
"comgooglemaps://?center=40.765819,-73.975866&zoom=14&views=traffic")!)
} else {
print("Can't use comgooglemaps://");
}
}
}
In Swift 3 sharedApplication() has been replaced with a property called shared.
Try updating your code:
if (UIApplication.shared.canOpenURL(NSURL(string:"comgooglemaps://")!)) {
UIApplication.shared.openURL(NSURL(string:
"comgooglemaps://?center=40.765819,-73.975866&zoom=14&views=traffic")!)
} else {
print("Can't use comgooglemaps://");
}
"comgooglemaps:// and comgooglemaps-x-callback:// - These schemes allow you to launch the Google Maps app for iOS and perform one of several actions"
Please make sure that your device already installed Google Maps app.
https://developers.google.com/maps/documentation/ios-sdk/urlscheme
Hope this will help you.

Resources