2014年12月16日火曜日

Xcode6でOrganizerからValidate ArchiveするとiTunes Store operation failed. The network connection was lost.になって進まない。

Provisioning Profileを変えても駄目で、Xcode5の事例で出てたrestartも駄目で開発機再起動も駄目で何度やっても弾かれるしどうしようもなくなってたが、Application loaderを使うことで解決。
https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide_Jpn/Chapters/SubmittingTheApp.html#//apple_ref/doc/uid/TP40014483-CH33-SW8

Organizerでipaにexportして(Save for iOS App Store Deployment)、Application Loaderからアップロードするとそのままアップロード出来た。


というか、新生TestFlightはなぜあんな処理に時間かかるのか。アップロード完了してからアクティブになるまでひどい時だと30分くらいかかる。

2014年12月4日木曜日

単一Fragmentを表示するActivityの共通化

全画面想定のFragmentをActivityで取り回したい場合。AaaFragment, BbbFragmentに合わせてAaaActivity, BbbActivityとか作るのは面倒なのでActivityのWrapperを共通化。

Fragmentは public static XxxFragment newInstance(Bundle args);を実装している想定。
画面遷移時は、FragmentからならWrapperActivity.openFragmentActivity(getActivity(), SecondFragment.class, secondFragmentsArguments); という感じで行える。

package hoge.fuga.activities;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.View;
import android.view.View.OnClickListener;
import jp.arithmetic.arithmusic.R;
import jp.arithmetic.arithmusic.model.FragmentReplacer;

public class WrapperActivity extends Activity {
 public static final String TAG = "WrapperActivity";
 public static final String ARGS_FRAGMENT = "app-fragment";
 
 
 /** 
  * 1つのFragmentを全面に表示する共通化Activity
  * @param fromActivity
  * @param clazz
  * @param args
  */
 public static void openFragmentActivity(Activity fromActivity, Class clazz, Bundle args) {
  // setup bundle
  if (args == null) {
   args = new Bundle();
  }
  args.putString(ARGS_FRAGMENT, clazz.getName());
  
  // setup intent
  Intent i = new Intent(fromActivity, WrapperActivity.class);
  i.putExtras(args);
  
  // start activity
  fromActivity.startActivity(i);
 }
 
 /** 
  * close
  * @param fromActivity
  */
 public static void closeFragmentActivity(Activity fromActivity) {
  fromActivity.finish();
 }
 
 public static void closeToStartActivity(Activity fromActivity) {
  Intent i = new Intent(fromActivity, SomeStartActivity.class);
  i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
  i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
  fromActivity.startActivity(i);
 }
 
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_empty_container);

  // intentパラメータ優先
  Bundle args = (getIntent() != null) ? getIntent().getExtras() : savedInstanceState;
  if (args == null) {
   throw new RuntimeException("Wrapper: Empty arguments");
  }
  
  // 呼び出しFragment特定、初期化
  String className = args.getString(ARGS_FRAGMENT);
  if (className == null || className.isEmpty()) {
   throw new RuntimeException("Wrapper: Empty class name");
  }
  Fragment f = null;
  try {
   Class clazz = Class.forName(className);
   Method newInstance = clazz.getMethod("newInstance", Bundle.class);
   f = (Fragment)newInstance.invoke(null, args);

   replaceFragment(f);
   
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
   finish();
  } catch (NoSuchMethodException e) {
   e.printStackTrace();
   finish();
  } catch (IllegalAccessException e) {
   e.printStackTrace();
   finish();
  } catch (IllegalArgumentException e) {
   e.printStackTrace();
   finish();
  } catch (InvocationTargetException e) {
   e.printStackTrace();
   finish();
  }
 }
 
 @Override
 public void onBackPressed() {
  if (getSupportFragmentManager().getBackStackEntryCount() == 1) {
   closeFragmentActivity(this);
  } else {
   super.onBackPressed();
  }
 }
 
 
 public void replaceFragment(Fragment f) {
  getSupportFragmentManager()
  .beginTransaction()
  .addToBackStack(null)
  .replace(R.id.empty_container, f)
  .commit();
 }
}