简体   繁体   中英

How to re-archive an app.ipa file using xcode4 with an updated ad-hoc profile?

  • XCode4 is used to "Archive" a project and generate an app.ipa file that has been signed with an Ad-Hoc profile
  • The Ad-Hoc profile is aware of 10 distinct iOS devices. This means that the app.ipa can be pushed to 10 folks for testing
  • Now if an eleventh (11th) device is added to the Ad-Hoc profile via the apple portal, then we end up with an updated profile!

  • we do NOT want to create a new "Archive" using XCode because a lot of code has changed
  • we simply want the comfort of taking the exact same app.ipa file and re-signing it with the update profile so that we may start sending the app to the 11th device in an ad-hoc manner as well.

  • Please do NOT suggest using the repository to check-out the earlier version of the code and then using archive with the updated profile. I am already aware of that workaround and I want an option that is much more technologically comfortable than that

Thanks to this blog: http://blog.futureshock-ed.com/xcode-ad-hock-provisioning-certificate-pains

I figured out that I can simply open the Organizer in my XCode 4, select any one of the previously archived builds and when I look to generate the app.ipa again, it will use the newly imported & updated adhoc provisioning profile to create the ipa file.

How to import the updated provisioning profile before doing this action you ask? Well just double-click the newly downloaded profile and make sure to delete its older sibling in the window that pops-up to show both of them now sitting on your mac. You can determine which one is the older by visually inspecting the value for "Creation Date"

It should have been obvious but somehow it wasn't, I wonder how many others suffer from the same affliction.

Something like the following should work (taken from a project I created that builds applications using the xcodebuild command line tool):

- (BOOL)createSignedIPA:(NSError **)error
{
   [self.delegate builder:self didUpdateStatus:@"creating IPA, please be patient ..."];

   NSTask *task = [[NSTask alloc] init];
   NSString *path = @"/usr/bin/xcrun";
   [task setLaunchPath: path];

   NSString *input = [MOB_PROJECT_DIR stringByExpandingTildeInPath];
   input = [NSString stringWithFormat:@"%@/build/%@-iphoneos/yourapp.app", input, isDemoApp ? @"Debug" : @"Release"]; 

   NSString *output = [@"~/Desktop" stringByExpandingTildeInPath];
   output = [NSString stringWithFormat:@"%@/%@%ld.ipa", output, isDemoApp ? @"demo" : @"app", appIdentifier];

   NSString *bundleIdentifier = [self bundleIdentifier];
   NSString *profile = [self pathForProfileWithBundleIdentifier:bundleIdentifier error:error];   
   if (!profile) 
      if (*error) 
         return NO;
      else 
      {
         NSString *message = [NSString stringWithFormat:@"no profile found for bundle %@", bundleIdentifier];
         NSDictionary *userInfo = [NSDictionary dictionaryWithObject:message forKey:NSLocalizedDescriptionKey];
         *error = [NSError errorWithDomain:MOB_APP_DOMAIN code:MOB_ERR_PROFILE_NOT_FOUND userInfo:userInfo];
         return NO;
      }

   NSLog(@"%@", profile);

   NSArray *arguments = [NSArray arrayWithObjects:
                         @"-sdk", @"iphoneos5.0", 
                         @"PackageApplication", input,
                         @"-o", output, 
                         @"--sign", isDemoApp ? @"Wolfgang Schreurs (YK9DVMECC4)" : @"My Company",
                         @"--embed", profile,
                         @"-verbose",
                         nil];
   [task setArguments:arguments];

   NSString *projectDirectory = [MOB_PROJECT_DIR stringByExpandingTildeInPath];
   [task setCurrentDirectoryPath:projectDirectory];

   NSPipe *pipe = [NSPipe pipe];
   [task setStandardOutput: pipe];
   [task setStandardInput:[NSPipe pipe]]; 
   NSFileHandle *file = [pipe fileHandleForReading];

   [task launch];

   NSData *data = [file readDataToEndOfFile];
   NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

   [self.delegate builder:self didUpdateStatus:string];

   return YES;
}

In this snippet above I take the *.app from the build directory and create a signed IPA using the provisioning profile from ~/Library/MobileProvisioning (or something like that).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM