Skip to content

Commit

Permalink
Add iOS user steps tracking
Browse files Browse the repository at this point in the history
* Send CLI version, OS, platform, language, application Id, actions taken by the CLI and error logging
  • Loading branch information
Jeasmine committed Nov 29, 2021
1 parent 64e4bb8 commit 0b9e0ac
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 34 deletions.
19 changes: 14 additions & 5 deletions lib/oscli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,21 @@ class InstallCommand < Clamp::Command
option ["--path"], "PATH", "path to the project directory"
option ["--entrypoint"], "ENTRYPOINT", "Name of the target XCProject (ios) or appclassfile (android)"
option ["--lang"], "LANG", "programming language to use for ios (objc, swift) or android (java, kotlin)", default: ""
option ["--appid"], "[APPID]", "OneSignal App ID", default: ""
option ["--appid"], "[APPID]", "OneSignal App ID"

def execute
if type == 'ios'
if appid.nil? || appid.empty?
puts 'Please provide a project appId with the --appid option'
exit(1)
end

if !type
puts 'Please provide a project type (ios or android) with the --type option'
exit(1)
end

type_downcase = type.downcase
if type_downcase == 'ios'
langmap = {
'objc' => :objc,
'swift' => :swift
Expand All @@ -32,10 +43,8 @@ def execute
ios_proj = OSProject::IOS.new(path, target, language, appid)
xcodeproj_path = path + '/' + entrypoint + '.xcodeproj'
ios_proj.install_onesignal!(xcodeproj_path)
elsif type == 'android'
elsif type_downcase == 'android'
OSProject::GoogleAndroid.new(entrypoint, appid).add_sdk!()
elsif !type
puts 'Please provide a project type (ios or android) with the --type option'
else
puts 'Invalid type (ios or android)'
end
Expand Down
112 changes: 83 additions & 29 deletions lib/osproject_ios.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require_relative 'osproject'
require_relative 'osproject_helpers'
require_relative 'osnetwork'
require 'xcodeproj'

class OSProject::IOS < OSProject
Expand Down Expand Up @@ -38,14 +39,15 @@ def initialize(dir, target_name, lang, os_app_id)
def _add_sdk
# Order matters here
#Main target setup
_add_capabilities_to_main_target()
_add_os_init_to_app_target()
actions_taken = _add_capabilities_to_main_target()
actions_taken += _add_os_init_to_app_target()
#NSE setup
_create_nse()
_add_nse_to_app_target()
_add_app_groups_to_nse()
actions_taken += _create_nse()
actions_taken += _add_nse_to_app_target()
actions_taken += _add_app_groups_to_nse()
#Add OneSignal
_add_onesignal_dependency()
actions_taken += _add_onesignal_dependency()
NetworkHandler.instance.send_track_actions(app_id: os_app_id, platform: type, lang: lang, actions_taken: actions_taken)
end

def has_sdk?
Expand All @@ -62,12 +64,16 @@ def install_onesignal!(xcproj_path)
@project = Xcodeproj::Project.open(xcproj_path)
else
puts "Unable to open an xcodeproj at path: " + xcproj_path
error_track_message = "User provided a wrong xcodeproj path: #{xcproj_path};"
NetworkHandler.instance.send_track_error(app_id: os_app_id, platform: type, lang: lang, error_message: error_track_message)
exit(1)
end

@target = self.project.native_targets.find { |target| target.name == self.target_name}
if !self.target
puts "Unable to find an app target with name: " + self.target_name
error_track_message = "User provided a wrong target name;"
NetworkHandler.instance.send_track_error(app_id: os_app_id, platform: type, lang: lang, error_message: error_track_message)
exit(1)
end

Expand All @@ -84,10 +90,11 @@ def install_onesignal!(xcproj_path)
# Only use Cocoapods if a Podfile already exists. If not use SwiftPM
def _add_onesignal_dependency()
if File.exist?(self.dir + '/Podfile')
_add_onesignal_podspec_dependency()
return _add_onesignal_podspec_dependency()
else
_add_onesignal_sp_dependency()
_add_onesignal_framework_to_main_target()
actions_taken = _add_onesignal_sp_dependency()
actions_taken += _add_onesignal_framework_to_main_target()
return actions_taken
end
end

Expand All @@ -111,16 +118,23 @@ def _add_onesignal_podspec_dependency()
install_script = 'pod install --project-directory=' + self.dir
success = system(install_script)
if success
puts "Installed OneSignal pod"
message = "Installed OneSignal pod"
puts message
else
puts "Error adding OneSignal to Podfile"
internal_message = "Error adding OneSignal to Podfile"
message = "error=#{internal_message}"
puts internal_message
end

return "#{message};"
end

def _create_nse()
# Create NSE target
self.project.embedded_targets_in_native_target(self.target).each do |embedded_target|
return if embedded_target.name == 'OneSignalNotificationServiceExtension'
if embedded_target.name == 'OneSignalNotificationServiceExtension'
return ""
end
end
@nse = self.project.new_target(:app_extension, 'OneSignalNotificationServiceExtension', :ios, self.target.deployment_target, nil, lang)
self.nse.build_configuration_list.set_setting('PRODUCT_NAME', 'OneSignalNotificationServiceExtension')
Expand Down Expand Up @@ -166,12 +180,16 @@ def _create_nse()
self.nse_group.new_reference("OneSignalNotificationServiceExtension/Info.plist")
self.nse.build_configuration_list.set_setting('INFOPLIST_FILE', 'OneSignalNotificationServiceExtension/Info.plist')
end
puts "Created OneSignalNotificationServiceExtension"
message = "Created OneSignalNotificationServiceExtension"
puts message
self.project.save()
return "#{message};"
end

def _add_nse_to_app_target()
return if !self.nse
if !self.nse
return ""
end
unless self.target.dependency_for_target(self.nse)
self.target.add_dependency(self.nse)
nse_product = self.nse.product_reference
Expand All @@ -182,12 +200,20 @@ def _add_nse_to_app_target()
embed_extensions_plugins_phase = self.target.new_copy_files_build_phase('Embed App Extensions')
embed_extensions_plugins_phase.symbol_dst_subfolder_spec = :plug_ins
end
abort "Couldn't find 'Embed App Extensions Plugin' phase" if embed_extensions_plugins_phase.nil?


if embed_extensions_plugins_phase.nil?
error_track_message = "Couldn't find 'Embed App Extensions Plugin' phase"
NetworkHandler.instance.send_track_error(app_id: os_app_id, platform: type, lang: lang, error_message: error_track_message)
abort error_track_message
end

build_file = embed_extensions_plugins_phase.add_file_reference(nse_product)
build_file.settings = { "ATTRIBUTES" => ['RemoveHeadersOnCopy'] }
self.project.save()
puts "Added NSE to App target"

message = "Added NSE to App target"
puts message
return "#{message};"
end
end

Expand All @@ -210,8 +236,10 @@ def _add_onesignal_sp_dependency()

@onesignal_product_ref = Xcodeproj::Project::Object::XCSwiftPackageProductDependency.new(project, project.generate_uuid)
self.onesignal_product_ref.product_name = 'OneSignal'
puts "Added OneSignal Swift Package"
message = "Added OneSignal Swift Package"
puts message
self.project.save()
return "#{message};"
end

# add swift package binary to nse target
Expand All @@ -225,14 +253,19 @@ def _add_onesignal_framework_to_nse()
.each(&:remove_from_project)

self.nse.package_product_dependencies << self.onesignal_product_ref
puts "Added OneSignal Dependency to NSE"
message = "Added OneSignal Dependency to NSE"
puts message
self.project.save()
return "#{message};"
end

# app groups capability
# Creates OneSignalNotificationServiceExtension.entitlements if it doesn't exist
def _add_app_groups_to_nse()
return if !self.nse
if !self.nse
return ""
end

group_relative_entitlements_path = self.nse.name + "/" + self.nse.name + ".entitlements"
entitlements_path = dir + "/" + group_relative_entitlements_path
entitlements = {}
Expand All @@ -254,8 +287,10 @@ def _add_app_groups_to_nse()
self.nse_group.new_reference(group_relative_entitlements_path)
self.nse.build_configuration_list.set_setting('CODE_SIGN_ENTITLEMENTS', group_relative_entitlements_path)
end
puts "Added OneSignal App Group to NSE"
message = "Added OneSignal App Group to NSE"
puts message
self.project.save()
return "#{message};"
end

# add swift package binary to main target
Expand All @@ -265,24 +300,32 @@ def _add_onesignal_framework_to_main_target()
.each(&:remove_from_project)

self.target.package_product_dependencies << self.onesignal_product_ref
puts "Added OneSignal dependency to App target"
message = "Added OneSignal dependency to App target"
puts message
self.project.save()
return "#{message};"
end

# push capability in entitlments
# background capability with remote notifications enabled
# App group entitlement based on target bundle id
def _add_capabilities_to_main_target()

message = ""
#Update Info.plist of Target to include background modes with remote notifications
plist_path = dir + "/" + self.target.build_configuration_list.get_setting('INFOPLIST_FILE')['Debug']
info_plist = Xcodeproj::Plist.read_from_path(plist_path)
if info_plist["UIBackgroundModes"].nil?
info_plist["UIBackgroundModes"] = ["remote-notification"]
puts "Added remote notification background mode"
message = "Added remote notification background mode"
puts message
elsif !info_plist["UIBackgroundModes"].include? 'remote-notification'
info_plist["UIBackgroundModes"].push('remote-notification')
puts "Added remote notification background mode"
message = "Added remote notification background mode"
puts message
end

unless message.empty?
message = "#{message};"
end

Xcodeproj::Plist.write_to_path(info_plist, plist_path)
Expand All @@ -297,7 +340,9 @@ def _add_capabilities_to_main_target()
if entitlements['aps-environment'].nil?
entitlements['aps-environment'] = 'development'
Xcodeproj::Plist.write_to_path(entitlements, entitlements_path)
puts "Added push notification capability"
internal_message = "Added push notification capability"
message += "#{internal_message};"
puts internal_message
end
else
entitlements = {
Expand All @@ -306,25 +351,34 @@ def _add_capabilities_to_main_target()
Xcodeproj::Plist.write_to_path(entitlements, entitlements_path)
group.new_reference(self.target_name + ".entitlements")
self.target.build_configuration_list.set_setting('CODE_SIGN_ENTITLEMENTS', group_relative_entitlements_path)
puts "Added push notification capability"
internal_message = "Added push notification capability"
message += "#{internal_message};"
puts internal_message
end

# Add App Group to entitlements
bundle_id = self.target.build_configuration_list.get_setting('PRODUCT_BUNDLE_IDENTIFIER')["Debug"]
app_group_name = 'group.' + bundle_id + '.onesignal'
if entitlements['com.apple.security.application-groups'].nil?
entitlements['com.apple.security.application-groups'] = [app_group_name]
puts "Added OneSignal App Group"
internal_message = "Added OneSignal App Group"
message += "#{internal_message};"
puts internal_message
elsif !entitlements['com.apple.security.application-groups'].include? app_group_name
entitlements['com.apple.security.application-groups'].push(app_group_name)
puts "Added OneSignal App Group"
internal_message = "Added OneSignal App Group"
message += "#{internal_message};"
puts internal_message
end
Xcodeproj::Plist.write_to_path(entitlements, entitlements_path)
self.project.save()

return message
end

# depends on language and app lifecycle (appdelegate vs swiftui)
def _add_os_init_to_app_target()
return ""
end
end

0 comments on commit 0b9e0ac

Please sign in to comment.