Skip to content

Instantly share code, notes, and snippets.

@dornad
Created May 10, 2018 17:14
Show Gist options
  • Save dornad/b064dc0d7897fad4cfb0819b81bdf17c to your computer and use it in GitHub Desktop.
Save dornad/b064dc0d7897fad4cfb0819b81bdf17c to your computer and use it in GitHub Desktop.
Share Extension Spike Gist
//
// ViewController.swift
// ShareSpike
//
// Created by Daniel Rodriguez on 5/10/18.
// Copyright © 2018 Daniel Rodriguez. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func onButtonTap(_ sender: UIButton) {
// These come from Flyer JS.
let originalURLStr = "http://www.google.com"
let mappings = [
// Copy To Clipboard
"com.apple.UIKit.activity.CopyToPasteboard" : "utm_campaign=ios_flyer_share_dialog&utm_source=clipboard&utm_content=toolbar",
// Social Networks
"com.apple.UIKit.activity.PostToFacebook": "utm_campaign=ios_flyer_share_dialog&utm_medium=social&utm_source=facebook&utm_content=toolbar", // FB
"com.apple.UIKit.activity.PostToTwitter" : "utm_campaign=flyer_share_dialog&utm_medium=social&utm_source=twitter&utm_content=toolbar", // Twitter
//"??????????????????????????????????????" : "utm_campaign=flyer_share_dialog&utm_medium=social&utm_source=linkedin&utm_content=toolbar", // LinkedIn
// Messaging Apps
"com.apple.UIKit.activity.Message": "utm_campaign=flyer_share_dialog&utm_medium=messaging&utm_source=sms&utm_content=toolbar", // Apple Messages / SMS
// "????????????????????????????????": "utm_campaign=flyer_share_dialog&utm_medium=messaging&utm_source=whatsapp&utm_content=toolbar", // WhatApp
]
let url = URL(string: originalURLStr)!
let activityMapping = FlyerShareManager.buildMapping(url: url, sourceObject: mappings)
FlyerShareManager.share(url: url, supportedActivities: activityMapping, presenter: self)
}
}
typealias SupportedActivityMapping = [String: URL]
class FlyerShareManager: NSObject {
static func share(url:URL, supportedActivities:SupportedActivityMapping, presenter: UIViewController) {
let item = MyActivityProvider(url: url, supportedActivityMapping: supportedActivities)
let shareController = UIActivityViewController(activityItems: [item], applicationActivities: nil)
presenter.present(shareController, animated: true, completion: nil);
}
static func buildMapping(url: URL, sourceObject: [String: String]) -> SupportedActivityMapping {
guard var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true) else { return [:] }
var mapping: SupportedActivityMapping = [:]
sourceObject.forEach { (activityId: String, urlParams: String) in
urlComponents.query = urlParams
if let url = urlComponents.url {
mapping[activityId] = url
}
}
return mapping
}
}
//struct UTMParameters: Codable {
// let campaign: String
// let source: String
// let content: String
// let medium: String?
//
// var urlParameters: String {
// var params: String =
// "?" + CodingKeys.campaign + "=" + campaign +
// "&" + CodingKeys.source + "=" + source +
// "&" + CodingKeys.content + "=" + content
// if let m = medium {
// params = params + ("&" + CodingKeys.medium + "=" + m)
// }
// return params
// }
//
// private enum CodingKeys: String, CodingKey {
// case campaign = "utm_campaign"
// case source = "utm_source"
// case content = "utm_content"
// case medium = "utm_medium"
// }
//}
/// A proxy that provides a list of mappings between share options on a device and the UTM parameters to append.
class MyActivityProvider: UIActivityItemProvider {
/// A dictionary building a list of mappings between share options on a device and the UTM parameters to append.
private var supportedActivityMapping: SupportedActivityMapping = [:]
/// Initialize the ActivityProvider with a URL and the supported activities.
///
/// - Parameters:
/// - url: the URL to use if the user selects an activity that is not currently supported.
/// - activities: A mapping of share extensions identifiers (i.e.: com.example.share.extension) and the final URL
convenience init(url: URL, supportedActivityMapping activities: SupportedActivityMapping) {
self.init(placeholderItem: url, supportedActivityMapping: activities)
}
/// Initialize the ActivityProvider with a placeholder item and the supported activities.
///
/// - Parameters:
/// - item: the placeholder item. This can be anything.
/// - activities: A mapping of share extensions identifiers (i.e.: com.example.share.extension) and URLComponents
convenience init(placeholderItem item: Any, supportedActivityMapping activities: SupportedActivityMapping) {
self.init(placeholderItem: item)
supportedActivityMapping = activities
}
/// Returns the data object to be acted upon.
override func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType _activityType: UIActivityType?) -> Any? {
guard let activityType = _activityType else {
return nil
}
guard let url = self.supportedActivityMapping[activityType.rawValue] else {
print("activity not supported: \(activityType)")
print("Supported activityMapping: \(supportedActivityMapping)")
// not supported, return the original placeholder item
return self.placeholderItem
}
return url
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment