Skip to content
This repository has been archived by the owner on Nov 19, 2018. It is now read-only.

[Ready] Update for the new iTunes Connect #108

Merged
merged 15 commits into from Sep 25, 2015
Merged
25 changes: 25 additions & 0 deletions Rakefile
Expand Up @@ -8,3 +8,28 @@ task default: :spec
task :test do
sh "../fastlane/bin/fastlane test"
end

task :beta do
require 'spaceship'
puts "Login..."
Spaceship::Tunes.login('flapple@krausefx.com')
app = Spaceship::Application.find("tools.fastlane.app")
require 'pry'

# puts app.name["en-US"]
# puts app.privacy_url["en-US"]

details = app.details
details.name['en-US'] = "Updated by fastlane"
details.privacy_url['en-US'] = "https://fastlane.tools"
details.primary_category = 'Sports'
details.secondary_category = 'Family'
details.save!

# v = app.edit_version

# puts v.marketing_url['de-DE']
# v.marketing_url['en-US'] = "https://neu.com"
# v.marketing_url['de-DE'] = "https://suchdeutsch.com"

end
14 changes: 11 additions & 3 deletions docs/iTunesConnect.md
Expand Up @@ -44,6 +44,15 @@ app = Spaceship::Tunes::Application.create!(name: "App Name",
bundle_id: "com.krausefx.app")
```

To update non version specific details, use the following code

```ruby
details = app.details
details.name['en-US'] = "App Name"
details.privacy_url['en-US'] = "https://fastlane.tools"
details.save!
```

## AppVersions

<img src="/assets/docs/AppVersions.png" width="500">
Expand Down Expand Up @@ -72,7 +81,7 @@ v.version # => "0.9.14"
v.copyright = "#{Time.now.year} Felix Krause"

# Get a list of available languages for this app
v.name.keys # => ["German", "English"]
v.description.languages # => ["German", "English"]

# Update localised app metadata
v.name["English"] = "New Title"
Expand Down Expand Up @@ -134,7 +143,6 @@ attr_reader :name
attr_reader :keywords
attr_reader :description
attr_reader :release_notes
attr_reader :privacy_url
attr_reader :support_url
attr_reader :marketing_url
attr_reader :screenshots
Expand Down Expand Up @@ -167,7 +175,7 @@ build = train.builds.first
# Enable beta testing for a build train
# This will put the latest build into beta testing mode
# and turning off beta testing for all other build trains
train.update_testing_status!(true)
train.update_testing_status!(true, 'internal')
```

## Builds
Expand Down
3 changes: 2 additions & 1 deletion lib/spaceship.rb
Expand Up @@ -10,7 +10,8 @@
# iTunes Connect
require 'spaceship/tunes/tunes'
require 'spaceship/tunes/spaceship'
require 'spaceship/tunes/tester'

require 'pry'

# To support legacy code
module Spaceship
Expand Down
4 changes: 3 additions & 1 deletion lib/spaceship/base.rb
Expand Up @@ -45,7 +45,9 @@ def lookup(keys)
end

def to_json
@hash.to_json
h = @hash.dup
h.delete(:application)
h.to_json
end
end

Expand Down
107 changes: 107 additions & 0 deletions lib/spaceship/tunes/app_details.rb
@@ -0,0 +1,107 @@
module Spaceship
module Tunes
class AppDetails < TunesBase
attr_accessor :application

####
# Localized values
####

# @return (Array) Raw access the all available languages. You shouldn't use it probbaly
attr_accessor :languages

# @return (Hash) A hash representing the app name in all languages
attr_reader :name

# @return (Hash) A hash representing the keywords in all languages
attr_reader :privacy_url

# Categories (e.g. MZGenre.Business)
attr_accessor :primary_category

attr_accessor :primary_first_sub_category

attr_accessor :primary_second_sub_category

attr_accessor :secondary_category

attr_accessor :secondary_first_sub_category

attr_accessor :secondary_second_sub_category

attr_mapping(
'localizedMetadata.value' => :languages,
'primaryCategory.value' => :primary_category,
'primaryFirstSubCategory.value' => :primary_first_sub_category,
'primarySecondSubCategory.value' => :primary_second_sub_category,
'secondaryCategory.value' => :secondary_category,
'secondaryFirstSubCategory.value' => :secondary_first_sub_category,
'secondarySecondSubCategory.value' => :secondary_second_sub_category
)

class << self
# Create a new object based on a hash.
# This is used to create a new object based on the server response.
def factory(attrs)
obj = self.new(attrs)
obj.unfold_languages

return obj
end
end

# Prefill name, privacy url
def unfold_languages
{
name: :name,
privacyPolicyUrl: :privacy_url
}.each do |json, attribute|
instance_variable_set("@#{attribute}".to_sym, LanguageItem.new(json, languages))
end
end

# Push all changes that were made back to iTunes Connect
def save!
client.update_app_details!(application.apple_id, raw_data)
end

# Custom Setters
#
def primary_category=(value)
value = "MZGenre.#{value}" unless value.include? "MZGenre"
super(value)
end

def primary_first_sub_category=(value)
value = "MZGenre.#{value}" unless value.include? "MZGenre"
super(value)
end

def primary_second_sub_category=(value)
value = "MZGenre.#{value}" unless value.include? "MZGenre"
super(value)
end

def secondary_category=(value)
value = "MZGenre.#{value}" unless value.include? "MZGenre"
super(value)
end

def secondary_first_sub_category=(value)
value = "MZGenre.#{value}" unless value.include? "MZGenre"
super(value)
end

def secondary_second_sub_category=(value)
value = "MZGenre.#{value}" unless value.include? "MZGenre"
super(value)
end

#####################################################
# @!group General
#####################################################
def setup
end
end
end
end
66 changes: 6 additions & 60 deletions lib/spaceship/tunes/app_version.rb
Expand Up @@ -20,19 +20,6 @@ class AppVersion < TunesBase
# @return (Bool) Is that the version that's currently available in the App Store?
attr_accessor :is_live

# Categories (e.g. MZGenre.Business)
attr_accessor :primary_category

attr_accessor :primary_first_sub_category

attr_accessor :primary_second_sub_category

attr_accessor :secondary_category

attr_accessor :secondary_first_sub_category

attr_accessor :secondary_second_sub_category

# @return (String) App Status (e.g. 'readyForSale'). You should use `app_status` instead
attr_accessor :raw_status

Expand Down Expand Up @@ -100,9 +87,6 @@ class AppVersion < TunesBase
# @return (Array) Raw access the all available languages. You shouldn't use it probbaly
attr_accessor :languages

# @return (Hash) A hash representing the app name in all languages
attr_reader :name

# @return (Hash) A hash representing the keywords in all languages
attr_reader :keywords

Expand All @@ -112,9 +96,6 @@ class AppVersion < TunesBase
# @return (Hash) The changelog
attr_reader :release_notes

# @return (Hash) A hash representing the keywords in all languages
attr_reader :privacy_url

# @return (Hash) A hash representing the keywords in all languages
attr_reader :support_url

Expand All @@ -133,13 +114,7 @@ class AppVersion < TunesBase
'details.value' => :languages,
'largeAppIcon.value.originalFileName' => :app_icon_original_name,
'largeAppIcon.value.url' => :app_icon_url,
'primaryCategory.value' => :primary_category,
'primaryFirstSubCategory.value' => :primary_first_sub_category,
'primarySecondSubCategory.value' => :primary_second_sub_category,
'releaseOnApproval.value' => :release_on_approval,
'secondaryCategory.value' => :secondary_category,
'secondaryFirstSubCategory.value' => :secondary_first_sub_category,
'secondarySecondSubCategory.value' => :secondary_second_sub_category,
'status' => :raw_status,
'supportsAppleWatch' => :supports_apple_watch,
'versionId' => :version_id,
Expand Down Expand Up @@ -169,9 +144,10 @@ def factory(attrs)

# @param application (Spaceship::Tunes::Application) The app this version is for
# @param app_id (String) The unique Apple ID of this app
# @param is_live (Boolean) Is that the version that's live in the App Store?
def find(application, app_id, is_live = false)
# @param is_live (Boolean)
def find(application, app_id, is_live)
attrs = client.app_version(app_id, is_live)
return nil unless attrs
attrs.merge!(application: application)
attrs.merge!(is_live: is_live)

Expand Down Expand Up @@ -226,7 +202,9 @@ def save!

# @return (String) An URL to this specific resource. You can enter this URL into your browser
def url
"https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/ra/ng/app/#{self.application.apple_id}/" + (self.is_live? ? "cur" : "")
url = "https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/ra/ng/app/904332168/ios/versioninfo/"
url += "deliverable" if self.is_live?
return url
end

# Private methods
Expand All @@ -246,10 +224,8 @@ def setup
# Prefill name, keywords, etc...
def unfold_languages
{
name: :name,
keywords: :keywords,
description: :description,
privacyURL: :privacy_url,
supportURL: :support_url,
marketingURL: :marketing_url,
releaseNotes: :release_notes
Expand All @@ -268,36 +244,6 @@ def supports_apple_watch
!super.nil?
end

def primary_category=(value)
value = "MZGenre.#{value}" unless value.include? "MZGenre"
super(value)
end

def primary_first_sub_category=(value)
value = "MZGenre.#{value}" unless value.include? "MZGenre"
super(value)
end

def primary_second_sub_category=(value)
value = "MZGenre.#{value}" unless value.include? "MZGenre"
super(value)
end

def secondary_category=(value)
value = "MZGenre.#{value}" unless value.include? "MZGenre"
super(value)
end

def secondary_first_sub_category=(value)
value = "MZGenre.#{value}" unless value.include? "MZGenre"
super(value)
end

def secondary_second_sub_category=(value)
value = "MZGenre.#{value}" unless value.include? "MZGenre"
super(value)
end

private

# generates the nested data structure to represent screenshots
Expand Down
18 changes: 12 additions & 6 deletions lib/spaceship/tunes/application.rb
Expand Up @@ -55,7 +55,7 @@ class << self
# Create a new object based on a hash.
# This is used to create a new object based on the server response.
def factory(attrs)
self.new(attrs)
return self.new(attrs)
end

# @return (Array) Returns all apps available for this account
Expand Down Expand Up @@ -106,12 +106,12 @@ def live_version

# @return (Spaceship::AppVersion) Receive the version that can fully be edited
def edit_version
# Apple's server will respond with the same version if there is only one, for both v=live and v=
# That's why we have to check in the app_summary.json request if there are 2 versions or just one
# if there is only one version, we'll return nil
if raw_data['versions'].count == 1
return nil # only live version, user should create a new version
end
# if raw_data['versions'].count == 1
# return nil # only live version, user should create a new version
# end
# TODO: Fix

Spaceship::AppVersion.find(self, self.apple_id, false)
end
Expand All @@ -134,6 +134,12 @@ def resolution_center
client.get_resolution_center(apple_id)
end

def details
attrs = client.app_details(apple_id)
attrs.merge!(application: self)
Tunes::AppDetails.factory(attrs)
end

#####################################################
# @!group Modifying
#####################################################
Expand Down Expand Up @@ -165,7 +171,7 @@ def build_trains
# These are all build that have no information except the upload date
# Those builds can also be the builds that are stuck on iTC.
def pre_processing_builds
data = client.build_trains(apple_id) # we need to fetch all trains here to get the builds
data = client.build_trains(apple_id, 'internal') # we need to fetch all trains here to get the builds

builds = data.fetch('processingBuilds', []).collect do |attrs|
attrs.merge!(build_train: self)
Expand Down