Пример #1
0
  @Override
  public void serializeInto(XcodeprojSerializer s) {
    super.serializeInto(s);

    s.addField("mainGroup", mainGroup);

    Collections.sort(
        targets,
        Ordering.natural()
            .onResultOf(
                new Function<PBXTarget, String>() {
                  @Override
                  public String apply(PBXTarget input) {
                    return input.getName();
                  }
                }));
    s.addField("targets", targets);
    s.addField("buildConfigurationList", buildConfigurationList);
    s.addField("compatibilityVersion", compatibilityVersion);

    NSDictionary d = new NSDictionary();
    d.put("LastUpgradeCheck", "0600");

    s.addField("attributes", d);
  }
Пример #2
0
 private String readRequiredString(NSDictionary dict, String parameter, String fileName)
     throws IOException {
   if (!dict.containsKey(parameter)) {
     throw new IOException(
         "Invalid manifest file. No " + parameter + " given. (" + fileName + ")");
   }
   return ((NSString) dict.get(parameter)).getContent();
 }
Пример #3
0
 private void parseOXZ(String fileName) throws IOException {
   ZipResourceFile zip = new ZipResourceFile(fileName);
   InputStream manifestStream = zip.getInputStream("manifest.plist");
   if (manifestStream == null) {
     throw new FileNotFoundException("Cannot read manifest file of " + fileName + ".");
   }
   NSDictionary manifest = PListParser.parseFile(manifestStream);
   if (manifest.isEmpty()) {
     throw new FileNotFoundException("Cannot parse manifest file of " + fileName + ".");
   }
   identifier = readRequiredString(manifest, "identifier", fileName);
   name = readRequiredString(manifest, "title", fileName);
   version = readRequiredString(manifest, "version", fileName);
   category = readString(manifest, "category");
   description = readString(manifest, "description");
   author = readString(manifest, "author");
   license = readString(manifest, "license");
 }
  public static Optional<AppleSimulatorProfile> parseProfilePlistStream(InputStream inputStream)
      throws IOException {
    NSDictionary profile;
    try (BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream)) {
      try {
        profile = (NSDictionary) PropertyListParser.parse(bufferedInputStream);
      } catch (Exception e) {
        throw new IOException(e);
      }
    }

    NSObject supportedProductFamilyIDsObject = profile.objectForKey("supportedProductFamilyIDs");
    if (!(supportedProductFamilyIDsObject instanceof NSArray)) {
      LOG.warn(
          "Invalid simulator profile.plist (supportedProductFamilyIDs missing or not an array)");
      return Optional.absent();
    }
    NSArray supportedProductFamilyIDs = (NSArray) supportedProductFamilyIDsObject;

    AppleSimulatorProfile.Builder profileBuilder = AppleSimulatorProfile.builder();
    for (NSObject supportedProductFamilyID : supportedProductFamilyIDs.getArray()) {
      if (supportedProductFamilyID instanceof NSNumber) {
        profileBuilder.addSupportedProductFamilyIDs(
            ((NSNumber) supportedProductFamilyID).intValue());
      } else {
        LOG.warn(
            "Invalid simulator profile.plist (supportedProductFamilyIDs contains non-number %s)",
            supportedProductFamilyID);
        return Optional.absent();
      }
    }

    NSObject supportedArchsObject = profile.objectForKey("supportedArchs");
    if (!(supportedArchsObject instanceof NSArray)) {
      LOG.warn("Invalid simulator profile.plist (supportedArchs missing or not an array)");
      return Optional.absent();
    }
    NSArray supportedArchs = (NSArray) supportedArchsObject;
    for (NSObject supportedArch : supportedArchs.getArray()) {
      profileBuilder.addSupportedArchitectures(supportedArch.toString());
    }

    return Optional.of(profileBuilder.build());
  }
Пример #5
0
  private ProvisioningProfile(File file, NSDictionary dict) {
    this.file = file;
    this.dict = dict;
    this.uuid = dict.objectForKey("UUID").toString();
    this.name = dict.objectForKey("Name").toString();
    this.appIdName =
        dict.objectForKey("AppIDName") != null ? dict.objectForKey("AppIDName").toString() : null;
    this.appIdPrefix =
        ((NSArray) dict.objectForKey("ApplicationIdentifierPrefix")).objectAtIndex(0).toString();
    this.creationDate = ((NSDate) dict.objectForKey("CreationDate")).getDate();
    this.expirationDate = ((NSDate) dict.objectForKey("ExpirationDate")).getDate();
    this.entitlements = (NSDictionary) dict.objectForKey("Entitlements");

    for (NSObject o : ((NSArray) dict.objectForKey("DeveloperCertificates")).getArray()) {
      NSData data = (NSData) o;
      certFingerprints.add(getCertFingerprint(data.bytes()));
    }
  }
  /**
   * Returns a map containing entries that should be added to the merged plist. These are usually
   * generated by Xcode automatically during the build process.
   */
  private NSDictionary automaticEntries() {
    List<Integer> uiDeviceFamily =
        TargetDeviceFamily.UI_DEVICE_FAMILY_VALUES.get(bundleSupport.targetDeviceFamilies());
    AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class);
    Platform platform = appleConfiguration.getBundlingPlatform();
    ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);

    NSDictionary result = new NSDictionary();

    if (uiDeviceFamily != null) {
      result.put("UIDeviceFamily", NSObject.wrap(uiDeviceFamily.toArray()));
    }
    result.put("DTPlatformName", NSObject.wrap(platform.getLowerCaseNameInPlist()));
    result.put(
        "DTSDKName",
        NSObject.wrap(platform.getLowerCaseNameInPlist() + appleConfiguration.getIosSdkVersion()));
    result.put("CFBundleSupportedPlatforms", new NSArray(NSObject.wrap(platform.getNameInPlist())));
    result.put("MinimumOSVersion", NSObject.wrap(objcConfiguration.getMinimumOs().toString()));

    return result;
  }
Пример #7
0
 private String _readFloatValue(NSDictionary dict, String key) {
   String value = dict.getStrValue(key);
   return value != null
       ? s_df.format(Double.parseDouble(value) / 1000.0).replace('.', ',')
       : "-00.00";
 }
Пример #8
0
 private String _readValue(NSDictionary dict, String key) {
   String value = dict.getStrValue(key);
   return value != null ? value : NULL_VALUE;
 }
Пример #9
0
  public void assertFilesEqual(Path expected, Path actual) throws IOException {
    if (!expected.isAbsolute()) {
      expected = templatePath.resolve(expected);
    }
    if (!actual.isAbsolute()) {
      actual = destPath.resolve(actual);
    }
    if (!Files.isRegularFile(actual)) {
      fail("Expected file " + actual + " could not be found.");
    }

    String extension = MorePaths.getFileExtension(actual);
    String cleanPathToObservedFile =
        MoreStrings.withoutSuffix(templatePath.relativize(expected).toString(), EXPECTED_SUFFIX);

    switch (extension) {
        // For Apple .plist and .stringsdict files, we define equivalence if:
        // 1. The two files are the same type (XML or binary)
        // 2. If binary: unserialized objects are deeply-equivalent.
        //    Otherwise, fall back to exact string match.
      case "plist":
      case "stringsdict":
        NSObject expectedObject;
        try {
          expectedObject = BinaryPropertyListParser.parse(expected.toFile());
        } catch (Exception e) {
          // Not binary format.
          expectedObject = null;
        }

        NSObject observedObject;
        try {
          observedObject = BinaryPropertyListParser.parse(actual.toFile());
        } catch (Exception e) {
          // Not binary format.
          observedObject = null;
        }

        assertTrue(
            String.format(
                "In %s, expected plist to be of %s type.",
                cleanPathToObservedFile, (expectedObject != null) ? "binary" : "XML"),
            (expectedObject != null) == (observedObject != null));

        if (expectedObject != null) {
          // These keys depend on the locally installed version of Xcode, so ignore them
          // in comparisons.
          String[] ignoredKeys = {
            "DTSDKName",
            "DTPlatformName",
            "DTPlatformVersion",
            "MinimumOSVersion",
            "DTSDKBuild",
            "DTPlatformBuild",
            "DTXcode",
            "DTXcodeBuild"
          };
          if (observedObject instanceof NSDictionary && expectedObject instanceof NSDictionary) {
            for (String key : ignoredKeys) {
              ((NSDictionary) observedObject).remove(key);
              ((NSDictionary) expectedObject).remove(key);
            }
          }

          assertEquals(
              String.format(
                  "In %s, expected binary plist contents to match.", cleanPathToObservedFile),
              expectedObject,
              observedObject);
          break;
        } else {
          assertFileContentsEqual(expected, actual);
        }
        break;

      default:
        assertFileContentsEqual(expected, actual);
    }
  }
Пример #10
0
 private String readString(NSDictionary dict, String parameter) {
   if (!dict.containsKey(parameter)) {
     return "";
   }
   return ((NSString) dict.get(parameter)).getContent();
 }
Пример #11
0
  @Override
  public int execute(ExecutionContext context) throws InterruptedException {

    final String bundleID;
    try {
      bundleID =
          AppleInfoPlistParsing.getBundleIdFromPlistStream(
                  filesystem.getInputStreamForRelativePath(infoPlist))
              .get();
    } catch (IOException e) {
      throw new HumanReadableException("Unable to get bundle ID from info.plist: " + infoPlist);
    }

    final Optional<ImmutableMap<String, NSObject>> entitlements;
    final String prefix;
    if (entitlementsPlist.isPresent()) {
      try {
        NSDictionary entitlementsPlistDict =
            (NSDictionary) PropertyListParser.parse(entitlementsPlist.get().toFile());
        entitlements = Optional.of(ImmutableMap.copyOf(entitlementsPlistDict.getHashMap()));
        prefix = ProvisioningProfileMetadata.prefixFromEntitlements(entitlements.get());
      } catch (IOException e) {
        throw new HumanReadableException(
            "Unable to find entitlement .plist: " + entitlementsPlist.get());
      } catch (Exception e) {
        throw new HumanReadableException(
            "Malformed entitlement .plist: " + entitlementsPlist.get());
      }
    } else {
      entitlements = ProvisioningProfileStore.MATCH_ANY_ENTITLEMENT;
      prefix = "*";
    }

    Optional<ProvisioningProfileMetadata> bestProfile =
        provisioningProfileUUID.isPresent()
            ? provisioningProfileStore.getProvisioningProfileByUUID(provisioningProfileUUID.get())
            : provisioningProfileStore.getBestProvisioningProfile(bundleID, entitlements);

    if (!bestProfile.isPresent()) {
      throw new HumanReadableException(
          "No valid non-expired provisioning profiles match for " + prefix + "." + bundleID);
    }

    selectedProvisioningProfileFuture.set(bestProfile.get());
    Path provisioningProfileSource = bestProfile.get().getProfilePath();

    // Copy the actual .mobileprovision.
    try {
      filesystem.copy(
          provisioningProfileSource, provisioningProfileDestination, CopySourceMode.FILE);
    } catch (IOException e) {
      context.logError(e, "Failed when trying to copy: %s", getDescription(context));
      return 1;
    }

    // Merge tne entitlements with the profile, and write out.
    if (entitlementsPlist.isPresent()) {
      return (new PlistProcessStep(
              filesystem,
              entitlementsPlist.get(),
              signingEntitlementsTempPath,
              bestProfile.get().getEntitlements(),
              ImmutableMap.<String, NSObject>of(),
              PlistProcessStep.OutputFormat.XML))
          .execute(context);
    } else {
      // No entitlements.plist explicitly specified; write out the minimal entitlements needed.
      String appID = bestProfile.get().getAppID().getFirst() + "." + bundleID;
      NSDictionary entitlementsPlist = new NSDictionary();
      entitlementsPlist.putAll(bestProfile.get().getEntitlements());
      entitlementsPlist.put(APPLICATION_IDENTIFIER, appID);
      entitlementsPlist.put(KEYCHAIN_ACCESS_GROUPS, new String[] {appID});
      return (new WriteFileStep(
              filesystem,
              entitlementsPlist.toXMLPropertyList(),
              signingEntitlementsTempPath,
              /* executable */ false))
          .execute(context);
    }
  }
Пример #12
0
  @Override
  protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);

    // Get the item that was clicked
    NSDictionary item = (NSDictionary) getListAdapter().getItem(position);

    NSObject action;
    if ((action = item.objectForKey("subcontent")) != null) {
      NSArrayWrapper wrapper = new NSArrayWrapper((NSArray) action);

      Intent intent = new Intent(this, Info.class);
      intent.putExtra("class", this.getClass().getCanonicalName());
      intent.putExtra(
          "tracking", getIntent().getStringExtra("tracking") + "/" + item.objectForKey("title"));
      intent.putExtra("content", wrapper);
      startActivity(intent);

    } else if ((action = item.objectForKey("url")) != null
        || (action = item.objectForKey("url-android")) != null) {
      Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(((NSString) action).toString()));
      // Handle external activities as described in
      // http://developer.android.com/training/implementing-navigation/descendant.html#external-activities
      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);

      // We can't call the code in the onCreate as we may be opening the play store, so track it
      // here.
      EasyTracker.getTracker()
          .sendView(getIntent().getStringExtra("tracking") + " > " + item.objectForKey("title"));
      Log.i(
          "Tracking", getIntent().getStringExtra("tracking") + " > " + item.objectForKey("title"));

      startActivity(intent);
    } else if ((action = item.objectForKey("html")) != null) {
      Intent intent = new Intent(this, InfoWebActivity.class);
      intent.putExtra("class", this.getClass().getCanonicalName());

      EasyTracker.getTracker()
          .sendView(getIntent().getStringExtra("tracking") + " > " + item.objectForKey("title"));
      Log.i(
          "Tracking", getIntent().getStringExtra("tracking") + " > " + item.objectForKey("title"));

      intent.putExtra("page", ((NSString) action).toString());
      startActivity(intent);
    } else if ((action = item.objectForKey("association")) != null) {
      Toast.makeText(
              this, "TODO: implement the association for " + action.toString(), Toast.LENGTH_SHORT)
          .show();
      System.err.println(action);
    } else {
      System.err.println("WHAT THE F**K IS THIS SHIT?");
    }
  }
Пример #13
0
  @Override
  public int execute(ExecutionContext context) throws InterruptedException {

    final String bundleID;
    try {
      bundleID =
          AppleInfoPlistParsing.getBundleIdFromPlistStream(
                  context.getProjectFilesystem().getInputStreamForRelativePath(infoPlist))
              .get();
    } catch (IOException e) {
      throw new HumanReadableException("Unable to get bundle ID from info.plist: " + infoPlist);
    }

    // What to look for in the provisioning profile.
    final Optional<String> prefix; // e.g. ABCDE12345
    if (entitlementsPlist.isPresent()) {
      NSDictionary entitlementsPlistDict;
      try {
        entitlementsPlistDict =
            (NSDictionary) PropertyListParser.parse(entitlementsPlist.get().toFile());

      } catch (Exception e) {
        throw new HumanReadableException(
            "Malformed entitlement .plist: " + entitlementsPlist.get());
      }

      try {
        String appID =
            ((NSArray) entitlementsPlistDict.get("keychain-access-groups"))
                .objectAtIndex(0)
                .toString();
        prefix = Optional.<String>of(ProvisioningProfileMetadata.splitAppID(appID).getFirst());
      } catch (Exception e) {
        throw new HumanReadableException(
            "Malformed entitlement .plist (missing keychain-access-groups): "
                + entitlementsPlist.get());
      }
    } else {
      prefix = Optional.<String>absent();
    }

    Optional<ProvisioningProfileMetadata> bestProfile =
        getBestProvisioningProfile(profiles, bundleID, provisioningProfileUUID, prefix);

    if (!bestProfile.isPresent()) {
      throw new HumanReadableException(
          "No valid non-expired provisioning profiles match for " + prefix + "." + bundleID);
    }

    Path provisioningProfileSource = bestProfile.get().getProfilePath().get();

    // Copy the actual .mobileprovision.
    try {
      context
          .getProjectFilesystem()
          .copy(provisioningProfileSource, provisioningProfileDestination, CopySourceMode.FILE);
    } catch (IOException e) {
      context.logError(e, "Failed when trying to copy: %s", getDescription(context));
      return 1;
    }

    // Merge tne entitlements with the profile, and write out.
    if (entitlementsPlist.isPresent()) {
      return (new PlistProcessStep(
              entitlementsPlist.get(),
              signingEntitlementsTempPath,
              bestProfile.get().getEntitlements(),
              ImmutableMap.<String, NSObject>of(),
              PlistProcessStep.OutputFormat.XML))
          .execute(context);
    } else {
      // No entitlements.plist explicitly specified; write out the minimal entitlements needed.
      String appID = bestProfile.get().getAppID().getFirst() + "." + bundleID;
      NSDictionary entitlements = new NSDictionary();
      entitlements.putAll(bestProfile.get().getEntitlements());
      entitlements.put(APPLICATION_IDENTIFIER, appID);
      entitlements.put(KEYCHAIN_ACCESS_GROUPS, new String[] {appID});
      return (new WriteFileStep(
              filesystem,
              entitlements.toXMLPropertyList(),
              signingEntitlementsTempPath,
              /* executable */ false))
          .execute(context);
    }
  }