Does your app contain, display or access third-party content?

Apple have recently added a new question into the iTunes Connect flow when submitting a new app, or an update to an existing app.

"Does your app contain, display or access third-party content?"

If you answer "No", you can continue with the submission, if you answer "Yes" you are asked a further question, "Do you have all necessary rights to that content or are you otherwise permitted to use it under the laws of each App Store territory in which your app is available (for example, fair use).

If you answer "Yes", you can continue, if you answer "No" you are shown a warning, and a link to the trademarks section of the App Store Guidelines.

This doesn't appear to be any new policy on Apple's part, but we can guess that Apple is planning to enforce the guidelines more strictly in future, in particular guideline 8.5:

8.5 Apps may not use protected third party material such as trademarks, copyrights, patents or violate 3rd party terms of use. Authorization to use such material must be provided upon request.

This seems most likely to affect apps which use the brand names or logos of other companies, for example apps which show fashion products, sports teams, TV network logos, etc. Be prepared to submit written documentation that you have the right to show such content, even in the past Apple has not rigorously required this.

Happy Year of the Horse! 新年快乐!

To kickoff the CNY celebrations, ReignDesign sponsored a lion dance for our friends in Park Space to enjoy. IMG_0284

To reserve the red and yellow clad lions, Fluxa and Matt used their Uber taxi app. Instead of booking a taxi, they requested a lion dance. Brilliant idea! IMG_0075

 

Like all CNY celebrations, this party was loud! And these guys were excellent!IMG_0093

 

Sadly, not everyone can be a skilled musician. IMG_0288

ReignDesign would like to wish you and your loved ones a happy, healthy, and prosperous year of the horse!IMG_0061

 

Customizing individual share services in a ShareActionProvider on Android

In theory, sharing on Android is simple. Because of the system of Intents, you can prepare your shareable content, like an image, or text, and then easily show a list of installed apps which are able to handle this type of content. For example, if you’re sharing a photo, apps like Instagram, Twitter and the Gallery app will be available in the list. No additional coding is required for each sharing service!

  1. Intent i=new Intent(android.content.Intent.ACTION_SEND);
  2. i.setType("text/plain");
  3. i.putExtra(android.content.Intent.EXTRA_SUBJECT,"My cool app");
  4. i.putExtra(android.content.Intent.EXTRA_TEXT, "Here’s some content to share");
  5. startActivity(Intent.createChooser(i,"Share"));

But what if you want to customise the content depending on the chosen service? For example, if the user chooses Twitter you might want to shorten the text you’re sharing. Facebook on Android also has a long-running bug that means it won’t share text/plain content shared via an Intent… it only works for links.

Perhaps we’d like to use some different logic when our user clicks Facebook, for example using the Facebook Android SDK we could invoke an Open Graph sharing dialog.

Unfortunately, this is not easy. If you’ve followed the Android tutorial on adding an easy share action to the action bar then you’ll have a ShareActionProvider which creates a share button and dropdown for your action bar.

sap

The documentation is rather contradictory about whether you can customise ShareActionProvider’s behaviour. There’s a promising looking listener called setOnShareTargetSelectedListener, described here:

Sets a listener to be notified when a share target has been selected. The listener can optionally decide to handle the selection and not rely on the default behaviour which is to launch the activity.

So we might think to check the type of the intent in the listener, and run some custom behaviour for certain share types.

However the documentation goes on to say that

"Modifying the intent is not permitted and any changes to the latter will be ignored. You should not handle the intent here. This callback aims to notify the client that a sharing is being performed, so the client can update the UI if necessary."

The return result is ignored. Always return false for consistency.

It turns out if we try to add some custom code in setOnShareTargetSelectedListener, the custom code is run, but the standard share intent is also launched :(

Luckily since Android is open source, we can dig around in the source code to find out what’s going on.

Here’s the source code for the ShareActionProvider class in the v7 support library on Github.

Notice the class at the bottom ShareActivityChooserModelPolicy, which calls the listener, but then returns false regardless. Returning true from this method would allow us to handle the intent, without invoking the default behaviour.

  1. private class ShareActivityChooserModelPolicy implements OnChooseActivityListener {
  2. @Override
  3. public boolean onChooseActivity(ActivityChooserModel host, Intent intent) {
  4. if (mOnShareTargetSelectedListener != null) {
  5. mOnShareTargetSelectedListener.onShareTargetSelected(ShareActionProvider.this,intent);
  6. }
  7. return false;
  8. }
  9. }

We can’t easily subclass ShareActionProvider to override this behaviour, but what we can do is make a complete copy of the class and implement our own custom behaviour!

Copy the entire source file into your app, changing the package declaration at the top, and optionally the class name, for example to RDShareActionProvider.

Implement a new listener

  1.  
  2. private OnShareListener mOnShareListener; //also need to add getter and setter
  3.  
  4. public interface OnShareListener {
  5. /**
  6. * Called when a share target has been selected. The client can
  7. * decide whether to perform some action before the sharing is
  8. * actually performed OR handle the action itself.
  9.  
* * @param source The source of the notification. * @param intent The intent for launching the chosen share target. * @return Return true if you have handled the intent. */ public boolean willHandleShareTarget(RDShareActionProvider source, Intent intent); }

Time to re-implement the ShareActivityChooserModelPolicy using our new more powerful callback.

  1.  
  2. private class ShareActivityChooserModelPolicy implements OnChooseActivityListener {
  3. @Override
  4. public boolean onChooseActivity(ActivityChooserModel host, Intent intent) {
  5. if (mOnShareListener != null) {
  6. boolean result = mOnShareListener.willHandleShareTarget(
  7. RDShareActionProvider.this, intent);
  8. return result;
  9. }
  10. return false;
  11. }
  12. }
  13.  

We're in the home straight! Now we need to change the reference in the menu XML to our new class name.

  1. <item
  2. android:id="@+id/action_share"
  3. android:title="@string/menu_share"
  4. android:icon="@drawable/ic_action_share"
  5. myapp:showAsAction="always"
  6. myapp:actionProviderClass="com.myapp.RDShareActionProvider"

Finally we can implement our listener. We can check the package name of the intent, each sharer will have a different one, depending on the app. For Facebook, it’s com.facebook.katana.

  1.  
  2. mShareActionProvider.setOnShareListener(new OnShareListener() {
  3. @Override
  4. public boolean willHandleShareTarget(RDShareActionProvider source, Intent intent) {
  5. if (intent.getComponent().getPackageName().equalsIgnoreCase("com.facebook.katana")) {
  6. //just showing a toast for now
  7. //we could also manually dispatch an intent, based on the original intent
  8. Toast.makeText(self, "Hey, you're trying to share to Facebook", Toast.LENGTH_LONG).show();
  9. return true;
  10. } else {
  11. return false; //default behaviour.
  12. }
  13. }
  14. });
  15.  

Finally, we have control over individual sharers!

ReignDesign announces the opening of their international office in Santiago, Chile

ReignDesign-ChileWe are pleased to announce the opening of our first international office in Santiago, Chile for the South American region. ReignDesign is a multicultural software design agency. We specialize in the design and development of mobile applications particularly for Android and iOS.

After reviewing different markets around the world we decided to start with South America. We see the region as an interesting emerging market, and we feel that Chile will be a great place to work. Aside from finding good talent, there is a great startup scene, a stable economy, reasonable costs, and nice weather.

From January 1, Juan Claudio Lopez will be our first international Business Development Manager, working as the Country Manager in Santiago. He was ReignDesign’s Business Development Manager for almost three years in Shanghai, China. Juan Claudio is thrilled to be back in Chile, and he is looking forward to finding new clients and to introducing the ReignDesign brand to South America.

 

ReignDesign anuncia la puesta en marcha de su oficina internacional en Santiago, Chile

ReignDesign-Chile

Estamos felices de poder anunciar la apertura de nuestra primera oficina internacional en Santiago, Chile para Sud América. ReignDesign es una agencia de diseño internacional de carácter multicultural.  Nuestra oficina se especializa en el diseño y desarrollo de aplicaciones específicamente para Android y iOS.

Luego de estudiar los diversos mercados mundiales, hemos decidido comenzar en Sud América. Percibimos a esta región como un mercado emergente e interesante; a la vez, pensamos que Chile será un muy buen lugar de trabajo. No solo hemos encontrado grandes talentos, sino también encontramos una muy buena área de emprendimiento, una economía estable, costos razonables y un muy buen clima.

Comenzando el 1 de Enero de 2014, Juan Claudio López será nuestro primer Gerente de Desarrollo de Comercio Internacional y se desempeñará como Gerente Zonal en Santiago para el área de Sud América. Previamente se desempeñó como Gerente de Desarrollo de Negocios por casi tres años en Shanghai, China. Juan Claudio esta feliz de estar de vuelta en Chile, y de comenzar a trabajar con nuevos clientes introduciendo la marca ReignDesign en Súd America.