Giter Site home page Giter Site logo

xextensionitem's People

Contributors

adriana-elizondo avatar afterxleep avatar arix avatar captphunkosis avatar irace avatar mattbischoff avatar taichino avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xextensionitem's Issues

Should the Core Location dependency be removed?

This library currently has a Core Location dependency as a “location” parameter seems commonly useful enough to warrant inclusion. I can understand developers not wanting to pull this in so am interested in suggestions on how to best structure this. Perhaps a XExtensionItem+Location subspec that augments the core library with these capabilities?

Should XExtensionItemMutableParameters be replaced with a builder class?

Mutability should be avoided. A great way to provide an easy-to-use object creation API is by using the builder pattern.

Unfortunately, many Objective-C developers seem adverse to using builders. As such, the first version of this library includes the XExtensionItemMutableParameters subclass, which allows one to create an XExtensionItemParameters instance without using its initializer (which takes a large number of arguments).

I'd prefer a builder but want this library to be as approachable as possible. The introduction of a builder class means XExtensionItemMutableParameters would be deleted altogether, and XExtensionItemParameters's large initializer would be made private. The only way to get an instance would be to use the builder object and then call build at the end.

Is “XExtensionItem” a good name?

This project was inspired by x-callback-url, and is clearly named as such. Is this a good name or does anyone have an idea for something better?

On one hand, XExtensionItem is:

  • Obvious: The x- prefix has long been used for custom HTTP headers, and x-callback-url continued the tradition. It signifies an unofficial, user-land addition on top of a platform.
  • Transparent: This library is really just a thin wrapper and set of conventions around NSExtensionItem.

On the other hand, XExtensionItem is:

  • Boring
  • Hard to say
  • Not particularly memorable

Project structure should match what `pod lib create` generates

Is two Xcode projects confusing? @Twigz seems to think so. The arguments I can remember him making:

  1. It’s not the default from pod lib create
  2. If you’re working on the library in the normal code → test your code in the sample app workflow, it’s more difficult to run the unit tests.

Allow a default `subject` to be provided

As per @prendio – allow a default subject to be provided rather than explicitly registering subjects for individual activity types using the registerSubject:forActivityType: method added in this pull request.

(This isn’t particularly pressing since there isn’t public API for extensions to read this value, and only Mail and Messages support subjects out of the built-in activities (which only change once a year, at most), but we only just realized that the latter does yesterday, so who knows what else we could potentially be missing?)

A couple of options:

  • Use the attributedTitle value if it exists and a subject was not explicitly registered for a given activity type
  • Add a @property (nonatomic, copy) NSString *defaultSubject; property
  • Document that calling registerSubject:forActivityType: with a nil activity type will register it as the default. I think I like this one the best.

Thoughts?

Should provider types return `id` types?

Consider the following use case: in general, you are sharing a URL but want to provide a custom HTML email if the Mail activity is chosen. You’d write code like the following:

[[XExtensionItemSource alloc] initWithURLProvider:^(NSString *activityType) {
    if (activityType == UIActivityTypeMail) {
        return HTMLEmailString;
    }
    else {
        return URL;
    }
}];

This wouldn’t compile though, since the URL provider block is typed to return an NSURL. Should it be typed to return an id instead? This way the developer can return non-URL types for activities that they know can take those non-URL types as inputs.

@AriX

Wiki Clarification

In the wiki we have written:

## Could be supported using custom parameters

* Custom URL slug
* Post type (for apps that specifically only want to create posts of a certain type)
* Post to Twitter (yes/no)
* Post to Facebook (yes/no)

I think it should be modified to read:

## Could be supported using custom parameters

* Suggested custom URL slug
* Post type (for apps that specifically only want to create posts of a certain type)
* Shareable to Twitter (yes/no)
* Shareable to Facebook (yes/no)

Consider supporting iOS 7

It would just pass a single item through rather than providing any of the benefits, but at least would make it easier for apps that still support iOS 7 to simply drop XExtensionItem in.

Consider renaming typeIdentifiersToContentRepresentations

The current name makes this property sound a little more like a mapping and less like it actually has content inside of it!

Potential replacements: alternateContentRepresentations or alternateRepresentations, or if we want to maintain the typeIdentifier part, alternateRepresentationsByType, alternateContentRepresentationsByType, alternateRepresentationsByTypeIdentifier, etc

iOS 9

⚠️ Preliminary thoughts! Please take this with a grain of salt as I haven’t thought about it for long enough to feel like I have my head fully wrapped around it. ⚠️

To try and determine what modifications we may want/need to make to XExtensionItem in the short term, I think it’s worthwhile to consider how we’d want the library to function if we only needed to support iOS 9.

XExtensionItem for iOS 8 has two goals:

  • Support multiple attachments (obviated by iOS 9)
  • Support metadata parameters (still useful on iOS 9)

Therefore, XExtensionItem usage on iOS 9 only could look something like the following:

// Application

// `XExtensionItem` no longer wraps your attachments, instead it’s just an additional metadata object
[[UIActivityViewController alloc] initWithActivityItems:
 @[@"Apple homepage", [NSURL URLWithString:@"http://apple.com"], xExtensionItemSource] 
                                  applicationActivities:nil]

// Extension

// Rather than treat *every* item as something that can be wrapped by an `XExtensionItem`, just specifically look to see if one was passed in
for (NSExtensionItem *item in self.extensionContext.inputItems) {
    if ([XExtensionItem isXExtensionItem:item]) {
        XExtensionItem *xExtensionItem = [[XExtensionItem alloc] initWithExtensionItem:item];
        // Access tags, app attribution, custom application parameters, etc.
    }
    else {
        // Process regular, non-XExtensionItem item
    }
}

Ideally, we’d release what we currently have (let’s call it 1.0) and add a section to the README documenting how we envision the library changing in order to eventually better support iOS 9 exclusively. Then at some point we cut a new release for developers who only support 9 (let’s call this 2.0), and those who continue to support 8 can just use the older version.

But the problem here is interoperability. An application that uses XExtensionItem 1.0 (e.g. provides a single XExtensionItem instance as their lone activity item) wouldn’t be compatible with an extension that uses 2.0 (I need to think about it a little more but I think an app that uses 2.0 will still work just fine with an extension that uses 1.0).

How can we resolve this? It seems as though modifying the extension-facing API to support both types of input is the most future-proof course of action. Otherwise, we’d have to either:

  • Go iOS 9 only and not be useful to anyone who needs to support iOS 8 for a while still (bad option, almost no one will use this)
  • Forget about changing the library in the future to better mesh with how activity items work in a post-iOS 9 world (makes this library very useful in the short term but more annoying to use than it needs to be post-iOS 9)

@mattbischoff @prendio2 @AriX

Allow `attributedContentText` to be configured on a per-activity type basis

As requested by @prendio2:

Certain built-in system activities (Facebook/Twitter/Vimeo/Flickr and possibly Weibo) can consume an NSExtensionItem as input, and display the attributedContentText value. XExtensionItem does not currently provide a way to customize this attributedContentText value on a per-activity item basis, however.

One could use the new registerItemProvidingBlock:forActivityType: method added in this pull request, but if they wanted to pass an image/string/etc. to the Twitter activity as well, the caller would need to build an NSExtensionItem themselves in order to provide a Twitter-specific attributedContentText value. This is suboptimal as part of XExtensionItem’s mission is to prevent users from having to construct NSExtensionItem instances themselves.

This isn’t as useful for Flickr, Vimeo, or Facebook, since it’s safe to assume that anyone who shares using those extensions also has the apps installed – if so, the app’s extension takes precedence and promptly throws the attributedContentText on the floor ¯_(ツ)_/¯

Probably safe to assume that Twitter will add an official share extension of their own at some point, but this would still be useful in the interim.

Use #import syntax instead of @import?

I'm not sure if this will be an issue or not, but does using @import assume that the project that will be using this pod has modules enabled? I know that if you use modules #import is automatically turned into an @import, but I'm not sure if it goes the other way around.

pod try fails with the following output

[!] Invalid `Podfile` file: undefined method `source' for #<Pod::Podfile:0x007f91739ab850>. Updating CocoaPods might fix the issue.

 #  from /private/tmp/CocoaPods/Try/XExtensionItem/Example/Podfile:1
 #  -------------------------------------------
 >  source 'https://github.com/CocoaPods/Specs.git'
 #  
 #  -------------------------------------------

[!] Invalid `Podfile` file: undefined method `source' for #<Pod::Podfile:0x007fe470af43b0>. Updating CocoaPods might fix the issue.

 #  from /private/tmp/CocoaPods/Try/XExtensionItem/Example/Podfile:1
 #  -------------------------------------------
 >  source 'https://github.com/CocoaPods/Specs.git'
 #  
 #  -------------------------------------------

OS X support

Shouldn’t be much work, I just haven’t put any thought into supporting usage on OS X yet.

Should be able to specify titles on a per-activity type basis

The more I think about this, the more I think we would actually want to be able to key titles off of activity types, if we’re going to use them as the subject that the UIActivityItemSource provides. I realized this by sharing from the Tumblr app to the Tumblr extension and realizing that our subjects written specifically for email don’t translate well to quote posts or link posts, where we consume the title field in our extension.

XExtensionItemSource API is Too Complicated

I'm a little worried that XExtensionItemSource is a little bit confusing/difficult to use for newcomers. Normal users might not be familiar with what a "placeholder item" is or why it's here.

It seems confusing that you can initialize an XExtensionItemSource with an attachments array or use the registerItemProvidingBlock: method and what the difference is between those things. And how are people supposed to understand how attributedContentText ties into those things? I worry that you have to be an expert in how UIActivityItemSource/NSExtensionItem/NSItemProvider work in order to use this API.

Compare that to UIActivityViewController, which (in the simple case) is easy as can be - literally just pass it whatever object you want. I wonder if we should be trying to offer a slightly higher-level API that abstracts away a few of these things. Particularly the placeholder item, the attachments array, and the attributedContentText/attributedTitle properties. I think that attributedTitle and subject are fundamentally the same concept and could be easily merged (since the activities that use subject never use attributedTitle)

Working on ideas for alternatives.

Should XExtensionItemParameters be backed by an NSExtensionItem instead of separate properties?

(An architectural suggestion from @khanlou)

Pros

  • XExtensionItemParameters implementation becomes a lot simpler. Adding new fields doesn’t require modifying description, isEqual, hash, etc.

Cons

  • XExtensionItemMutableParameters wouldn't be able to read from or write to the NSExtensionItem instance internal to its superclass. As @khanlou put it “they would both be standalone classes basically.”

Currently leaning towards “no” but getting rid of the mutable subclass in favor of a builder would certainly make this suggestion more appealing.

Add the ability to provide alternative items on a per-activity type basis

Provide hooks for giving specific items to specific activities, instead of simply passing the same fully-populated NSExtensionItem everywhere (e.g. to send different representations to Twitter, Facebook, Mail.app, etc.)

I can think of three different ways to register alternative items off the top of my head (these methods would all be on XExtensionItemSource:

@implementation XExtensionItemSource

...

// Simplest – just provide a value that should be used in place of the default `NSExtensionItem` if a specific activity is picked
- (void)registerItem:(id)item forActivityType:(NSString *)activityType;

// More complex – provide a block that returns a value, to avoid necessarily creating values for activities that may never be selected
- (void)registerItemProvider:(void (^)())itemProvider forActivityType:(NSString *)activityType;

// Most flexible – provide an object that determines what item should be returned for an activity type

@property (nonatomic) id <XExtensionItemProvider> alternativeItemProvider;

@end

@protocol XExtensionItemProvider

- (id)itemForActivityType:(NSString *)activityType;

@end

Usage would look something like:

[itemSource registerItem:twitterLengthSummaryString forActivityType: UIActivityTypePostToTwitter];

[itemSource registerItemProvider:^{
    // Lazily compute the Twitter-specific summary
    return twitterLengthSummaryString;
} forActivityType: UIActivityTypePostToTwitter];

@implementation MyAppCustomActivityItemProvider <XExtensionItemProvider>

- (id)itemForActivityType:(NSString *)activityType {
    if (activityType == UIActivityTypePostToTwitter) {
        return self.twitterLengthSummaryString;
    }

    // Returning `nil` would mean the activity/extension gets the default `NSItemProvider` instead of something special
    return nil;
}

@end

itemSource.alternativeItemProvider = [[MyAppCustomActivityItemProvider alloc] init];

I feel like @AriX will have opinions on this one.

Add hooks for `UIActivityItemSource`’s optional methods

To provide more robust sharing to activities like mail (subject) and Facebook/Twitter (thumbnail image):

  • - (UIImage *)activityViewController:(UIActivityViewController *)activityViewController thumbnailImageForActivityType:(NSString *)activityType suggestedSize:(CGSize)size
  • - (NSString *)activityViewController:(UIActivityViewController *)activityViewController dataTypeIdentifierForActivityType:(NSString *)activityType
  • - (NSString *)activityViewController:(UIActivityViewController *)activityViewController subjectForActivityType:(NSString *)activityType

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.