Instantly share code, notes, and snippets.
Created
May 10, 2018 17:14
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save dornad/b064dc0d7897fad4cfb0819b81bdf17c to your computer and use it in GitHub Desktop.
Share Extension Spike Gist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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