Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to download .ipa by the app ID #263

Merged
merged 3 commits into from
Apr 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,17 @@ Usage:
ipatool download [flags]

Flags:
-b, --bundle-identifier string The bundle identifier of the target iOS app (required)
-i, --app-id int ID of the target iOS app (required)
-b, --bundle-identifier string The bundle identifier of the target iOS app (overrides the app ID)
-h, --help help for download
-o, --output string The destination path of the downloaded app package
--purchase Obtain a license for the app if needed

Global Flags:
--format format sets output format for command; can be 'text', 'json' (default text)
--non-interactive run in non-interactive session
--verbose enables verbose logs
--format format sets output format for command; can be 'text', 'json' (default text)
--keychain-passphrase string passphrase for unlocking keychain
--non-interactive run in non-interactive session
--verbose enables verbose logs
```

**Note:** the tool runs in interactive mode by default. Use the `--non-interactive` flag
Expand Down
24 changes: 17 additions & 7 deletions cmd/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,18 @@ func downloadCmd() *cobra.Command {
var (
acquireLicense bool
outputPath string
appID int64
bundleID string
)

cmd := &cobra.Command{
Use: "download",
Short: "Download (encrypted) iOS app packages from the App Store",
RunE: func(cmd *cobra.Command, args []string) error {
if appID == 0 && bundleID == "" {
return errors.New("either the app ID or the bundle identifier must be specified")
}

var lastErr error
var acc appstore.Account

Expand All @@ -43,13 +48,18 @@ func downloadCmd() *cobra.Command {
acc = loginResult.Account
}

lookupResult, err := dependencies.AppStore.Lookup(appstore.LookupInput{Account: acc, BundleID: bundleID})
if err != nil {
return err
app := appstore.App{ID: appID}
if bundleID != "" {
lookupResult, err := dependencies.AppStore.Lookup(appstore.LookupInput{Account: acc, BundleID: bundleID})
if err != nil {
return err
}

app = lookupResult.App
}

if errors.Is(lastErr, appstore.ErrLicenseRequired) {
err := dependencies.AppStore.Purchase(appstore.PurchaseInput{Account: acc, App: lookupResult.App})
err := dependencies.AppStore.Purchase(appstore.PurchaseInput{Account: acc, App: app})
if err != nil {
return err
}
Expand All @@ -74,7 +84,7 @@ func downloadCmd() *cobra.Command {
)
}

out, err := dependencies.AppStore.Download(appstore.DownloadInput{Account: acc, App: lookupResult.App, OutputPath: outputPath, Progress: progress})
out, err := dependencies.AppStore.Download(appstore.DownloadInput{Account: acc, App: app, OutputPath: outputPath, Progress: progress})
if err != nil {
return err
}
Expand Down Expand Up @@ -112,10 +122,10 @@ func downloadCmd() *cobra.Command {
},
}

cmd.Flags().StringVarP(&bundleID, "bundle-identifier", "b", "", "The bundle identifier of the target iOS app (required)")
cmd.Flags().Int64VarP(&appID, "app-id", "i", 0, "ID of the target iOS app (required)")
cmd.Flags().StringVarP(&bundleID, "bundle-identifier", "b", "", "The bundle identifier of the target iOS app (overrides the app ID)")
cmd.Flags().StringVarP(&outputPath, "output", "o", "", "The destination path of the downloaded app package")
cmd.Flags().BoolVar(&acquireLicense, "purchase", false, "Obtain a license for the app if needed")
_ = cmd.MarkFlagRequired("bundle-identifier")

return cmd
}
20 changes: 16 additions & 4 deletions pkg/appstore/appstore_download.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"io"
"os"
"strconv"
"strings"

"github.com/majd/ipatool/v2/pkg/http"
Expand Down Expand Up @@ -161,10 +162,21 @@ func (*appstore) downloadRequest(acc Account, app App, guid string) http.Request
}

func fileName(app App) string {
return fmt.Sprintf("%s_%d_%s.ipa",
app.BundleID,
app.ID,
app.Version)
var parts []string

if app.BundleID != "" {
parts = append(parts, app.BundleID)
}

if app.ID != 0 {
parts = append(parts, strconv.FormatInt(app.ID, 10))
}

if app.Version != "" {
parts = append(parts, app.Version)
}

return fmt.Sprintf("%s.ipa", strings.Join(parts, "_"))
}

func (t *appstore) resolveDestinationPath(app App, path string) (string, error) {
Expand Down
Loading