MM-18490 Migrate app builds to circleCi (#3373)
* Add pods to source control * Update Fastlane to work with circleCi * Configure circleCi workflows to build the app * Set BRANCH_TO_BUILD env var to CIRCLE_BRANCH for PRs * Use different context for each platform and type * Fix regex * Add i18n check
This commit is contained in:
parent
4f1211a586
commit
010c099654
78 changed files with 6755 additions and 248 deletions
|
|
@ -1,5 +1,201 @@
|
|||
version: 2.1
|
||||
|
||||
executors:
|
||||
android:
|
||||
parameters:
|
||||
resource_class:
|
||||
default: large
|
||||
type: string
|
||||
environment:
|
||||
NODE_OPTIONS: --max_old_space_size=12000
|
||||
NODE_ENV: production
|
||||
BABEL_ENV: production
|
||||
docker:
|
||||
- image: circleci/android:api-27-node
|
||||
working_directory: ~/mattermost-mobile
|
||||
resource_class: <<parameters.resource_class>>
|
||||
|
||||
ios:
|
||||
environment:
|
||||
NODE_OPTIONS: --max_old_space_size=12000
|
||||
NODE_ENV: production
|
||||
BABEL_ENV: production
|
||||
macos:
|
||||
xcode: "11.0.0"
|
||||
working_directory: ~/mattermost-mobile
|
||||
shell: /bin/bash --login -o pipefail
|
||||
|
||||
commands:
|
||||
checkout-private:
|
||||
description: "Checkout the private repo with build env vars"
|
||||
steps:
|
||||
- add_ssh_keys:
|
||||
fingerprints:
|
||||
- "59:4d:99:5e:1c:6d:30:36:6d:60:76:88:ff:a7:ab:63"
|
||||
- run:
|
||||
name: Clone the mobile private repo
|
||||
command: git clone git@github.com:mattermost/mattermost-mobile-private.git ~/mattermost-mobile-private
|
||||
|
||||
android-gem-dependencies:
|
||||
description: "Get Fastlane dependencies for Android builds"
|
||||
steps:
|
||||
- restore_cache:
|
||||
name: Restore Fastlane cache
|
||||
key: v1-gems-android-{{ checksum "fastlane/Gemfile.lock" }}-{{ arch }}
|
||||
- run:
|
||||
working_directory: fastlane
|
||||
name: Download Fastlane dependencies
|
||||
command: bundle install --path vendor/bundle
|
||||
- save_cache:
|
||||
name: Save Fastlane cache
|
||||
key: v1-gems-android-{{ checksum "fastlane/Gemfile.lock" }}-{{ arch }}
|
||||
paths:
|
||||
- fastlane/vendor/bundle
|
||||
|
||||
android-gradle-dependencies:
|
||||
description: "Get Gradle dependencies for Android buils"
|
||||
steps:
|
||||
- restore_cache:
|
||||
name: Restore Gradle cache
|
||||
key: v1-gradle-{{ checksum "android/build.gradle" }}-{{ checksum "android/app/build.gradle" }}
|
||||
- run:
|
||||
working_directory: android
|
||||
name: Download Gradle dependencies
|
||||
command: ./gradlew dependencies
|
||||
- save_cache:
|
||||
name: Save Gradle cache
|
||||
paths:
|
||||
- ~/.gradle
|
||||
key: v1-gradle-{{ checksum "android/build.gradle" }}-{{ checksum "android/app/build.gradle" }}
|
||||
|
||||
assets:
|
||||
description: "Generate app assets"
|
||||
steps:
|
||||
- restore_cache:
|
||||
name: Restore assets cache
|
||||
key: v1-assets-{{ checksum "assets/base/config.json" }}-{{ arch }}
|
||||
- run:
|
||||
name: Generate assets
|
||||
command: make dist/assets
|
||||
- save_cache:
|
||||
name: Save assets cache
|
||||
key: v1-assets-{{ checksum "assets/base/config.json" }}-{{ arch }}
|
||||
paths:
|
||||
- dist
|
||||
|
||||
ios-gem-dependencies:
|
||||
description: "Get Fastlane dependencies for iOS builds"
|
||||
steps:
|
||||
- run:
|
||||
name: Set Ruby version
|
||||
command: echo "ruby-2.6.3" > ~/.ruby-version
|
||||
- restore_cache:
|
||||
name: Restore Fastlane cache
|
||||
key: v1-gems-ios-{{ checksum "fastlane/Gemfile.lock" }}-{{ arch }}
|
||||
- run:
|
||||
working_directory: fastlane
|
||||
name: Download Fastlane dependencies
|
||||
command: bundle install --path vendor/bundle
|
||||
- save_cache:
|
||||
name: Save Fastlane cache
|
||||
key: v1-gems-ios-{{ checksum "fastlane/Gemfile.lock" }}-{{ arch }}
|
||||
paths:
|
||||
- fastlane/vendor/bundle
|
||||
|
||||
npm-dependencies:
|
||||
description: "Get JavaScript dependencies for the job"
|
||||
steps:
|
||||
- restore_cache:
|
||||
name: Restore npm cache
|
||||
key: v1-npm-{{ checksum "package.json" }}-{{ arch }}
|
||||
- run:
|
||||
name: Getting JavaScript dependencies
|
||||
command: NODE_ENV=development npm install
|
||||
- save_cache:
|
||||
name: Save npm cache
|
||||
key: v1-npm-{{ checksum "package.json" }}-{{ arch }}
|
||||
paths:
|
||||
- node_modules
|
||||
|
||||
build-android:
|
||||
description: "Build the android app"
|
||||
steps:
|
||||
- checkout:
|
||||
path: ~/mattermost-mobile
|
||||
- checkout-private
|
||||
- npm-dependencies
|
||||
- assets
|
||||
- android-gem-dependencies
|
||||
- android-gradle-dependencies
|
||||
- run:
|
||||
name: Append Keystore to build Android
|
||||
command: |
|
||||
cp ~/mattermost-mobile-private/android/${STORE_FILE} android/app/${STORE_FILE}
|
||||
echo MATTERMOST_RELEASE_STORE_FILE=${STORE_FILE} | tee -a android/gradle.properties > /dev/null
|
||||
echo ${STORE_ALIAS} | tee -a android/gradle.properties > /dev/null
|
||||
echo ${STORE_PASSWORD} | tee -a android/gradle.properties > /dev/null
|
||||
- run:
|
||||
working_directory: fastlane
|
||||
name: Run fastlane to build android
|
||||
no_output_timeout: 30m
|
||||
command: bundle exec fastlane android build || exit 1
|
||||
|
||||
build-ios:
|
||||
description: "Build the iOS app"
|
||||
steps:
|
||||
- checkout:
|
||||
path: ~/mattermost-mobile
|
||||
- npm-dependencies
|
||||
- assets
|
||||
- ios-gem-dependencies
|
||||
- run:
|
||||
working_directory: fastlane
|
||||
name: Run fastlane to build iOS
|
||||
no_output_timeout: 30m
|
||||
command: bundle exec fastlane ios build || exit 1
|
||||
|
||||
deploy-android:
|
||||
description: "Deploy apk to Google Play"
|
||||
parameters:
|
||||
apk_path:
|
||||
type: string
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: ~/mattermost-mobile
|
||||
- deploy:
|
||||
name: "Deploy apk to Google Play"
|
||||
working_directory: fastlane
|
||||
command: bundle exec fastlane android deploy apk:../<<parameters.apk_path>>
|
||||
|
||||
deploy-ios:
|
||||
description: "Deploy ipa to TestFlight"
|
||||
parameters:
|
||||
ipa_path:
|
||||
type: string
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: ~/mattermost-mobile
|
||||
- deploy:
|
||||
name: "Deploy ipa to TestFlight"
|
||||
working_directory: fastlane
|
||||
command: bundle exec fastlane ios deploy ipa:../<<parameters.ipa_path>>
|
||||
|
||||
persist:
|
||||
description: "Persist mattermost-mobile directory"
|
||||
steps:
|
||||
- persist_to_workspace:
|
||||
root: ./
|
||||
paths:
|
||||
- ./
|
||||
|
||||
save:
|
||||
description: "Save binaries artifacts"
|
||||
parameters:
|
||||
filename:
|
||||
type: string
|
||||
steps:
|
||||
- store_artifacts:
|
||||
path: ~/mattermost-mobile/<<parameters.filename>>
|
||||
|
||||
jobs:
|
||||
test:
|
||||
|
|
@ -7,17 +203,201 @@ jobs:
|
|||
docker:
|
||||
- image: circleci/node:10
|
||||
steps:
|
||||
- checkout
|
||||
- run: |
|
||||
echo assets/base/config.json
|
||||
cat assets/base/config.json
|
||||
# Avoid installing pods
|
||||
touch .podinstall
|
||||
# Run tests
|
||||
make test || exit 1
|
||||
- checkout:
|
||||
path: ~/mattermost-mobile
|
||||
- npm-dependencies
|
||||
- assets
|
||||
- run:
|
||||
name: Check styles
|
||||
command: npm run check
|
||||
- run:
|
||||
name: Running Tests
|
||||
command: npm test
|
||||
- run:
|
||||
name: Check i18n
|
||||
command: make i18n-extract-ci
|
||||
|
||||
build-android-beta:
|
||||
executor: android
|
||||
steps:
|
||||
- build-android
|
||||
- persist
|
||||
- save:
|
||||
filename: "Mattermost_Beta.apk"
|
||||
|
||||
build-android-release:
|
||||
executor: android
|
||||
steps:
|
||||
- build-android
|
||||
- persist
|
||||
- save:
|
||||
filename: "Mattermost.apk"
|
||||
|
||||
build-android-pr:
|
||||
executor: android
|
||||
environment:
|
||||
BRANCH_TO_BUILD: ${CIRCLE_BRANCH}
|
||||
steps:
|
||||
- build-android
|
||||
- persist
|
||||
- save:
|
||||
filename: "Mattermost_Beta.apk"
|
||||
|
||||
build-ios-beta:
|
||||
executor: ios
|
||||
steps:
|
||||
- build-ios
|
||||
- persist
|
||||
- save:
|
||||
filename: "Mattermost_Beta.ipa"
|
||||
|
||||
build-ios-release:
|
||||
executor: ios
|
||||
steps:
|
||||
- build-ios
|
||||
- persist
|
||||
- save:
|
||||
filename: "Mattermost.ipa"
|
||||
|
||||
build-ios-pr:
|
||||
executor: ios
|
||||
environment:
|
||||
BRANCH_TO_BUILD: ${CIRCLE_BRANCH}
|
||||
steps:
|
||||
- build-ios
|
||||
- persist
|
||||
- save:
|
||||
filename: "Mattermost_Beta.ipa"
|
||||
|
||||
deploy-android-release:
|
||||
executor:
|
||||
name: android
|
||||
resource_class: medium
|
||||
steps:
|
||||
- deploy-android:
|
||||
apk_path: Mattermost.apk
|
||||
|
||||
deploy-android-beta:
|
||||
executor:
|
||||
name: android
|
||||
resource_class: medium
|
||||
steps:
|
||||
- deploy-android:
|
||||
apk_path: Mattermost_Beta.apk
|
||||
|
||||
deploy-ios-release:
|
||||
executor: ios
|
||||
steps:
|
||||
- deploy-ios:
|
||||
ipa_path: Mattermost.ipa
|
||||
|
||||
deploy-ios-beta:
|
||||
executor: ios
|
||||
steps:
|
||||
- deploy-ios:
|
||||
ipa_path: Mattermost_Beta.ipa
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
pr-test:
|
||||
build:
|
||||
jobs:
|
||||
- test
|
||||
|
||||
- build-android-release:
|
||||
context: mattermost-mobile-android-release
|
||||
requires:
|
||||
- test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /^build-\d+$/
|
||||
- /^build-android-\d+$/
|
||||
- /^build-android-release-\d+$/
|
||||
- deploy-android-release:
|
||||
context: mattermost-mobile-android-release
|
||||
requires:
|
||||
- build-android-release
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /^build-\d+$/
|
||||
- /^build-android-\d+$/
|
||||
- /^build-android-release-\d+$/
|
||||
|
||||
- build-android-beta:
|
||||
context: mattermost-mobile-android-beta
|
||||
requires:
|
||||
- test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /^build-\d+$/
|
||||
- /^build-android-\d+$/
|
||||
- /^build-android-beta-\d+$/
|
||||
- deploy-android-beta:
|
||||
context: mattermost-mobile-android-beta
|
||||
requires:
|
||||
- build-android-beta
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /^build-\d+$/
|
||||
- /^build-android-\d+$/
|
||||
- /^build-android-beta-\d+$/
|
||||
|
||||
- build-ios-release:
|
||||
context: mattermost-mobile-ios-release
|
||||
requires:
|
||||
- test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /^build-\d+$/
|
||||
- /^build-ios-\d+$/
|
||||
- /^build-ios-release-\d+$/
|
||||
- deploy-ios-release:
|
||||
context: mattermost-mobile-ios-release
|
||||
requires:
|
||||
- build-ios-release
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /^build-\d+$/
|
||||
- /^build-ios-\d+$/
|
||||
- /^build-ios-release-\d+$/
|
||||
|
||||
- build-ios-beta:
|
||||
context: mattermost-mobile-ios-beta
|
||||
requires:
|
||||
- test
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /^build-\d+$/
|
||||
- /^build-ios-\d+$/
|
||||
- /^build-ios-beta-\d+$/
|
||||
- deploy-ios-beta:
|
||||
context: mattermost-mobile-ios-beta
|
||||
requires:
|
||||
- build-ios-beta
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /^build-\d+$/
|
||||
- /^build-ios-\d+$/
|
||||
- /^build-ios-beta-\d+$/
|
||||
|
||||
- build-android-pr:
|
||||
context: mattermost-mobile-android-pr
|
||||
requires:
|
||||
- test
|
||||
filters:
|
||||
branches:
|
||||
only: /^build-pr-.*/
|
||||
- build-ios-pr:
|
||||
context: mattermost-mobile-ios-pr
|
||||
requires:
|
||||
- test
|
||||
filters:
|
||||
branches:
|
||||
only: /^build-pr-.*/
|
||||
|
|
|
|||
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -85,10 +85,6 @@ ios/sentry.properties
|
|||
.nyc_output
|
||||
coverage
|
||||
|
||||
# Pods
|
||||
.podinstall
|
||||
ios/Pods/
|
||||
|
||||
# Bundle artifact
|
||||
*.jsbundle
|
||||
|
||||
|
|
|
|||
18
Makefile
18
Makefile
|
|
@ -31,18 +31,6 @@ npm-ci: package.json
|
|||
@echo Getting Javascript dependencies
|
||||
@npm ci
|
||||
|
||||
.podinstall:
|
||||
ifeq ($(OS), Darwin)
|
||||
ifdef POD
|
||||
@echo Getting Cocoapods dependencies;
|
||||
@cd ios && pod install;
|
||||
else
|
||||
@echo "Cocoapods is not installed https://cocoapods.org/"
|
||||
@exit 1
|
||||
endif
|
||||
endif
|
||||
@touch $@
|
||||
|
||||
dist/assets: $(BASE_ASSETS) $(OVERRIDE_ASSETS)
|
||||
@mkdir -p dist
|
||||
|
||||
|
|
@ -53,9 +41,9 @@ dist/assets: $(BASE_ASSETS) $(OVERRIDE_ASSETS)
|
|||
@echo "Generating app assets"
|
||||
@node scripts/make-dist-assets.js
|
||||
|
||||
pre-run: | node_modules .podinstall dist/assets ## Installs dependencies and assets
|
||||
pre-run: | node_modules dist/assets ## Installs dependencies and assets
|
||||
|
||||
pre-build: | npm-ci .podinstall dist/assets ## Install dependencies and assets before building
|
||||
pre-build: | npm-ci dist/assets ## Install dependencies and assets before building
|
||||
|
||||
check-style: node_modules ## Runs eslint
|
||||
@echo Checking for style guide compliance
|
||||
|
|
@ -65,10 +53,8 @@ clean: ## Cleans dependencies, previous builds and temp files
|
|||
@echo Cleaning started
|
||||
|
||||
@rm -rf node_modules
|
||||
@rm -f .podinstall
|
||||
@rm -rf dist
|
||||
@rm -rf ios/build
|
||||
@rm -rf ios/Pods
|
||||
@rm -rf android/app/build
|
||||
|
||||
@echo Cleanup finished
|
||||
|
|
|
|||
|
|
@ -11,69 +11,69 @@ configured = false
|
|||
is_build_pr = false
|
||||
|
||||
# Executes before anything else use to setup the script
|
||||
before_all do |lane, options|
|
||||
if lane.to_s == 'build_pr'
|
||||
pr = options[:pr]
|
||||
UI.success("Building #{pr}")
|
||||
ENV['BRANCH_TO_BUILD'] = pr
|
||||
is_build_pr = true
|
||||
end
|
||||
before_all do
|
||||
is_build_pr = ENV['BUILD_PR'] == 'true'
|
||||
UI.success("Building for release #{ENV['BUILD_FOR_RELEASE']}")
|
||||
|
||||
# Raises an error is git is not clean
|
||||
if ENV['COMMIT_CHANGES_TO_GIT'] == 'true'
|
||||
ensure_git_status_clean
|
||||
end
|
||||
if ENV['CIRCLECI'] != 'true'
|
||||
# Raises an error is git is not clean
|
||||
if ENV['COMMIT_CHANGES_TO_GIT'] == 'true'
|
||||
ensure_git_status_clean
|
||||
end
|
||||
|
||||
# Block to ensure we are on the right branch
|
||||
branch = ENV['BRANCH_TO_BUILD'] || ENV['GIT_BRANCH']
|
||||
begin
|
||||
ensure_git_branch(
|
||||
branch: branch
|
||||
)
|
||||
rescue
|
||||
sh "git checkout #{branch}"
|
||||
UI.success("Using branch \"#{branch}\"")
|
||||
end
|
||||
# Block to ensure we are on the right branch
|
||||
branch = ENV['BRANCH_TO_BUILD'] || ENV['GIT_BRANCH']
|
||||
begin
|
||||
ensure_git_branch(
|
||||
branch: branch
|
||||
)
|
||||
rescue
|
||||
sh "git checkout #{branch}"
|
||||
UI.success("Using branch \"#{branch}\"")
|
||||
end
|
||||
|
||||
# If we are going to commit changes to git create a separate branch
|
||||
# so no changes are done in the branch that is being built
|
||||
if ENV['COMMIT_CHANGES_TO_GIT'] == 'true'
|
||||
local_branch = ENV['GIT_LOCAL_BRANCH'] || 'build'
|
||||
sh "git checkout -b #{local_branch}"
|
||||
UI.success("Creating branch \"#{local_branch}\"")
|
||||
# If we are going to commit changes to git create a separate branch
|
||||
# so no changes are done in the branch that is being built
|
||||
if ENV['COMMIT_CHANGES_TO_GIT'] == 'true'
|
||||
local_branch = ENV['GIT_LOCAL_BRANCH'] || 'build'
|
||||
sh "git checkout -b #{local_branch}"
|
||||
UI.success("Creating branch \"#{local_branch}\"")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
after_all do |lane|
|
||||
if lane.to_s == 'build'
|
||||
submit_to_store
|
||||
end
|
||||
|
||||
if ENV['RESET_GIT_BRANCH'] == 'true'
|
||||
branch = ENV['BRANCH_TO_BUILD'] || 'master'
|
||||
package_id = ENV['MAIN_APP_IDENTIFIER'] || 'com.mattermost.rnbeta'
|
||||
beta_dir = '../android/app/src/main/java/com/mattermost/rnbeta'
|
||||
release_dir = "../android/app/src/main/java/#{package_id.gsub '.', '/'}"
|
||||
|
||||
if beta_dir != release_dir
|
||||
sh "rm -rf #{release_dir}"
|
||||
if ENV['CIRCLECI'] != 'true'
|
||||
if lane.to_s == 'build'
|
||||
submit_to_store
|
||||
end
|
||||
|
||||
reset_git_repo(
|
||||
force: true,
|
||||
skip_clean: true
|
||||
)
|
||||
sh "git checkout #{branch}"
|
||||
if ENV['RESET_GIT_BRANCH'] == 'true'
|
||||
branch = ENV['BRANCH_TO_BUILD'] || 'master'
|
||||
package_id = ENV['MAIN_APP_IDENTIFIER'] || 'com.mattermost.rnbeta'
|
||||
beta_dir = '../android/app/src/main/java/com/mattermost/rnbeta'
|
||||
release_dir = "../android/app/src/main/java/#{package_id.gsub '.', '/'}"
|
||||
|
||||
if ENV['COMMIT_CHANGES_TO_GIT'] == 'true'
|
||||
local_branch = ENV['GIT_LOCAL_BRANCH'] || 'build'
|
||||
sh "git branch -D #{local_branch}"
|
||||
UI.success("Deleted working branch \"#{local_branch}\"")
|
||||
if lane.to_s == 'build_pr'
|
||||
sh 'git checkout master'
|
||||
## Remove the branch for the PR
|
||||
sh "git branch -D #{branch}"
|
||||
UI.success("Deleted PR branch \"#{branch}\"")
|
||||
if beta_dir != release_dir
|
||||
sh "rm -rf #{release_dir}"
|
||||
end
|
||||
|
||||
reset_git_repo(
|
||||
force: true,
|
||||
skip_clean: true
|
||||
)
|
||||
sh "git checkout #{branch}"
|
||||
|
||||
if ENV['COMMIT_CHANGES_TO_GIT'] == 'true'
|
||||
local_branch = ENV['GIT_LOCAL_BRANCH'] || 'build'
|
||||
sh "git branch -D #{local_branch}"
|
||||
UI.success("Deleted working branch \"#{local_branch}\"")
|
||||
if lane.to_s == 'build_pr'
|
||||
sh 'git checkout master'
|
||||
## Remove the branch for the PR
|
||||
sh "git branch -D #{branch}"
|
||||
UI.success("Deleted PR branch \"#{branch}\"")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -196,20 +196,110 @@ lane :unsigned do
|
|||
unsigned
|
||||
end
|
||||
|
||||
desc 'Build the app using a PR so QA can test'
|
||||
lane :build_pr do
|
||||
configure
|
||||
desc 'Upload file to s3'
|
||||
lane :upload_file_to_s3 do |options|
|
||||
os_type = options[:os_type]
|
||||
file = options[:file]
|
||||
file_plist = ""
|
||||
|
||||
# Build the android app
|
||||
self.runner.current_platform = :android
|
||||
build
|
||||
if file.nil? || file.empty?
|
||||
app_name = ENV['APP_NAME'] || 'Mattermost Beta'
|
||||
filename = app_name.gsub(" ", "_")
|
||||
|
||||
# Build the ios app
|
||||
self.runner.current_platform = :ios
|
||||
build
|
||||
if os_type == 'Android'
|
||||
file = "#{filename}.apk"
|
||||
elsif os_type == 'iOS'
|
||||
file = "#{filename}.ipa"
|
||||
file_plist = "#{filename}.plist"
|
||||
end
|
||||
end
|
||||
|
||||
build_folder_path = Dir[File.expand_path('..')].first
|
||||
file_path = "#{build_folder_path}/#{file}"
|
||||
|
||||
unless ENV['AWS_BUCKET_NAME'].nil? || ENV['AWS_BUCKET_NAME'].empty? || ENV['AWS_REGION'].nil? || ENV['AWS_REGION'].empty? || file_path.nil?
|
||||
s3_region = ENV['AWS_REGION']
|
||||
s3_bucket = ENV['AWS_BUCKET_NAME']
|
||||
s3_folder = ''
|
||||
|
||||
version_number = ''
|
||||
build_number = ''
|
||||
|
||||
if is_build_pr
|
||||
s3_folder = "#{ENV['AWS_FOLDER_NAME']}/#{ENV['BRANCH_TO_BUILD']}"
|
||||
else
|
||||
if os_type == 'Android'
|
||||
version_number = android_get_version_name(gradle_file: './android/app/build.gradle')
|
||||
build_number = android_get_version_code(gradle_file: './android/app/build.gradle')
|
||||
elsif os_type == 'iOS'
|
||||
version_number = get_version_number(xcodeproj: './ios/Mattermost.xcodeproj', target: 'Mattermost')
|
||||
build_number = get_build_number(xcodeproj: './ios/Mattermost.xcodeproj')
|
||||
end
|
||||
|
||||
s3_folder = "#{ENV['AWS_FOLDER_NAME']}/#{version_number}/#{build_number}"
|
||||
end
|
||||
|
||||
s3 = Aws::S3::Resource.new(region: s3_region)
|
||||
file_obj = s3.bucket(s3_bucket).object("#{s3_folder}/#{file}")
|
||||
file_obj.upload_file("#{file_path}")
|
||||
|
||||
if is_build_pr
|
||||
if os_type == 'Android'
|
||||
install_url = "https://#{s3_bucket}/#{s3_folder}/#{file}"
|
||||
elsif os_type == 'iOS'
|
||||
current_build_number = get_build_number(xcodeproj: './ios/Mattermost.xcodeproj')
|
||||
plist_template = File.read('plist.erb')
|
||||
plist_body = ERB.new(plist_template).result(binding)
|
||||
|
||||
plist_obj = s3.bucket(s3_bucket).object("#{s3_folder}/#{file_plist}")
|
||||
plist_obj.put(body: plist_body)
|
||||
|
||||
install_url = "itms-services://?action=download-manifest&url=https://#{s3_bucket}/#{s3_folder}/#{file_plist}"
|
||||
end
|
||||
|
||||
qa_build_message({
|
||||
:os_type => os_type,
|
||||
:install_url => install_url
|
||||
})
|
||||
end
|
||||
|
||||
public_link = "https://#{s3_bucket}/#{s3_folder}/#{file}"
|
||||
if file == 'Mattermost-simulator-x86_64.app.zip'
|
||||
pretext = '#### New iOS build for VM/Simulator'
|
||||
msg = "Download link: #{public_link}"
|
||||
send_message_to_mattermost({
|
||||
:version_number => version_number,
|
||||
:build_number => build_number,
|
||||
:pretext => pretext,
|
||||
:title => '',
|
||||
:thumb_url => 'https://support.apple.com/library/content/dam/edam/applecare/images/en_US/iOS/move-to-ios-icon.png',
|
||||
:msg => msg,
|
||||
:default_payloads => [],
|
||||
:success => true,
|
||||
})
|
||||
end
|
||||
|
||||
UI.success("S3 bucket @#{s3_bucket}, object @#{s3_folder}/#{file}")
|
||||
UI.success("S3 public path: #{public_link}")
|
||||
end
|
||||
end
|
||||
|
||||
platform :ios do
|
||||
before_all do
|
||||
if ENV['CIRCLECI'] == 'true'
|
||||
setup_circle_ci
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Get iOS adhoc profiles'
|
||||
lane :adhoc do
|
||||
if ENV['MATCH_TYPE'] != 'adhoc' && !ENV['MATCH_PASSWORD'].nil? && !ENV['MATCH_PASSWORD'].empty?
|
||||
match(
|
||||
type: 'adhoc'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Build iOS app'
|
||||
lane :build do
|
||||
unless configured
|
||||
|
|
@ -321,7 +411,7 @@ platform :ios do
|
|||
)
|
||||
|
||||
# Sync the provisioning profiles using match
|
||||
if ENV['SYNC_PROVISIONING_PROFILES'] == 'true'
|
||||
if ENV['SYNC_PROVISIONING_PROFILES'] == 'true' && !ENV['MATCH_PASSWORD'].nil? && !ENV['MATCH_PASSWORD'].empty?
|
||||
match(type: ENV['MATCH_TYPE'] || 'adhoc')
|
||||
end
|
||||
end
|
||||
|
|
@ -333,6 +423,14 @@ platform :ios do
|
|||
end
|
||||
end
|
||||
|
||||
lane :deploy do |options|
|
||||
ipa_path = options[:ipa]
|
||||
|
||||
unless ipa_path.nil?
|
||||
submit_to_testflight(ipa_path)
|
||||
end
|
||||
end
|
||||
|
||||
error do |lane, exception|
|
||||
version = get_version_number(xcodeproj: './ios/Mattermost.xcodeproj', target: 'Mattermost')
|
||||
build_number = get_build_number(xcodeproj: './ios/Mattermost.xcodeproj')
|
||||
|
|
@ -348,12 +446,37 @@ platform :ios do
|
|||
})
|
||||
end
|
||||
|
||||
def setup_code_signing
|
||||
disable_automatic_code_signing(path: './ios/Mattermost.xcodeproj')
|
||||
|
||||
ENV['MATCH_APP_IDENTIFIER'].split(',').each do |id|
|
||||
target = 'Mattermost'
|
||||
if id.include? 'NotificationService'
|
||||
target = 'NotificationService'
|
||||
elsif id.include? 'MattermostShare'
|
||||
target = 'MattermostShare'
|
||||
end
|
||||
|
||||
profile = "sigh_#{id}_#{ENV['MATCH_TYPE']}"
|
||||
|
||||
update_project_provisioning(
|
||||
xcodeproj: './ios/Mattermost.xcodeproj',
|
||||
profile: ENV["#{profile}_profile-path"], # optional if you use sigh
|
||||
target_filter: ".*#{target}$", # matches name or type of a target
|
||||
build_configuration: 'Release',
|
||||
code_signing_identity: 'iPhone Distribution' # optionally specify the codesigning identity
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def build_ios()
|
||||
app_name = ENV['APP_NAME'] || 'Mattermost Beta'
|
||||
app_name_sub = app_name.gsub(" ", "_")
|
||||
config_mode = ENV['BUILD_FOR_RELEASE'] == 'true' ? 'Release' : 'Debug'
|
||||
method = ENV['IOS_BUILD_EXPORT_METHOD'].nil? || ENV['IOS_BUILD_EXPORT_METHOD'].empty? ? 'ad-hoc' : ENV['IOS_BUILD_EXPORT_METHOD']
|
||||
|
||||
setup_code_signing
|
||||
|
||||
gym(
|
||||
clean: true,
|
||||
scheme: 'Mattermost',
|
||||
|
|
@ -362,6 +485,7 @@ platform :ios do
|
|||
export_method: method,
|
||||
skip_profile_detection: true,
|
||||
output_name: "#{app_name_sub}.ipa",
|
||||
export_xcargs: "-allowProvisioningUpdates",
|
||||
export_options: {
|
||||
signingStyle: 'manual',
|
||||
iCloudContainerEnvironment: 'Production'
|
||||
|
|
@ -483,6 +607,14 @@ platform :android do
|
|||
end
|
||||
end
|
||||
|
||||
lane :deploy do |options|
|
||||
apk_path = options[:apk]
|
||||
|
||||
unless apk_path.nil?
|
||||
submit_to_google_play(apk_path)
|
||||
end
|
||||
end
|
||||
|
||||
error do |lane, exception|
|
||||
build_number = android_get_version_code(
|
||||
gradle_file: './android/app/build.gradle'
|
||||
|
|
@ -587,83 +719,102 @@ def send_message_to_mattermost(options)
|
|||
end
|
||||
end
|
||||
|
||||
def submit_to_testflight(ipa_path)
|
||||
app_name = ENV['APP_NAME'] || 'Mattermost Beta'
|
||||
app_name_sub = app_name.gsub(" ", "_")
|
||||
|
||||
if(File.file?(ipa_path))
|
||||
UI.success("ipa file #{ipa_path}")
|
||||
upload_to_tesflight(
|
||||
ipa: ipa_path
|
||||
)
|
||||
else
|
||||
UI.user_error! "ipa file does not exist #{ipa_path}"
|
||||
return
|
||||
end
|
||||
|
||||
version_number = get_version_number(xcodeproj: './ios/Mattermost.xcodeproj', target: 'Mattermost')
|
||||
build_number = get_build_number(xcodeproj: './ios/Mattermost.xcodeproj')
|
||||
s3_folder = "#{ENV['AWS_FOLDER_NAME']}/#{version_number}/#{build_number}"
|
||||
public_link = "https://#{ENV['AWS_BUCKET_NAME']}/#{s3_folder}/#{app_name_sub}.ipa"
|
||||
|
||||
|
||||
# Send a build message to Mattermost
|
||||
pretext = '#### New iOS released ready to be published'
|
||||
msg = "Release has been cut and is on TestFlight ready to be published.\nDownload link: #{public_link}"
|
||||
|
||||
if ENV['BETA_BUILD'] == 'true'
|
||||
pretext = '#### New iOS beta published to TestFlight'
|
||||
msg = "Sign up as a beta tester [here](https://testflight.apple.com/join/Q7Rx7K9P).\nDownload link: #{public_link}"
|
||||
end
|
||||
|
||||
send_message_to_mattermost({
|
||||
:version_number => version_number,
|
||||
:build_number => build_number,
|
||||
:pretext => pretext,
|
||||
:title => '',
|
||||
:thumb_url => 'https://support.apple.com/library/content/dam/edam/applecare/images/en_US/iOS/move-to-ios-icon.png',
|
||||
:msg => msg,
|
||||
:default_payloads => [],
|
||||
:success => true,
|
||||
})
|
||||
end
|
||||
|
||||
def submit_to_google_play(apk_path)
|
||||
app_name = ENV['APP_NAME'] || 'Mattermost Beta'
|
||||
app_name_sub = app_name.gsub(" ", "_")
|
||||
|
||||
if(File.file?(apk_path))
|
||||
UI.success("apk file #{apk_path}")
|
||||
unless ENV['SUPPLY_JSON_KEY'].nil? || ENV['SUPPLY_JSON_KEY'].empty?
|
||||
supply(
|
||||
track: ENV['SUPPLY_TRACK'] || 'alpha',
|
||||
apk: apk_path
|
||||
)
|
||||
end
|
||||
else
|
||||
UI.user_error! "apk file does not exist #{apk_path}"
|
||||
return
|
||||
end
|
||||
|
||||
version_number = android_get_version_name(gradle_file: './android/app/build.gradle')
|
||||
build_number = android_get_version_code(gradle_file: './android/app/build.gradle')
|
||||
s3_folder = "#{ENV['AWS_FOLDER_NAME']}/#{version_number}/#{build_number}"
|
||||
public_link = "https://#{ENV['AWS_BUCKET_NAME']}/#{s3_folder}/#{app_name_sub}.apk"
|
||||
|
||||
# Send a build message to Mattermost
|
||||
pretext = '#### New Android released ready to be published'
|
||||
msg = "Release has been cut and is on the Beta track ready to be published.\nDownload link: #{public_link}"
|
||||
|
||||
if ENV['BETA_BUILD'] == 'true'
|
||||
pretext = '#### New Android beta published to Google Play'
|
||||
msg = "Sign up as a beta tester [here](https://play.google.com/apps/testing/com.mattermost.rnbeta).\nDownload link: #{public_link}"
|
||||
end
|
||||
|
||||
send_message_to_mattermost({
|
||||
:version_number => version_number,
|
||||
:build_number => build_number,
|
||||
:pretext => pretext,
|
||||
:title => '',
|
||||
:thumb_url => 'https://lh3.ggpht.com/XL0CrI8skkxnboGct-duyg-bZ_MxJDTrjczyjdU8OP2PM1dmj7SP4jL1K8JQeMIB3AM=w300',
|
||||
:msg => msg,
|
||||
:default_payloads => [],
|
||||
:success => true,
|
||||
})
|
||||
end
|
||||
|
||||
def submit_to_store
|
||||
apk_path = lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]
|
||||
ipa_path = lane_context[SharedValues::IPA_OUTPUT_PATH]
|
||||
|
||||
app_name = ENV['APP_NAME'] || 'Mattermost Beta'
|
||||
app_name_sub = app_name.gsub(" ", "_")
|
||||
|
||||
s3_region = ENV['AWS_REGION']
|
||||
s3_bucket = ENV['AWS_BUCKET_NAME']
|
||||
|
||||
# Submit to Google Play if required
|
||||
if !apk_path.nil? && ENV['SUBMIT_ANDROID_TO_GOOGLE_PLAY'] == 'true'
|
||||
UI.success("apk file #{apk_path}")
|
||||
|
||||
supply(
|
||||
track: ENV['SUPPLY_TRACK'] || 'alpha',
|
||||
apk: apk_path
|
||||
)
|
||||
|
||||
version_number = android_get_version_name(gradle_file: './android/app/build.gradle')
|
||||
build_number = android_get_version_code(gradle_file: './android/app/build.gradle')
|
||||
|
||||
s3_folder = "#{ENV['AWS_FOLDER_NAME']}/#{version_number}/#{build_number}"
|
||||
public_link = "https://#{s3_bucket}/#{s3_folder}/#{app_name_sub}.apk"
|
||||
|
||||
# Send a build message to Mattermost
|
||||
pretext = '#### New Android released ready to be published'
|
||||
msg = "Release has been cut and is on the Beta track ready to be published.\nDownload link: #{public_link}"
|
||||
|
||||
if ENV['BETA_BUILD'] == 'true'
|
||||
pretext = '#### New Android beta published to Google Play'
|
||||
msg = "Sign up as a beta tester [here](https://play.google.com/apps/testing/com.mattermost.rnbeta).\nDownload link: #{public_link}"
|
||||
end
|
||||
|
||||
send_message_to_mattermost({
|
||||
:version_number => version_number,
|
||||
:build_number => build_number,
|
||||
:pretext => pretext,
|
||||
:title => '',
|
||||
:thumb_url => 'https://lh3.ggpht.com/XL0CrI8skkxnboGct-duyg-bZ_MxJDTrjczyjdU8OP2PM1dmj7SP4jL1K8JQeMIB3AM=w300',
|
||||
:msg => msg,
|
||||
:default_payloads => [],
|
||||
:success => true,
|
||||
})
|
||||
submit_to_google_play(apk_path)
|
||||
end
|
||||
|
||||
# Submit to TestFlight if required
|
||||
if !ipa_path.nil? && ENV['SUBMIT_IOS_TO_TESTFLIGHT'] == 'true'
|
||||
UI.success("ipa file #{ipa_path}")
|
||||
|
||||
pilot
|
||||
|
||||
version_number = get_version_number(xcodeproj: './ios/Mattermost.xcodeproj', target: 'Mattermost')
|
||||
build_number = get_build_number(xcodeproj: './ios/Mattermost.xcodeproj')
|
||||
|
||||
s3_folder = "#{ENV['AWS_FOLDER_NAME']}/#{version_number}/#{build_number}"
|
||||
public_link = "https://#{s3_bucket}/#{s3_folder}/#{app_name_sub}.ipa"
|
||||
|
||||
# Send a build message to Mattermost
|
||||
pretext = '#### New iOS released ready to be published'
|
||||
msg = "Release has been cut and is on TestFlight ready to be published.\nDownload link: #{public_link}"
|
||||
|
||||
if ENV['BETA_BUILD'] == 'true'
|
||||
pretext = '#### New iOS beta published to TestFlight'
|
||||
msg = "Sign up as a beta tester [here](https://testflight.apple.com/join/Q7Rx7K9P).\nDownload link: #{public_link}"
|
||||
end
|
||||
|
||||
send_message_to_mattermost({
|
||||
:version_number => version_number,
|
||||
:build_number => build_number,
|
||||
:pretext => pretext,
|
||||
:title => '',
|
||||
:thumb_url => 'https://support.apple.com/library/content/dam/edam/applecare/images/en_US/iOS/move-to-ios-icon.png',
|
||||
:msg => msg,
|
||||
:default_payloads => [],
|
||||
:success => true,
|
||||
})
|
||||
submit_to_testflight(ipa_path)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -686,92 +837,3 @@ def qa_build_message(options)
|
|||
UI.success("PR Built for #{os_type}: #{install_url}")
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Upload file to s3'
|
||||
lane :upload_file_to_s3 do |options|
|
||||
os_type = options[:os_type]
|
||||
file = options[:file]
|
||||
file_plist = ""
|
||||
|
||||
if file.nil? || file.empty?
|
||||
app_name = ENV['APP_NAME'] || 'Mattermost Beta'
|
||||
filename = app_name.gsub(" ", "_")
|
||||
|
||||
if os_type == 'Android'
|
||||
file = "#{filename}.apk"
|
||||
elsif os_type == 'iOS'
|
||||
file = "#{filename}.ipa"
|
||||
file_plist = "#{filename}.plist"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
build_folder_path = Dir[File.expand_path('..')].first
|
||||
file_path = "#{build_folder_path}/#{file}"
|
||||
|
||||
unless ENV['AWS_BUCKET_NAME'].nil? || ENV['AWS_BUCKET_NAME'].empty? || ENV['AWS_REGION'].nil? || ENV['AWS_REGION'].empty? || file_path.nil?
|
||||
s3_region = ENV['AWS_REGION']
|
||||
s3_bucket = ENV['AWS_BUCKET_NAME']
|
||||
s3_folder = ''
|
||||
|
||||
version_number = ''
|
||||
build_number = ''
|
||||
|
||||
if is_build_pr
|
||||
s3_folder = "#{ENV['AWS_FOLDER_NAME']}/#{ENV['BRANCH_TO_BUILD']}"
|
||||
else
|
||||
if os_type == 'Android'
|
||||
version_number = android_get_version_name(gradle_file: './android/app/build.gradle')
|
||||
build_number = android_get_version_code(gradle_file: './android/app/build.gradle')
|
||||
elsif os_type == 'iOS'
|
||||
version_number = get_version_number(xcodeproj: './ios/Mattermost.xcodeproj', target: 'Mattermost')
|
||||
build_number = get_build_number(xcodeproj: './ios/Mattermost.xcodeproj')
|
||||
end
|
||||
|
||||
s3_folder = "#{ENV['AWS_FOLDER_NAME']}/#{version_number}/#{build_number}"
|
||||
end
|
||||
|
||||
s3 = Aws::S3::Resource.new(region: s3_region)
|
||||
file_obj = s3.bucket(s3_bucket).object("#{s3_folder}/#{file}")
|
||||
file_obj.upload_file("#{file_path}")
|
||||
|
||||
if is_build_pr
|
||||
if os_type == 'Android'
|
||||
install_url = "https://#{s3_bucket}/#{s3_folder}/#{file}"
|
||||
elsif os_type == 'iOS'
|
||||
current_build_number = get_build_number(xcodeproj: './ios/Mattermost.xcodeproj')
|
||||
plist_template = File.read('plist.erb')
|
||||
plist_body = ERB.new(plist_template).result(binding)
|
||||
|
||||
plist_obj = s3.bucket(s3_bucket).object("#{s3_folder}/#{file_plist}")
|
||||
plist_obj.put(body: plist_body)
|
||||
|
||||
install_url = "itms-services://?action=download-manifest&url=https://#{s3_bucket}/#{s3_folder}/#{file_plist}"
|
||||
end
|
||||
|
||||
qa_build_message({
|
||||
:os_type => os_type,
|
||||
:install_url => install_url
|
||||
})
|
||||
end
|
||||
|
||||
public_link = "https://#{s3_bucket}/#{s3_folder}/#{file}"
|
||||
if file == 'Mattermost-simulator-x86_64.app.zip'
|
||||
pretext = '#### New iOS build for VM/Simulator'
|
||||
msg = "Download link: #{public_link}"
|
||||
send_message_to_mattermost({
|
||||
:version_number => version_number,
|
||||
:build_number => build_number,
|
||||
:pretext => pretext,
|
||||
:title => '',
|
||||
:thumb_url => 'https://support.apple.com/library/content/dam/edam/applecare/images/en_US/iOS/move-to-ios-icon.png',
|
||||
:msg => msg,
|
||||
:default_payloads => [],
|
||||
:success => true,
|
||||
})
|
||||
end
|
||||
|
||||
UI.success("S3 bucket @#{s3_bucket}, object @#{s3_folder}/#{file}")
|
||||
UI.success("S3 public path: #{public_link}")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeClient.h
generated
Symbolic link
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeClient.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeClient.h
|
||||
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeDashManifestXML.h
generated
Symbolic link
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeDashManifestXML.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeDashManifestXML.h
|
||||
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeError.h
generated
Symbolic link
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeError.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeError.h
|
||||
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeKit.h
generated
Symbolic link
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeKit.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeKit.h
|
||||
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeLogger+Private.h
generated
Symbolic link
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeLogger+Private.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeLogger+Private.h
|
||||
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeLogger.h
generated
Symbolic link
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeLogger.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeLogger.h
|
||||
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeOperation.h
generated
Symbolic link
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeOperation.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeOperation.h
|
||||
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubePlayerScript.h
generated
Symbolic link
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubePlayerScript.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../XCDYouTubeKit/XCDYouTubeKit/XCDYouTubePlayerScript.h
|
||||
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeVideo+Private.h
generated
Symbolic link
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeVideo+Private.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideo+Private.h
|
||||
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeVideo.h
generated
Symbolic link
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeVideo.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideo.h
|
||||
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeVideoOperation.h
generated
Symbolic link
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeVideoOperation.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideoOperation.h
|
||||
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeVideoPlayerViewController.h
generated
Symbolic link
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeVideoPlayerViewController.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideoPlayerViewController.h
|
||||
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeVideoWebpage.h
generated
Symbolic link
1
ios/Pods/Headers/Private/XCDYouTubeKit/XCDYouTubeVideoWebpage.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideoWebpage.h
|
||||
1
ios/Pods/Headers/Private/YoutubePlayer-in-WKWebView/WKYTPlayerView.h
generated
Symbolic link
1
ios/Pods/Headers/Private/YoutubePlayer-in-WKWebView/WKYTPlayerView.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YoutubePlayer-in-WKWebView/WKYTPlayerView/WKYTPlayerView.h
|
||||
1
ios/Pods/Headers/Public/XCDYouTubeKit/XCDYouTubeClient.h
generated
Symbolic link
1
ios/Pods/Headers/Public/XCDYouTubeKit/XCDYouTubeClient.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeClient.h
|
||||
1
ios/Pods/Headers/Public/XCDYouTubeKit/XCDYouTubeError.h
generated
Symbolic link
1
ios/Pods/Headers/Public/XCDYouTubeKit/XCDYouTubeError.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeError.h
|
||||
1
ios/Pods/Headers/Public/XCDYouTubeKit/XCDYouTubeKit.h
generated
Symbolic link
1
ios/Pods/Headers/Public/XCDYouTubeKit/XCDYouTubeKit.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeKit.h
|
||||
1
ios/Pods/Headers/Public/XCDYouTubeKit/XCDYouTubeLogger.h
generated
Symbolic link
1
ios/Pods/Headers/Public/XCDYouTubeKit/XCDYouTubeLogger.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeLogger.h
|
||||
1
ios/Pods/Headers/Public/XCDYouTubeKit/XCDYouTubeOperation.h
generated
Symbolic link
1
ios/Pods/Headers/Public/XCDYouTubeKit/XCDYouTubeOperation.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeOperation.h
|
||||
1
ios/Pods/Headers/Public/XCDYouTubeKit/XCDYouTubeVideo.h
generated
Symbolic link
1
ios/Pods/Headers/Public/XCDYouTubeKit/XCDYouTubeVideo.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideo.h
|
||||
1
ios/Pods/Headers/Public/XCDYouTubeKit/XCDYouTubeVideoOperation.h
generated
Symbolic link
1
ios/Pods/Headers/Public/XCDYouTubeKit/XCDYouTubeVideoOperation.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideoOperation.h
|
||||
1
ios/Pods/Headers/Public/XCDYouTubeKit/XCDYouTubeVideoPlayerViewController.h
generated
Symbolic link
1
ios/Pods/Headers/Public/XCDYouTubeKit/XCDYouTubeVideoPlayerViewController.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideoPlayerViewController.h
|
||||
1
ios/Pods/Headers/Public/YoutubePlayer-in-WKWebView/WKYTPlayerView.h
generated
Symbolic link
1
ios/Pods/Headers/Public/YoutubePlayer-in-WKWebView/WKYTPlayerView.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YoutubePlayer-in-WKWebView/WKYTPlayerView/WKYTPlayerView.h
|
||||
20
ios/Pods/Manifest.lock
generated
Normal file
20
ios/Pods/Manifest.lock
generated
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
PODS:
|
||||
- XCDYouTubeKit (2.7.1)
|
||||
- YoutubePlayer-in-WKWebView (0.3.3)
|
||||
|
||||
DEPENDENCIES:
|
||||
- XCDYouTubeKit (= 2.7.1)
|
||||
- YoutubePlayer-in-WKWebView (~> 0.3.1)
|
||||
|
||||
SPEC REPOS:
|
||||
https://github.com/cocoapods/specs.git:
|
||||
- XCDYouTubeKit
|
||||
- YoutubePlayer-in-WKWebView
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
XCDYouTubeKit: c8567fd5cb388a3099fa26eee4b30df2a467847d
|
||||
YoutubePlayer-in-WKWebView: 7694e858c5c3472ed067d6fe34eb9b944845e63c
|
||||
|
||||
PODFILE CHECKSUM: e565d3af8eabb0e489b73c79433e140e30f8fa9c
|
||||
|
||||
COCOAPODS: 1.5.3
|
||||
893
ios/Pods/Pods.xcodeproj/project.pbxproj
generated
Normal file
893
ios/Pods/Pods.xcodeproj/project.pbxproj
generated
Normal file
|
|
@ -0,0 +1,893 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
00EF717F2CE5C08CE046FAB25A49C579 /* Pods-MattermostTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C0A3E27A51ED227A8460BDBC0B1A5BDC /* Pods-MattermostTests-dummy.m */; };
|
||||
19A3D8279379A5ACBE7F699CB120E20C /* XCDYouTubeOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = A16570331366E84C38260E575C1ACDAF /* XCDYouTubeOperation.h */; settings = {ATTRIBUTES = (Project, ); }; };
|
||||
1B069680B86677A2EA0846201573A2C9 /* XCDYouTubeClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 218BAF448A4CEBF30D9938922CA236C2 /* XCDYouTubeClient.h */; settings = {ATTRIBUTES = (Project, ); }; };
|
||||
1C5F63B626D206B0ED32320876A3EA60 /* XCDYouTubeVideo.h in Headers */ = {isa = PBXBuildFile; fileRef = BB52596A2D243BBDCE8BCB3CF50A6E20 /* XCDYouTubeVideo.h */; settings = {ATTRIBUTES = (Project, ); }; };
|
||||
2F6113A993C9CA73926D2946728A7D37 /* XCDYouTubeVideoPlayerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DD5E806A91AFE8DD2B077AE695123547 /* XCDYouTubeVideoPlayerViewController.m */; };
|
||||
32BC55AFE9DADF2BE266AB44A9F9C382 /* XCDYouTubeDashManifestXML.m in Sources */ = {isa = PBXBuildFile; fileRef = 7A014D164D90DF54F9BD4AC60868D11D /* XCDYouTubeDashManifestXML.m */; };
|
||||
3933FE5CEDAAFF0AE1DE7413EDA8CA38 /* XCDYouTubeDashManifestXML.h in Headers */ = {isa = PBXBuildFile; fileRef = 18BED515670B4F1D15806832C57D59F9 /* XCDYouTubeDashManifestXML.h */; settings = {ATTRIBUTES = (Project, ); }; };
|
||||
3F0B35BE6C13ADDF8364D0E9F7A07522 /* XCDYouTubeKit-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = CFFE5759AD00493BC5172561B1C1C7CD /* XCDYouTubeKit-dummy.m */; };
|
||||
4C91B4A27AFBF35591DD3CDF23E2DC17 /* XCDYouTubeError.h in Headers */ = {isa = PBXBuildFile; fileRef = 162E428722ECD765CEE83EB3D33C71E2 /* XCDYouTubeError.h */; settings = {ATTRIBUTES = (Project, ); }; };
|
||||
5B8AEF4A577D21542D6F8DE2B248C8E7 /* XCDYouTubeVideoWebpage.m in Sources */ = {isa = PBXBuildFile; fileRef = 920F9C3CEECF4C1924F458E3D0428ED8 /* XCDYouTubeVideoWebpage.m */; };
|
||||
5BE4F6E90A8A1644C0BBB4635AD0D84F /* WKYTPlayerView.h in Headers */ = {isa = PBXBuildFile; fileRef = 19281C3EF03E987F37C203D17BCA2EC5 /* WKYTPlayerView.h */; settings = {ATTRIBUTES = (Project, ); }; };
|
||||
5ED62229AE2031D59F1DF033F77D03B2 /* XCDYouTubeVideoOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = BA781F6AB0F7487AD05BC63EA40AB8BF /* XCDYouTubeVideoOperation.m */; };
|
||||
607B50452E483ACCA8FA33B3C0114BFD /* XCDYouTubeVideoOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 281750171C47F186466B86E65956736D /* XCDYouTubeVideoOperation.h */; settings = {ATTRIBUTES = (Project, ); }; };
|
||||
6A881BEE202BC2AC64ACE1C2E7583756 /* XCDYouTubeVideo+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CBB4B14F0B800EC1527A5353A3AE1CA /* XCDYouTubeVideo+Private.h */; settings = {ATTRIBUTES = (Project, ); }; };
|
||||
7621E888B2755702A10B6724E4107332 /* XCDYouTubePlayerScript.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E94B5BEED415E94C72301A86E7A9859 /* XCDYouTubePlayerScript.m */; };
|
||||
76BE93DCF558BFA281930A26018F9330 /* XCDYouTubeLogger+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 3DAF995C826738DB2D85603716D91154 /* XCDYouTubeLogger+Private.h */; settings = {ATTRIBUTES = (Project, ); }; };
|
||||
77F5E0033E60972EC230A8ABD78071A3 /* XCDYouTubeVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = EFFFFBEC2A07FFA8841667B371ED34E0 /* XCDYouTubeVideo.m */; };
|
||||
80627FF4ECD0A58F8A6C2874FA612EB1 /* YoutubePlayer-in-WKWebView-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 72206B26A17824A476D334C5612D4142 /* YoutubePlayer-in-WKWebView-dummy.m */; };
|
||||
8433D3049BEEF12D212D6B1DD6DD0512 /* XCDYouTubeClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 46714161B2C62428DB972729952DC352 /* XCDYouTubeClient.m */; };
|
||||
90A4DC7BA3E2C3C54D484B8959CFB708 /* XCDYouTubePlayerScript.h in Headers */ = {isa = PBXBuildFile; fileRef = F1766C4F2FDC063F421CA2D4688FED68 /* XCDYouTubePlayerScript.h */; settings = {ATTRIBUTES = (Project, ); }; };
|
||||
9EFEB7A7C37759A0328EB1B198E2C37D /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15D48C716A411AD7621E7125E083F54A /* MediaPlayer.framework */; };
|
||||
A53E28B0072944DEE03E0D2DA20C0FA0 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 98C181471820795EDEAACBC10B84709A /* JavaScriptCore.framework */; };
|
||||
C50CA7A8B2F6691C7E29BD7BC2733975 /* XCDYouTubeLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F752B1C4CE355EE8A9DA89A25D0AE73 /* XCDYouTubeLogger.m */; };
|
||||
CA1EF66BB4AA70EFF1869D1FE0A373AE /* Pods-Mattermost-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 926D56CC36F536DEFF1A45331E070750 /* Pods-Mattermost-dummy.m */; };
|
||||
D56363E3D25AE7C3C37948A2ED267EFC /* WKYTPlayerView.m in Sources */ = {isa = PBXBuildFile; fileRef = A081D43F9928F93E8E7FCA268B6660DA /* WKYTPlayerView.m */; };
|
||||
E74005FCD11C34B3705DE02F89D4028B /* XCDYouTubeKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 724042289C9DC57B313DD893EFD1AA54 /* XCDYouTubeKit.h */; settings = {ATTRIBUTES = (Project, ); }; };
|
||||
EA6A2186A0767AD5C4A45579994658BD /* XCDYouTubeVideoPlayerViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 294543F53C1E8CC7BECE8214C09765EE /* XCDYouTubeVideoPlayerViewController.h */; settings = {ATTRIBUTES = (Project, ); }; };
|
||||
F99FDC5AFF20BC2A65AEE5A41209A42C /* XCDYouTubeVideoWebpage.h in Headers */ = {isa = PBXBuildFile; fileRef = 8540AD01026C33CA77834BD0EE077CDB /* XCDYouTubeVideoWebpage.h */; settings = {ATTRIBUTES = (Project, ); }; };
|
||||
FB83D8680F87F8315167D84D2BEEDF6C /* XCDYouTubeLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 510EF6F5EB43790577352F6C8A0718B0 /* XCDYouTubeLogger.h */; settings = {ATTRIBUTES = (Project, ); }; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
165E90C48BE6DE526DE6EFE88F787BE2 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 191A114290607BBCF32141FA83AB9F6E;
|
||||
remoteInfo = "Pods-Mattermost";
|
||||
};
|
||||
A2AEF4FA0A01D420BBD3AC4B1428E3FD /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 5552A5DF4126A9D12B869B8272B40FF1;
|
||||
remoteInfo = XCDYouTubeKit;
|
||||
};
|
||||
DB4FDEE7D3C70BEC4323EBE859F93B11 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = D5F98C908412D8333DECA6E74A2FC15E;
|
||||
remoteInfo = "YoutubePlayer-in-WKWebView";
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
0800A13BE9EB3366E47E9A990DDEF5A4 /* Pods-MattermostTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-MattermostTests-acknowledgements.plist"; sourceTree = "<group>"; };
|
||||
0AD2A25648B085555683131216BAD797 /* Pods-Mattermost-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Mattermost-acknowledgements.markdown"; sourceTree = "<group>"; };
|
||||
0CA88A7462704DBCB53C017185C1A65F /* Pods-Mattermost-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Mattermost-acknowledgements.plist"; sourceTree = "<group>"; };
|
||||
15D48C716A411AD7621E7125E083F54A /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/MediaPlayer.framework; sourceTree = DEVELOPER_DIR; };
|
||||
162E428722ECD765CEE83EB3D33C71E2 /* XCDYouTubeError.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = XCDYouTubeError.h; path = XCDYouTubeKit/XCDYouTubeError.h; sourceTree = "<group>"; };
|
||||
18BED515670B4F1D15806832C57D59F9 /* XCDYouTubeDashManifestXML.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = XCDYouTubeDashManifestXML.h; path = XCDYouTubeKit/XCDYouTubeDashManifestXML.h; sourceTree = "<group>"; };
|
||||
19281C3EF03E987F37C203D17BCA2EC5 /* WKYTPlayerView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = WKYTPlayerView.h; path = WKYTPlayerView/WKYTPlayerView.h; sourceTree = "<group>"; };
|
||||
1CBB4B14F0B800EC1527A5353A3AE1CA /* XCDYouTubeVideo+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "XCDYouTubeVideo+Private.h"; path = "XCDYouTubeKit/XCDYouTubeVideo+Private.h"; sourceTree = "<group>"; };
|
||||
218BAF448A4CEBF30D9938922CA236C2 /* XCDYouTubeClient.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = XCDYouTubeClient.h; path = XCDYouTubeKit/XCDYouTubeClient.h; sourceTree = "<group>"; };
|
||||
24390EFD555DD124430DFF9724065945 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
|
||||
281750171C47F186466B86E65956736D /* XCDYouTubeVideoOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = XCDYouTubeVideoOperation.h; path = XCDYouTubeKit/XCDYouTubeVideoOperation.h; sourceTree = "<group>"; };
|
||||
294543F53C1E8CC7BECE8214C09765EE /* XCDYouTubeVideoPlayerViewController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = XCDYouTubeVideoPlayerViewController.h; path = XCDYouTubeKit/XCDYouTubeVideoPlayerViewController.h; sourceTree = "<group>"; };
|
||||
377B2C391CA94B7612EDC96C2306DB48 /* Pods-MattermostTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-MattermostTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
3BC2AF7C034FA52EAB440AC387B0F3E9 /* XCDYouTubeKit.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = XCDYouTubeKit.xcconfig; sourceTree = "<group>"; };
|
||||
3DAF995C826738DB2D85603716D91154 /* XCDYouTubeLogger+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "XCDYouTubeLogger+Private.h"; path = "XCDYouTubeKit/XCDYouTubeLogger+Private.h"; sourceTree = "<group>"; };
|
||||
46714161B2C62428DB972729952DC352 /* XCDYouTubeClient.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = XCDYouTubeClient.m; path = XCDYouTubeKit/XCDYouTubeClient.m; sourceTree = "<group>"; };
|
||||
510EF6F5EB43790577352F6C8A0718B0 /* XCDYouTubeLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = XCDYouTubeLogger.h; path = XCDYouTubeKit/XCDYouTubeLogger.h; sourceTree = "<group>"; };
|
||||
60FB83EAEF578DD0C2DE316FCF4322A9 /* Pods-MattermostTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-MattermostTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
6170F2E79BA4DE1619C6FD1F25C3901F /* Pods-Mattermost-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Mattermost-frameworks.sh"; sourceTree = "<group>"; };
|
||||
6CD50F1ED20084866B7CE47B8F8E4BE4 /* libYoutubePlayer-in-WKWebView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libYoutubePlayer-in-WKWebView.a"; path = "libYoutubePlayer-in-WKWebView.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
6F752B1C4CE355EE8A9DA89A25D0AE73 /* XCDYouTubeLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = XCDYouTubeLogger.m; path = XCDYouTubeKit/XCDYouTubeLogger.m; sourceTree = "<group>"; };
|
||||
72206B26A17824A476D334C5612D4142 /* YoutubePlayer-in-WKWebView-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "YoutubePlayer-in-WKWebView-dummy.m"; sourceTree = "<group>"; };
|
||||
724042289C9DC57B313DD893EFD1AA54 /* XCDYouTubeKit.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = XCDYouTubeKit.h; path = XCDYouTubeKit/XCDYouTubeKit.h; sourceTree = "<group>"; };
|
||||
7703139D81F98B8B6130B2DAFB831C41 /* libPods-Mattermost.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libPods-Mattermost.a"; path = "libPods-Mattermost.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
7A014D164D90DF54F9BD4AC60868D11D /* XCDYouTubeDashManifestXML.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = XCDYouTubeDashManifestXML.m; path = XCDYouTubeKit/XCDYouTubeDashManifestXML.m; sourceTree = "<group>"; };
|
||||
8540AD01026C33CA77834BD0EE077CDB /* XCDYouTubeVideoWebpage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = XCDYouTubeVideoWebpage.h; path = XCDYouTubeKit/XCDYouTubeVideoWebpage.h; sourceTree = "<group>"; };
|
||||
8A89EF129E834187D884270CF5CAF3C5 /* Pods-Mattermost-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Mattermost-resources.sh"; sourceTree = "<group>"; };
|
||||
8E94B5BEED415E94C72301A86E7A9859 /* XCDYouTubePlayerScript.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = XCDYouTubePlayerScript.m; path = XCDYouTubeKit/XCDYouTubePlayerScript.m; sourceTree = "<group>"; };
|
||||
920F9C3CEECF4C1924F458E3D0428ED8 /* XCDYouTubeVideoWebpage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = XCDYouTubeVideoWebpage.m; path = XCDYouTubeKit/XCDYouTubeVideoWebpage.m; sourceTree = "<group>"; };
|
||||
926D56CC36F536DEFF1A45331E070750 /* Pods-Mattermost-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Mattermost-dummy.m"; sourceTree = "<group>"; };
|
||||
934A4B9575F4CBDCBE7B044C1F049365 /* Pods-Mattermost.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Mattermost.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
974866440990F0A14694BD9B2E9962E0 /* Pods-MattermostTests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-MattermostTests-acknowledgements.markdown"; sourceTree = "<group>"; };
|
||||
98C181471820795EDEAACBC10B84709A /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; };
|
||||
A081D43F9928F93E8E7FCA268B6660DA /* WKYTPlayerView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = WKYTPlayerView.m; path = WKYTPlayerView/WKYTPlayerView.m; sourceTree = "<group>"; };
|
||||
A16570331366E84C38260E575C1ACDAF /* XCDYouTubeOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = XCDYouTubeOperation.h; path = XCDYouTubeKit/XCDYouTubeOperation.h; sourceTree = "<group>"; };
|
||||
A43B4ECF27212BC0465EDA19AE3164CC /* XCDYouTubeKit-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "XCDYouTubeKit-prefix.pch"; sourceTree = "<group>"; };
|
||||
B564ED8191C54D3CAD8D2A2A6B9B9D1B /* Pods-Mattermost.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Mattermost.release.xcconfig"; sourceTree = "<group>"; };
|
||||
BA781F6AB0F7487AD05BC63EA40AB8BF /* XCDYouTubeVideoOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = XCDYouTubeVideoOperation.m; path = XCDYouTubeKit/XCDYouTubeVideoOperation.m; sourceTree = "<group>"; };
|
||||
BB52596A2D243BBDCE8BCB3CF50A6E20 /* XCDYouTubeVideo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = XCDYouTubeVideo.h; path = XCDYouTubeKit/XCDYouTubeVideo.h; sourceTree = "<group>"; };
|
||||
C0A3E27A51ED227A8460BDBC0B1A5BDC /* Pods-MattermostTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-MattermostTests-dummy.m"; sourceTree = "<group>"; };
|
||||
C70E5870375DC970207B78465E560E64 /* YoutubePlayer-in-WKWebView-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "YoutubePlayer-in-WKWebView-prefix.pch"; sourceTree = "<group>"; };
|
||||
C99CF8DC55235B8BA857A47235948EE7 /* libXCDYouTubeKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libXCDYouTubeKit.a; path = libXCDYouTubeKit.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
CA6DA7F1941EC2569E22ACF8A89FA03B /* Pods-MattermostTests-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-MattermostTests-resources.sh"; sourceTree = "<group>"; };
|
||||
CFFE5759AD00493BC5172561B1C1C7CD /* XCDYouTubeKit-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "XCDYouTubeKit-dummy.m"; sourceTree = "<group>"; };
|
||||
DD5E806A91AFE8DD2B077AE695123547 /* XCDYouTubeVideoPlayerViewController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = XCDYouTubeVideoPlayerViewController.m; path = XCDYouTubeKit/XCDYouTubeVideoPlayerViewController.m; sourceTree = "<group>"; };
|
||||
E0545ADDF3E1FF7C1BC19F497787C42B /* WKYTPlayerView.bundle */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "wrapper.plug-in"; name = WKYTPlayerView.bundle; path = WKYTPlayerView/WKYTPlayerView.bundle; sourceTree = "<group>"; };
|
||||
E4748ACD84B23087E6F590E0904FFEFB /* YoutubePlayer-in-WKWebView.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "YoutubePlayer-in-WKWebView.xcconfig"; sourceTree = "<group>"; };
|
||||
E99B330F0F9A45FF2E1ACB80DA268841 /* libPods-MattermostTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libPods-MattermostTests.a"; path = "libPods-MattermostTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
EFFFFBEC2A07FFA8841667B371ED34E0 /* XCDYouTubeVideo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = XCDYouTubeVideo.m; path = XCDYouTubeKit/XCDYouTubeVideo.m; sourceTree = "<group>"; };
|
||||
F1766C4F2FDC063F421CA2D4688FED68 /* XCDYouTubePlayerScript.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = XCDYouTubePlayerScript.h; path = XCDYouTubeKit/XCDYouTubePlayerScript.h; sourceTree = "<group>"; };
|
||||
FFD8DC263483FE0689017EF3573C5C71 /* Pods-MattermostTests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-MattermostTests-frameworks.sh"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
3BF9126BA0554EB8C75B0C9B1F5908D5 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9607CC185A314A5FB24F3B67E3C0B743 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A53E28B0072944DEE03E0D2DA20C0FA0 /* JavaScriptCore.framework in Frameworks */,
|
||||
9EFEB7A7C37759A0328EB1B198E2C37D /* MediaPlayer.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
E909807276D8D8C1F62A49D70C2048F0 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
EBE0F2650665138130247C39F808CDFB /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
1628BF05B4CAFDCC3549A101F5A10A17 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B01816E2D09E8070AEE9E96136D917B6 /* iOS */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3EAAB2CFFBD8598AB3144F85D9EDACD8 /* Pods-Mattermost */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0AD2A25648B085555683131216BAD797 /* Pods-Mattermost-acknowledgements.markdown */,
|
||||
0CA88A7462704DBCB53C017185C1A65F /* Pods-Mattermost-acknowledgements.plist */,
|
||||
926D56CC36F536DEFF1A45331E070750 /* Pods-Mattermost-dummy.m */,
|
||||
6170F2E79BA4DE1619C6FD1F25C3901F /* Pods-Mattermost-frameworks.sh */,
|
||||
8A89EF129E834187D884270CF5CAF3C5 /* Pods-Mattermost-resources.sh */,
|
||||
934A4B9575F4CBDCBE7B044C1F049365 /* Pods-Mattermost.debug.xcconfig */,
|
||||
B564ED8191C54D3CAD8D2A2A6B9B9D1B /* Pods-Mattermost.release.xcconfig */,
|
||||
);
|
||||
name = "Pods-Mattermost";
|
||||
path = "Target Support Files/Pods-Mattermost";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
428BC12C5AD7D04CCD5564A473A61275 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
950725B3833769C44391B7E733E759D0 /* XCDYouTubeKit */,
|
||||
6571058FEA94E8172ABEAFD4A1D3C1A7 /* YoutubePlayer-in-WKWebView */,
|
||||
);
|
||||
name = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6571058FEA94E8172ABEAFD4A1D3C1A7 /* YoutubePlayer-in-WKWebView */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
19281C3EF03E987F37C203D17BCA2EC5 /* WKYTPlayerView.h */,
|
||||
A081D43F9928F93E8E7FCA268B6660DA /* WKYTPlayerView.m */,
|
||||
92B16AFE4649769630669C6CDA9910C9 /* Resources */,
|
||||
C609F4F9C6363362CDC6B91DC2BB8DA7 /* Support Files */,
|
||||
);
|
||||
name = "YoutubePlayer-in-WKWebView";
|
||||
path = "YoutubePlayer-in-WKWebView";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6CDFB0049112FA789537AC9B9E94FC6E /* Pods-MattermostTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
974866440990F0A14694BD9B2E9962E0 /* Pods-MattermostTests-acknowledgements.markdown */,
|
||||
0800A13BE9EB3366E47E9A990DDEF5A4 /* Pods-MattermostTests-acknowledgements.plist */,
|
||||
C0A3E27A51ED227A8460BDBC0B1A5BDC /* Pods-MattermostTests-dummy.m */,
|
||||
FFD8DC263483FE0689017EF3573C5C71 /* Pods-MattermostTests-frameworks.sh */,
|
||||
CA6DA7F1941EC2569E22ACF8A89FA03B /* Pods-MattermostTests-resources.sh */,
|
||||
60FB83EAEF578DD0C2DE316FCF4322A9 /* Pods-MattermostTests.debug.xcconfig */,
|
||||
377B2C391CA94B7612EDC96C2306DB48 /* Pods-MattermostTests.release.xcconfig */,
|
||||
);
|
||||
name = "Pods-MattermostTests";
|
||||
path = "Target Support Files/Pods-MattermostTests";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7D3B7C9338829DEF8BC3A52614FF35D6 /* Targets Support Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3EAAB2CFFBD8598AB3144F85D9EDACD8 /* Pods-Mattermost */,
|
||||
6CDFB0049112FA789537AC9B9E94FC6E /* Pods-MattermostTests */,
|
||||
);
|
||||
name = "Targets Support Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
92B16AFE4649769630669C6CDA9910C9 /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E0545ADDF3E1FF7C1BC19F497787C42B /* WKYTPlayerView.bundle */,
|
||||
);
|
||||
name = Resources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
950725B3833769C44391B7E733E759D0 /* XCDYouTubeKit */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
218BAF448A4CEBF30D9938922CA236C2 /* XCDYouTubeClient.h */,
|
||||
46714161B2C62428DB972729952DC352 /* XCDYouTubeClient.m */,
|
||||
18BED515670B4F1D15806832C57D59F9 /* XCDYouTubeDashManifestXML.h */,
|
||||
7A014D164D90DF54F9BD4AC60868D11D /* XCDYouTubeDashManifestXML.m */,
|
||||
162E428722ECD765CEE83EB3D33C71E2 /* XCDYouTubeError.h */,
|
||||
724042289C9DC57B313DD893EFD1AA54 /* XCDYouTubeKit.h */,
|
||||
510EF6F5EB43790577352F6C8A0718B0 /* XCDYouTubeLogger.h */,
|
||||
6F752B1C4CE355EE8A9DA89A25D0AE73 /* XCDYouTubeLogger.m */,
|
||||
3DAF995C826738DB2D85603716D91154 /* XCDYouTubeLogger+Private.h */,
|
||||
A16570331366E84C38260E575C1ACDAF /* XCDYouTubeOperation.h */,
|
||||
F1766C4F2FDC063F421CA2D4688FED68 /* XCDYouTubePlayerScript.h */,
|
||||
8E94B5BEED415E94C72301A86E7A9859 /* XCDYouTubePlayerScript.m */,
|
||||
BB52596A2D243BBDCE8BCB3CF50A6E20 /* XCDYouTubeVideo.h */,
|
||||
EFFFFBEC2A07FFA8841667B371ED34E0 /* XCDYouTubeVideo.m */,
|
||||
1CBB4B14F0B800EC1527A5353A3AE1CA /* XCDYouTubeVideo+Private.h */,
|
||||
281750171C47F186466B86E65956736D /* XCDYouTubeVideoOperation.h */,
|
||||
BA781F6AB0F7487AD05BC63EA40AB8BF /* XCDYouTubeVideoOperation.m */,
|
||||
294543F53C1E8CC7BECE8214C09765EE /* XCDYouTubeVideoPlayerViewController.h */,
|
||||
DD5E806A91AFE8DD2B077AE695123547 /* XCDYouTubeVideoPlayerViewController.m */,
|
||||
8540AD01026C33CA77834BD0EE077CDB /* XCDYouTubeVideoWebpage.h */,
|
||||
920F9C3CEECF4C1924F458E3D0428ED8 /* XCDYouTubeVideoWebpage.m */,
|
||||
E6B7DAED273DD709FF4449921C0817D9 /* Support Files */,
|
||||
);
|
||||
name = XCDYouTubeKit;
|
||||
path = XCDYouTubeKit;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A3D27D0A8AF193B0B5A20E3F139F18EE /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7703139D81F98B8B6130B2DAFB831C41 /* libPods-Mattermost.a */,
|
||||
E99B330F0F9A45FF2E1ACB80DA268841 /* libPods-MattermostTests.a */,
|
||||
C99CF8DC55235B8BA857A47235948EE7 /* libXCDYouTubeKit.a */,
|
||||
6CD50F1ED20084866B7CE47B8F8E4BE4 /* libYoutubePlayer-in-WKWebView.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B01816E2D09E8070AEE9E96136D917B6 /* iOS */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
98C181471820795EDEAACBC10B84709A /* JavaScriptCore.framework */,
|
||||
15D48C716A411AD7621E7125E083F54A /* MediaPlayer.framework */,
|
||||
);
|
||||
name = iOS;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C609F4F9C6363362CDC6B91DC2BB8DA7 /* Support Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E4748ACD84B23087E6F590E0904FFEFB /* YoutubePlayer-in-WKWebView.xcconfig */,
|
||||
72206B26A17824A476D334C5612D4142 /* YoutubePlayer-in-WKWebView-dummy.m */,
|
||||
C70E5870375DC970207B78465E560E64 /* YoutubePlayer-in-WKWebView-prefix.pch */,
|
||||
);
|
||||
name = "Support Files";
|
||||
path = "../Target Support Files/YoutubePlayer-in-WKWebView";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CF1408CF629C7361332E53B88F7BD30C = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
24390EFD555DD124430DFF9724065945 /* Podfile */,
|
||||
1628BF05B4CAFDCC3549A101F5A10A17 /* Frameworks */,
|
||||
428BC12C5AD7D04CCD5564A473A61275 /* Pods */,
|
||||
A3D27D0A8AF193B0B5A20E3F139F18EE /* Products */,
|
||||
7D3B7C9338829DEF8BC3A52614FF35D6 /* Targets Support Files */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E6B7DAED273DD709FF4449921C0817D9 /* Support Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3BC2AF7C034FA52EAB440AC387B0F3E9 /* XCDYouTubeKit.xcconfig */,
|
||||
CFFE5759AD00493BC5172561B1C1C7CD /* XCDYouTubeKit-dummy.m */,
|
||||
A43B4ECF27212BC0465EDA19AE3164CC /* XCDYouTubeKit-prefix.pch */,
|
||||
);
|
||||
name = "Support Files";
|
||||
path = "../Target Support Files/XCDYouTubeKit";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
121FA629058A6D7550BAA7E46A2DFF6C /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1B069680B86677A2EA0846201573A2C9 /* XCDYouTubeClient.h in Headers */,
|
||||
3933FE5CEDAAFF0AE1DE7413EDA8CA38 /* XCDYouTubeDashManifestXML.h in Headers */,
|
||||
4C91B4A27AFBF35591DD3CDF23E2DC17 /* XCDYouTubeError.h in Headers */,
|
||||
E74005FCD11C34B3705DE02F89D4028B /* XCDYouTubeKit.h in Headers */,
|
||||
76BE93DCF558BFA281930A26018F9330 /* XCDYouTubeLogger+Private.h in Headers */,
|
||||
FB83D8680F87F8315167D84D2BEEDF6C /* XCDYouTubeLogger.h in Headers */,
|
||||
19A3D8279379A5ACBE7F699CB120E20C /* XCDYouTubeOperation.h in Headers */,
|
||||
90A4DC7BA3E2C3C54D484B8959CFB708 /* XCDYouTubePlayerScript.h in Headers */,
|
||||
6A881BEE202BC2AC64ACE1C2E7583756 /* XCDYouTubeVideo+Private.h in Headers */,
|
||||
1C5F63B626D206B0ED32320876A3EA60 /* XCDYouTubeVideo.h in Headers */,
|
||||
607B50452E483ACCA8FA33B3C0114BFD /* XCDYouTubeVideoOperation.h in Headers */,
|
||||
EA6A2186A0767AD5C4A45579994658BD /* XCDYouTubeVideoPlayerViewController.h in Headers */,
|
||||
F99FDC5AFF20BC2A65AEE5A41209A42C /* XCDYouTubeVideoWebpage.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
87BA6E865700D97E7F71638AAE9AFC0D /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
946AD953D8D82CF2E2C495E655189FD9 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
B6DE8E634D9D8E06BFF5F56A21C33E98 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
5BE4F6E90A8A1644C0BBB4635AD0D84F /* WKYTPlayerView.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
191A114290607BBCF32141FA83AB9F6E /* Pods-Mattermost */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 0A6512CB2B9DF1554E714C059EE642EE /* Build configuration list for PBXNativeTarget "Pods-Mattermost" */;
|
||||
buildPhases = (
|
||||
946AD953D8D82CF2E2C495E655189FD9 /* Headers */,
|
||||
4A0A92E8C79C534671C264B96C2D3980 /* Sources */,
|
||||
EBE0F2650665138130247C39F808CDFB /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
32D9BECA4EDB7295613C7FBBFF1947E3 /* PBXTargetDependency */,
|
||||
12B381BF70C519F8F5E118A06F0715F4 /* PBXTargetDependency */,
|
||||
);
|
||||
name = "Pods-Mattermost";
|
||||
productName = "Pods-Mattermost";
|
||||
productReference = 7703139D81F98B8B6130B2DAFB831C41 /* libPods-Mattermost.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
5552A5DF4126A9D12B869B8272B40FF1 /* XCDYouTubeKit */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = A447275384E1E65FCC685DD176B14980 /* Build configuration list for PBXNativeTarget "XCDYouTubeKit" */;
|
||||
buildPhases = (
|
||||
121FA629058A6D7550BAA7E46A2DFF6C /* Headers */,
|
||||
6E02437F69A69D78682AC11124EF1525 /* Sources */,
|
||||
9607CC185A314A5FB24F3B67E3C0B743 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = XCDYouTubeKit;
|
||||
productName = XCDYouTubeKit;
|
||||
productReference = C99CF8DC55235B8BA857A47235948EE7 /* libXCDYouTubeKit.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
D5F98C908412D8333DECA6E74A2FC15E /* YoutubePlayer-in-WKWebView */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 1F5DC73135AFED29F2A39052787E8E88 /* Build configuration list for PBXNativeTarget "YoutubePlayer-in-WKWebView" */;
|
||||
buildPhases = (
|
||||
B6DE8E634D9D8E06BFF5F56A21C33E98 /* Headers */,
|
||||
BAD0507591933394D74E430744349DCA /* Sources */,
|
||||
3BF9126BA0554EB8C75B0C9B1F5908D5 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = "YoutubePlayer-in-WKWebView";
|
||||
productName = "YoutubePlayer-in-WKWebView";
|
||||
productReference = 6CD50F1ED20084866B7CE47B8F8E4BE4 /* libYoutubePlayer-in-WKWebView.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
DE7906C32BF02EEC471C43D2EE24AA47 /* Pods-MattermostTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 42CD827C438E22B810D149D4E59AC5FC /* Build configuration list for PBXNativeTarget "Pods-MattermostTests" */;
|
||||
buildPhases = (
|
||||
87BA6E865700D97E7F71638AAE9AFC0D /* Headers */,
|
||||
7FF2A957D32E6EED1BD925761A4422B4 /* Sources */,
|
||||
E909807276D8D8C1F62A49D70C2048F0 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
2FADDBF2AD8381C1F61DFCE1A376150B /* PBXTargetDependency */,
|
||||
);
|
||||
name = "Pods-MattermostTests";
|
||||
productName = "Pods-MattermostTests";
|
||||
productReference = E99B330F0F9A45FF2E1ACB80DA268841 /* libPods-MattermostTests.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
BFDFE7DC352907FC980B868725387E98 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 1100;
|
||||
LastUpgradeCheck = 1100;
|
||||
};
|
||||
buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = CF1408CF629C7361332E53B88F7BD30C;
|
||||
productRefGroup = A3D27D0A8AF193B0B5A20E3F139F18EE /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
191A114290607BBCF32141FA83AB9F6E /* Pods-Mattermost */,
|
||||
DE7906C32BF02EEC471C43D2EE24AA47 /* Pods-MattermostTests */,
|
||||
5552A5DF4126A9D12B869B8272B40FF1 /* XCDYouTubeKit */,
|
||||
D5F98C908412D8333DECA6E74A2FC15E /* YoutubePlayer-in-WKWebView */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
4A0A92E8C79C534671C264B96C2D3980 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CA1EF66BB4AA70EFF1869D1FE0A373AE /* Pods-Mattermost-dummy.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
6E02437F69A69D78682AC11124EF1525 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8433D3049BEEF12D212D6B1DD6DD0512 /* XCDYouTubeClient.m in Sources */,
|
||||
32BC55AFE9DADF2BE266AB44A9F9C382 /* XCDYouTubeDashManifestXML.m in Sources */,
|
||||
3F0B35BE6C13ADDF8364D0E9F7A07522 /* XCDYouTubeKit-dummy.m in Sources */,
|
||||
C50CA7A8B2F6691C7E29BD7BC2733975 /* XCDYouTubeLogger.m in Sources */,
|
||||
7621E888B2755702A10B6724E4107332 /* XCDYouTubePlayerScript.m in Sources */,
|
||||
77F5E0033E60972EC230A8ABD78071A3 /* XCDYouTubeVideo.m in Sources */,
|
||||
5ED62229AE2031D59F1DF033F77D03B2 /* XCDYouTubeVideoOperation.m in Sources */,
|
||||
2F6113A993C9CA73926D2946728A7D37 /* XCDYouTubeVideoPlayerViewController.m in Sources */,
|
||||
5B8AEF4A577D21542D6F8DE2B248C8E7 /* XCDYouTubeVideoWebpage.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
7FF2A957D32E6EED1BD925761A4422B4 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
00EF717F2CE5C08CE046FAB25A49C579 /* Pods-MattermostTests-dummy.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
BAD0507591933394D74E430744349DCA /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D56363E3D25AE7C3C37948A2ED267EFC /* WKYTPlayerView.m in Sources */,
|
||||
80627FF4ECD0A58F8A6C2874FA612EB1 /* YoutubePlayer-in-WKWebView-dummy.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
12B381BF70C519F8F5E118A06F0715F4 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
name = "YoutubePlayer-in-WKWebView";
|
||||
target = D5F98C908412D8333DECA6E74A2FC15E /* YoutubePlayer-in-WKWebView */;
|
||||
targetProxy = DB4FDEE7D3C70BEC4323EBE859F93B11 /* PBXContainerItemProxy */;
|
||||
};
|
||||
2FADDBF2AD8381C1F61DFCE1A376150B /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
name = "Pods-Mattermost";
|
||||
target = 191A114290607BBCF32141FA83AB9F6E /* Pods-Mattermost */;
|
||||
targetProxy = 165E90C48BE6DE526DE6EFE88F787BE2 /* PBXContainerItemProxy */;
|
||||
};
|
||||
32D9BECA4EDB7295613C7FBBFF1947E3 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
name = XCDYouTubeKit;
|
||||
target = 5552A5DF4126A9D12B869B8272B40FF1 /* XCDYouTubeKit */;
|
||||
targetProxy = A2AEF4FA0A01D420BBD3AC4B1428E3FD /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
0430B9AA2C1C5F6D02D86CB026100EE8 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = E4748ACD84B23087E6F590E0904FFEFB /* YoutubePlayer-in-WKWebView.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
|
||||
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
|
||||
GCC_PREFIX_HEADER = "Target Support Files/YoutubePlayer-in-WKWebView/YoutubePlayer-in-WKWebView-prefix.pch";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
OTHER_LDFLAGS = "";
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
PRIVATE_HEADERS_FOLDER_PATH = "";
|
||||
PRODUCT_MODULE_NAME = YoutubePlayer_in_WKWebView;
|
||||
PRODUCT_NAME = "YoutubePlayer-in-WKWebView";
|
||||
PUBLIC_HEADERS_FOLDER_PATH = "";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
|
||||
SWIFT_VERSION = 4.2;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
161EADF999CB6B2B796E0054E074569D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 60FB83EAEF578DD0C2DE316FCF4322A9 /* Pods-MattermostTests.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
|
||||
CLANG_ENABLE_OBJC_WEAK = NO;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
|
||||
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
|
||||
MACH_O_TYPE = staticlib;
|
||||
OTHER_LDFLAGS = "";
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
PODS_ROOT = "$(SRCROOT)";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
2D52F03349CA866E882EB87084FF9D21 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGNING_ALLOWED = NO;
|
||||
CODE_SIGNING_REQUIRED = NO;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"POD_CONFIGURATION_DEBUG=1",
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
STRIP_INSTALLED_PRODUCT = NO;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
SYMROOT = "${SRCROOT}/../build";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
3536F4235A4BE9CAF9A3A90CECC64AD5 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = E4748ACD84B23087E6F590E0904FFEFB /* YoutubePlayer-in-WKWebView.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
|
||||
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
|
||||
GCC_PREFIX_HEADER = "Target Support Files/YoutubePlayer-in-WKWebView/YoutubePlayer-in-WKWebView-prefix.pch";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
OTHER_LDFLAGS = "";
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
PRIVATE_HEADERS_FOLDER_PATH = "";
|
||||
PRODUCT_MODULE_NAME = YoutubePlayer_in_WKWebView;
|
||||
PRODUCT_NAME = "YoutubePlayer-in-WKWebView";
|
||||
PUBLIC_HEADERS_FOLDER_PATH = "";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
|
||||
SWIFT_VERSION = 4.2;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
45C68B99EB6B81E0DD1319B540AF6A4D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 3BC2AF7C034FA52EAB440AC387B0F3E9 /* XCDYouTubeKit.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
|
||||
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
|
||||
GCC_PREFIX_HEADER = "Target Support Files/XCDYouTubeKit/XCDYouTubeKit-prefix.pch";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
OTHER_LDFLAGS = "";
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
PRIVATE_HEADERS_FOLDER_PATH = "";
|
||||
PRODUCT_MODULE_NAME = XCDYouTubeKit;
|
||||
PRODUCT_NAME = XCDYouTubeKit;
|
||||
PUBLIC_HEADERS_FOLDER_PATH = "";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
|
||||
SWIFT_VERSION = 4.2;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
50A87C79F1E5C7C6BFADB42D9E50A087 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 377B2C391CA94B7612EDC96C2306DB48 /* Pods-MattermostTests.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
|
||||
CLANG_ENABLE_OBJC_WEAK = NO;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
|
||||
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
|
||||
MACH_O_TYPE = staticlib;
|
||||
OTHER_LDFLAGS = "";
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
PODS_ROOT = "$(SRCROOT)";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
682764580BDEF953B0E72A847F082705 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 934A4B9575F4CBDCBE7B044C1F049365 /* Pods-Mattermost.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
|
||||
CLANG_ENABLE_OBJC_WEAK = NO;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
|
||||
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
|
||||
MACH_O_TYPE = staticlib;
|
||||
OTHER_LDFLAGS = "";
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
PODS_ROOT = "$(SRCROOT)";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
86B3C2B708242AD4B00334BBE7D14EFB /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 3BC2AF7C034FA52EAB440AC387B0F3E9 /* XCDYouTubeKit.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
|
||||
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
|
||||
GCC_PREFIX_HEADER = "Target Support Files/XCDYouTubeKit/XCDYouTubeKit-prefix.pch";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
OTHER_LDFLAGS = "";
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
PRIVATE_HEADERS_FOLDER_PATH = "";
|
||||
PRODUCT_MODULE_NAME = XCDYouTubeKit;
|
||||
PRODUCT_NAME = XCDYouTubeKit;
|
||||
PUBLIC_HEADERS_FOLDER_PATH = "";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
|
||||
SWIFT_VERSION = 4.2;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
A0A8AE5FB77A90328CE173082A521CA4 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = B564ED8191C54D3CAD8D2A2A6B9B9D1B /* Pods-Mattermost.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
|
||||
CLANG_ENABLE_OBJC_WEAK = NO;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
|
||||
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
|
||||
MACH_O_TYPE = staticlib;
|
||||
OTHER_LDFLAGS = "";
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
PODS_ROOT = "$(SRCROOT)";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
B45EE3CA30FA810239EAC87C682A2A52 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGNING_ALLOWED = NO;
|
||||
CODE_SIGNING_REQUIRED = NO;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"POD_CONFIGURATION_RELEASE=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
STRIP_INSTALLED_PRODUCT = NO;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
SWIFT_VERSION = 5.0;
|
||||
SYMROOT = "${SRCROOT}/../build";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
0A6512CB2B9DF1554E714C059EE642EE /* Build configuration list for PBXNativeTarget "Pods-Mattermost" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
682764580BDEF953B0E72A847F082705 /* Debug */,
|
||||
A0A8AE5FB77A90328CE173082A521CA4 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
1F5DC73135AFED29F2A39052787E8E88 /* Build configuration list for PBXNativeTarget "YoutubePlayer-in-WKWebView" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
3536F4235A4BE9CAF9A3A90CECC64AD5 /* Debug */,
|
||||
0430B9AA2C1C5F6D02D86CB026100EE8 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
42CD827C438E22B810D149D4E59AC5FC /* Build configuration list for PBXNativeTarget "Pods-MattermostTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
161EADF999CB6B2B796E0054E074569D /* Debug */,
|
||||
50A87C79F1E5C7C6BFADB42D9E50A087 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
2D52F03349CA866E882EB87084FF9D21 /* Debug */,
|
||||
B45EE3CA30FA810239EAC87C682A2A52 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
A447275384E1E65FCC685DD176B14980 /* Build configuration list for PBXNativeTarget "XCDYouTubeKit" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
45C68B99EB6B81E0DD1319B540AF6A4D /* Debug */,
|
||||
86B3C2B708242AD4B00334BBE7D14EFB /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */;
|
||||
}
|
||||
46
ios/Pods/Target Support Files/Pods-Mattermost/Pods-Mattermost-acknowledgements.markdown
generated
Normal file
46
ios/Pods/Target Support Files/Pods-Mattermost/Pods-Mattermost-acknowledgements.markdown
generated
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
# Acknowledgements
|
||||
This application makes use of the following third party libraries:
|
||||
|
||||
## XCDYouTubeKit
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2016 Cédric Luthi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
|
||||
## YoutubePlayer-in-WKWebView
|
||||
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Generated by CocoaPods - https://cocoapods.org
|
||||
84
ios/Pods/Target Support Files/Pods-Mattermost/Pods-Mattermost-acknowledgements.plist
generated
Normal file
84
ios/Pods/Target Support Files/Pods-Mattermost/Pods-Mattermost-acknowledgements.plist
generated
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PreferenceSpecifiers</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>This application makes use of the following third party libraries:</string>
|
||||
<key>Title</key>
|
||||
<string>Acknowledgements</string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2016 Cédric Luthi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
</string>
|
||||
<key>License</key>
|
||||
<string>MIT</string>
|
||||
<key>Title</key>
|
||||
<string>XCDYouTubeKit</string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>Copyright 2014 Google Inc. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
</string>
|
||||
<key>License</key>
|
||||
<string>Apache</string>
|
||||
<key>Title</key>
|
||||
<string>YoutubePlayer-in-WKWebView</string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>Generated by CocoaPods - https://cocoapods.org</string>
|
||||
<key>Title</key>
|
||||
<string></string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>StringsTable</key>
|
||||
<string>Acknowledgements</string>
|
||||
<key>Title</key>
|
||||
<string>Acknowledgements</string>
|
||||
</dict>
|
||||
</plist>
|
||||
5
ios/Pods/Target Support Files/Pods-Mattermost/Pods-Mattermost-dummy.m
generated
Normal file
5
ios/Pods/Target Support Files/Pods-Mattermost/Pods-Mattermost-dummy.m
generated
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
@interface PodsDummy_Pods_Mattermost : NSObject
|
||||
@end
|
||||
@implementation PodsDummy_Pods_Mattermost
|
||||
@end
|
||||
146
ios/Pods/Target Support Files/Pods-Mattermost/Pods-Mattermost-frameworks.sh
generated
Executable file
146
ios/Pods/Target Support Files/Pods-Mattermost/Pods-Mattermost-frameworks.sh
generated
Executable file
|
|
@ -0,0 +1,146 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
set -u
|
||||
set -o pipefail
|
||||
|
||||
if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
|
||||
# If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
|
||||
# frameworks to, so exit 0 (signalling the script phase was successful).
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
|
||||
COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
|
||||
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
|
||||
|
||||
# Used as a return value for each invocation of `strip_invalid_archs` function.
|
||||
STRIP_BINARY_RETVAL=0
|
||||
|
||||
# This protects against multiple targets copying the same framework dependency at the same time. The solution
|
||||
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
|
||||
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
|
||||
|
||||
# Copies and strips a vendored framework
|
||||
install_framework()
|
||||
{
|
||||
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
|
||||
local source="${BUILT_PRODUCTS_DIR}/$1"
|
||||
elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
|
||||
local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
|
||||
elif [ -r "$1" ]; then
|
||||
local source="$1"
|
||||
fi
|
||||
|
||||
local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
|
||||
if [ -L "${source}" ]; then
|
||||
echo "Symlinked..."
|
||||
source="$(readlink "${source}")"
|
||||
fi
|
||||
|
||||
# Use filter instead of exclude so missing patterns don't throw errors.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
|
||||
|
||||
local basename
|
||||
basename="$(basename -s .framework "$1")"
|
||||
binary="${destination}/${basename}.framework/${basename}"
|
||||
if ! [ -r "$binary" ]; then
|
||||
binary="${destination}/${basename}"
|
||||
fi
|
||||
|
||||
# Strip invalid architectures so "fat" simulator / device frameworks work on device
|
||||
if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
|
||||
strip_invalid_archs "$binary"
|
||||
fi
|
||||
|
||||
# Resign the code if required by the build settings to avoid unstable apps
|
||||
code_sign_if_enabled "${destination}/$(basename "$1")"
|
||||
|
||||
# Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
|
||||
if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
|
||||
local swift_runtime_libs
|
||||
swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]})
|
||||
for lib in $swift_runtime_libs; do
|
||||
echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
|
||||
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
|
||||
code_sign_if_enabled "${destination}/${lib}"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
# Copies and strips a vendored dSYM
|
||||
install_dsym() {
|
||||
local source="$1"
|
||||
if [ -r "$source" ]; then
|
||||
# Copy the dSYM into a the targets temp dir.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
|
||||
|
||||
local basename
|
||||
basename="$(basename -s .framework.dSYM "$source")"
|
||||
binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}"
|
||||
|
||||
# Strip invalid architectures so "fat" simulator / device frameworks work on device
|
||||
if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then
|
||||
strip_invalid_archs "$binary"
|
||||
fi
|
||||
|
||||
if [[ $STRIP_BINARY_RETVAL == 1 ]]; then
|
||||
# Move the stripped file into its final destination.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
|
||||
else
|
||||
# The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
|
||||
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Signs a framework with the provided identity
|
||||
code_sign_if_enabled() {
|
||||
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
|
||||
# Use the current code_sign_identitiy
|
||||
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
|
||||
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
|
||||
|
||||
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
|
||||
code_sign_cmd="$code_sign_cmd &"
|
||||
fi
|
||||
echo "$code_sign_cmd"
|
||||
eval "$code_sign_cmd"
|
||||
fi
|
||||
}
|
||||
|
||||
# Strip invalid architectures
|
||||
strip_invalid_archs() {
|
||||
binary="$1"
|
||||
# Get architectures for current target binary
|
||||
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
|
||||
# Intersect them with the architectures we are building for
|
||||
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
|
||||
# If there are no archs supported by this binary then warn the user
|
||||
if [[ -z "$intersected_archs" ]]; then
|
||||
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
|
||||
STRIP_BINARY_RETVAL=0
|
||||
return
|
||||
fi
|
||||
stripped=""
|
||||
for arch in $binary_archs; do
|
||||
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
|
||||
# Strip non-valid architectures in-place
|
||||
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
|
||||
stripped="$stripped $arch"
|
||||
fi
|
||||
done
|
||||
if [[ "$stripped" ]]; then
|
||||
echo "Stripped $binary of architectures:$stripped"
|
||||
fi
|
||||
STRIP_BINARY_RETVAL=1
|
||||
}
|
||||
|
||||
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
|
||||
wait
|
||||
fi
|
||||
124
ios/Pods/Target Support Files/Pods-Mattermost/Pods-Mattermost-resources.sh
generated
Executable file
124
ios/Pods/Target Support Files/Pods-Mattermost/Pods-Mattermost-resources.sh
generated
Executable file
|
|
@ -0,0 +1,124 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
set -u
|
||||
set -o pipefail
|
||||
|
||||
if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then
|
||||
# If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy
|
||||
# resources to, so exit 0 (signalling the script phase was successful).
|
||||
exit 0
|
||||
fi
|
||||
|
||||
mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
|
||||
RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
|
||||
> "$RESOURCES_TO_COPY"
|
||||
|
||||
XCASSET_FILES=()
|
||||
|
||||
# This protects against multiple targets copying the same framework dependency at the same time. The solution
|
||||
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
|
||||
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
|
||||
|
||||
case "${TARGETED_DEVICE_FAMILY:-}" in
|
||||
1,2)
|
||||
TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
|
||||
;;
|
||||
1)
|
||||
TARGET_DEVICE_ARGS="--target-device iphone"
|
||||
;;
|
||||
2)
|
||||
TARGET_DEVICE_ARGS="--target-device ipad"
|
||||
;;
|
||||
3)
|
||||
TARGET_DEVICE_ARGS="--target-device tv"
|
||||
;;
|
||||
4)
|
||||
TARGET_DEVICE_ARGS="--target-device watch"
|
||||
;;
|
||||
*)
|
||||
TARGET_DEVICE_ARGS="--target-device mac"
|
||||
;;
|
||||
esac
|
||||
|
||||
install_resource()
|
||||
{
|
||||
if [[ "$1" = /* ]] ; then
|
||||
RESOURCE_PATH="$1"
|
||||
else
|
||||
RESOURCE_PATH="${PODS_ROOT}/$1"
|
||||
fi
|
||||
if [[ ! -e "$RESOURCE_PATH" ]] ; then
|
||||
cat << EOM
|
||||
error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script.
|
||||
EOM
|
||||
exit 1
|
||||
fi
|
||||
case $RESOURCE_PATH in
|
||||
*.storyboard)
|
||||
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
|
||||
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
|
||||
;;
|
||||
*.xib)
|
||||
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
|
||||
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
|
||||
;;
|
||||
*.framework)
|
||||
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
|
||||
mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
;;
|
||||
*.xcdatamodel)
|
||||
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true
|
||||
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom"
|
||||
;;
|
||||
*.xcdatamodeld)
|
||||
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true
|
||||
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd"
|
||||
;;
|
||||
*.xcmappingmodel)
|
||||
echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true
|
||||
xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
|
||||
;;
|
||||
*.xcassets)
|
||||
ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH"
|
||||
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
|
||||
;;
|
||||
*)
|
||||
echo "$RESOURCE_PATH" || true
|
||||
echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
if [[ "$CONFIGURATION" == "Debug" ]]; then
|
||||
install_resource "${PODS_ROOT}/YoutubePlayer-in-WKWebView/WKYTPlayerView/WKYTPlayerView.bundle"
|
||||
fi
|
||||
if [[ "$CONFIGURATION" == "Release" ]]; then
|
||||
install_resource "${PODS_ROOT}/YoutubePlayer-in-WKWebView/WKYTPlayerView/WKYTPlayerView.bundle"
|
||||
fi
|
||||
|
||||
mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then
|
||||
mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
fi
|
||||
rm -f "$RESOURCES_TO_COPY"
|
||||
|
||||
if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ]
|
||||
then
|
||||
# Find all other xcassets (this unfortunately includes those of path pods and other targets).
|
||||
OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
|
||||
while read line; do
|
||||
if [[ $line != "${PODS_ROOT}*" ]]; then
|
||||
XCASSET_FILES+=("$line")
|
||||
fi
|
||||
done <<<"$OTHER_XCASSETS"
|
||||
|
||||
if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then
|
||||
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
else
|
||||
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist"
|
||||
fi
|
||||
fi
|
||||
9
ios/Pods/Target Support Files/Pods-Mattermost/Pods-Mattermost.debug.xcconfig
generated
Normal file
9
ios/Pods/Target Support Files/Pods-Mattermost/Pods-Mattermost.debug.xcconfig
generated
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/XCDYouTubeKit" "${PODS_ROOT}/Headers/Public/YoutubePlayer-in-WKWebView"
|
||||
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/XCDYouTubeKit" "${PODS_CONFIGURATION_BUILD_DIR}/YoutubePlayer-in-WKWebView"
|
||||
OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/XCDYouTubeKit" -isystem "${PODS_ROOT}/Headers/Public/YoutubePlayer-in-WKWebView"
|
||||
OTHER_LDFLAGS = $(inherited) -ObjC -l"XCDYouTubeKit" -l"YoutubePlayer-in-WKWebView" -framework "JavaScriptCore" -framework "MediaPlayer"
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
||||
9
ios/Pods/Target Support Files/Pods-Mattermost/Pods-Mattermost.release.xcconfig
generated
Normal file
9
ios/Pods/Target Support Files/Pods-Mattermost/Pods-Mattermost.release.xcconfig
generated
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/XCDYouTubeKit" "${PODS_ROOT}/Headers/Public/YoutubePlayer-in-WKWebView"
|
||||
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/XCDYouTubeKit" "${PODS_CONFIGURATION_BUILD_DIR}/YoutubePlayer-in-WKWebView"
|
||||
OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/XCDYouTubeKit" -isystem "${PODS_ROOT}/Headers/Public/YoutubePlayer-in-WKWebView"
|
||||
OTHER_LDFLAGS = $(inherited) -ObjC -l"XCDYouTubeKit" -l"YoutubePlayer-in-WKWebView" -framework "JavaScriptCore" -framework "MediaPlayer"
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Acknowledgements
|
||||
This application makes use of the following third party libraries:
|
||||
Generated by CocoaPods - https://cocoapods.org
|
||||
29
ios/Pods/Target Support Files/Pods-MattermostTests/Pods-MattermostTests-acknowledgements.plist
generated
Normal file
29
ios/Pods/Target Support Files/Pods-MattermostTests/Pods-MattermostTests-acknowledgements.plist
generated
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PreferenceSpecifiers</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>This application makes use of the following third party libraries:</string>
|
||||
<key>Title</key>
|
||||
<string>Acknowledgements</string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>Generated by CocoaPods - https://cocoapods.org</string>
|
||||
<key>Title</key>
|
||||
<string></string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>StringsTable</key>
|
||||
<string>Acknowledgements</string>
|
||||
<key>Title</key>
|
||||
<string>Acknowledgements</string>
|
||||
</dict>
|
||||
</plist>
|
||||
5
ios/Pods/Target Support Files/Pods-MattermostTests/Pods-MattermostTests-dummy.m
generated
Normal file
5
ios/Pods/Target Support Files/Pods-MattermostTests/Pods-MattermostTests-dummy.m
generated
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
@interface PodsDummy_Pods_MattermostTests : NSObject
|
||||
@end
|
||||
@implementation PodsDummy_Pods_MattermostTests
|
||||
@end
|
||||
146
ios/Pods/Target Support Files/Pods-MattermostTests/Pods-MattermostTests-frameworks.sh
generated
Executable file
146
ios/Pods/Target Support Files/Pods-MattermostTests/Pods-MattermostTests-frameworks.sh
generated
Executable file
|
|
@ -0,0 +1,146 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
set -u
|
||||
set -o pipefail
|
||||
|
||||
if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
|
||||
# If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
|
||||
# frameworks to, so exit 0 (signalling the script phase was successful).
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
|
||||
COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
|
||||
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
|
||||
|
||||
# Used as a return value for each invocation of `strip_invalid_archs` function.
|
||||
STRIP_BINARY_RETVAL=0
|
||||
|
||||
# This protects against multiple targets copying the same framework dependency at the same time. The solution
|
||||
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
|
||||
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
|
||||
|
||||
# Copies and strips a vendored framework
|
||||
install_framework()
|
||||
{
|
||||
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
|
||||
local source="${BUILT_PRODUCTS_DIR}/$1"
|
||||
elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
|
||||
local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
|
||||
elif [ -r "$1" ]; then
|
||||
local source="$1"
|
||||
fi
|
||||
|
||||
local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
|
||||
if [ -L "${source}" ]; then
|
||||
echo "Symlinked..."
|
||||
source="$(readlink "${source}")"
|
||||
fi
|
||||
|
||||
# Use filter instead of exclude so missing patterns don't throw errors.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
|
||||
|
||||
local basename
|
||||
basename="$(basename -s .framework "$1")"
|
||||
binary="${destination}/${basename}.framework/${basename}"
|
||||
if ! [ -r "$binary" ]; then
|
||||
binary="${destination}/${basename}"
|
||||
fi
|
||||
|
||||
# Strip invalid architectures so "fat" simulator / device frameworks work on device
|
||||
if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
|
||||
strip_invalid_archs "$binary"
|
||||
fi
|
||||
|
||||
# Resign the code if required by the build settings to avoid unstable apps
|
||||
code_sign_if_enabled "${destination}/$(basename "$1")"
|
||||
|
||||
# Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
|
||||
if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
|
||||
local swift_runtime_libs
|
||||
swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]})
|
||||
for lib in $swift_runtime_libs; do
|
||||
echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
|
||||
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
|
||||
code_sign_if_enabled "${destination}/${lib}"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
# Copies and strips a vendored dSYM
|
||||
install_dsym() {
|
||||
local source="$1"
|
||||
if [ -r "$source" ]; then
|
||||
# Copy the dSYM into a the targets temp dir.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
|
||||
|
||||
local basename
|
||||
basename="$(basename -s .framework.dSYM "$source")"
|
||||
binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}"
|
||||
|
||||
# Strip invalid architectures so "fat" simulator / device frameworks work on device
|
||||
if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then
|
||||
strip_invalid_archs "$binary"
|
||||
fi
|
||||
|
||||
if [[ $STRIP_BINARY_RETVAL == 1 ]]; then
|
||||
# Move the stripped file into its final destination.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
|
||||
else
|
||||
# The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
|
||||
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Signs a framework with the provided identity
|
||||
code_sign_if_enabled() {
|
||||
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
|
||||
# Use the current code_sign_identitiy
|
||||
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
|
||||
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
|
||||
|
||||
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
|
||||
code_sign_cmd="$code_sign_cmd &"
|
||||
fi
|
||||
echo "$code_sign_cmd"
|
||||
eval "$code_sign_cmd"
|
||||
fi
|
||||
}
|
||||
|
||||
# Strip invalid architectures
|
||||
strip_invalid_archs() {
|
||||
binary="$1"
|
||||
# Get architectures for current target binary
|
||||
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
|
||||
# Intersect them with the architectures we are building for
|
||||
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
|
||||
# If there are no archs supported by this binary then warn the user
|
||||
if [[ -z "$intersected_archs" ]]; then
|
||||
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
|
||||
STRIP_BINARY_RETVAL=0
|
||||
return
|
||||
fi
|
||||
stripped=""
|
||||
for arch in $binary_archs; do
|
||||
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
|
||||
# Strip non-valid architectures in-place
|
||||
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
|
||||
stripped="$stripped $arch"
|
||||
fi
|
||||
done
|
||||
if [[ "$stripped" ]]; then
|
||||
echo "Stripped $binary of architectures:$stripped"
|
||||
fi
|
||||
STRIP_BINARY_RETVAL=1
|
||||
}
|
||||
|
||||
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
|
||||
wait
|
||||
fi
|
||||
118
ios/Pods/Target Support Files/Pods-MattermostTests/Pods-MattermostTests-resources.sh
generated
Executable file
118
ios/Pods/Target Support Files/Pods-MattermostTests/Pods-MattermostTests-resources.sh
generated
Executable file
|
|
@ -0,0 +1,118 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
set -u
|
||||
set -o pipefail
|
||||
|
||||
if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then
|
||||
# If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy
|
||||
# resources to, so exit 0 (signalling the script phase was successful).
|
||||
exit 0
|
||||
fi
|
||||
|
||||
mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
|
||||
RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
|
||||
> "$RESOURCES_TO_COPY"
|
||||
|
||||
XCASSET_FILES=()
|
||||
|
||||
# This protects against multiple targets copying the same framework dependency at the same time. The solution
|
||||
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
|
||||
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
|
||||
|
||||
case "${TARGETED_DEVICE_FAMILY:-}" in
|
||||
1,2)
|
||||
TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
|
||||
;;
|
||||
1)
|
||||
TARGET_DEVICE_ARGS="--target-device iphone"
|
||||
;;
|
||||
2)
|
||||
TARGET_DEVICE_ARGS="--target-device ipad"
|
||||
;;
|
||||
3)
|
||||
TARGET_DEVICE_ARGS="--target-device tv"
|
||||
;;
|
||||
4)
|
||||
TARGET_DEVICE_ARGS="--target-device watch"
|
||||
;;
|
||||
*)
|
||||
TARGET_DEVICE_ARGS="--target-device mac"
|
||||
;;
|
||||
esac
|
||||
|
||||
install_resource()
|
||||
{
|
||||
if [[ "$1" = /* ]] ; then
|
||||
RESOURCE_PATH="$1"
|
||||
else
|
||||
RESOURCE_PATH="${PODS_ROOT}/$1"
|
||||
fi
|
||||
if [[ ! -e "$RESOURCE_PATH" ]] ; then
|
||||
cat << EOM
|
||||
error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script.
|
||||
EOM
|
||||
exit 1
|
||||
fi
|
||||
case $RESOURCE_PATH in
|
||||
*.storyboard)
|
||||
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
|
||||
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
|
||||
;;
|
||||
*.xib)
|
||||
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
|
||||
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
|
||||
;;
|
||||
*.framework)
|
||||
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
|
||||
mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
;;
|
||||
*.xcdatamodel)
|
||||
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true
|
||||
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom"
|
||||
;;
|
||||
*.xcdatamodeld)
|
||||
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true
|
||||
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd"
|
||||
;;
|
||||
*.xcmappingmodel)
|
||||
echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true
|
||||
xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
|
||||
;;
|
||||
*.xcassets)
|
||||
ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH"
|
||||
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
|
||||
;;
|
||||
*)
|
||||
echo "$RESOURCE_PATH" || true
|
||||
echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then
|
||||
mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
fi
|
||||
rm -f "$RESOURCES_TO_COPY"
|
||||
|
||||
if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ]
|
||||
then
|
||||
# Find all other xcassets (this unfortunately includes those of path pods and other targets).
|
||||
OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
|
||||
while read line; do
|
||||
if [[ $line != "${PODS_ROOT}*" ]]; then
|
||||
XCASSET_FILES+=("$line")
|
||||
fi
|
||||
done <<<"$OTHER_XCASSETS"
|
||||
|
||||
if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then
|
||||
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
else
|
||||
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist"
|
||||
fi
|
||||
fi
|
||||
9
ios/Pods/Target Support Files/Pods-MattermostTests/Pods-MattermostTests.debug.xcconfig
generated
Normal file
9
ios/Pods/Target Support Files/Pods-MattermostTests/Pods-MattermostTests.debug.xcconfig
generated
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/XCDYouTubeKit" "${PODS_ROOT}/Headers/Public/YoutubePlayer-in-WKWebView"
|
||||
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/XCDYouTubeKit" "${PODS_CONFIGURATION_BUILD_DIR}/YoutubePlayer-in-WKWebView"
|
||||
OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/XCDYouTubeKit" -isystem "${PODS_ROOT}/Headers/Public/YoutubePlayer-in-WKWebView"
|
||||
OTHER_LDFLAGS = $(inherited) -ObjC -framework "JavaScriptCore" -framework "MediaPlayer"
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
||||
9
ios/Pods/Target Support Files/Pods-MattermostTests/Pods-MattermostTests.release.xcconfig
generated
Normal file
9
ios/Pods/Target Support Files/Pods-MattermostTests/Pods-MattermostTests.release.xcconfig
generated
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/XCDYouTubeKit" "${PODS_ROOT}/Headers/Public/YoutubePlayer-in-WKWebView"
|
||||
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/XCDYouTubeKit" "${PODS_CONFIGURATION_BUILD_DIR}/YoutubePlayer-in-WKWebView"
|
||||
OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/XCDYouTubeKit" -isystem "${PODS_ROOT}/Headers/Public/YoutubePlayer-in-WKWebView"
|
||||
OTHER_LDFLAGS = $(inherited) -ObjC -framework "JavaScriptCore" -framework "MediaPlayer"
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
||||
5
ios/Pods/Target Support Files/XCDYouTubeKit/XCDYouTubeKit-dummy.m
generated
Normal file
5
ios/Pods/Target Support Files/XCDYouTubeKit/XCDYouTubeKit-dummy.m
generated
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
@interface PodsDummy_XCDYouTubeKit : NSObject
|
||||
@end
|
||||
@implementation PodsDummy_XCDYouTubeKit
|
||||
@end
|
||||
12
ios/Pods/Target Support Files/XCDYouTubeKit/XCDYouTubeKit-prefix.pch
generated
Normal file
12
ios/Pods/Target Support Files/XCDYouTubeKit/XCDYouTubeKit-prefix.pch
generated
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#ifdef __OBJC__
|
||||
#import <UIKit/UIKit.h>
|
||||
#else
|
||||
#ifndef FOUNDATION_EXPORT
|
||||
#if defined(__cplusplus)
|
||||
#define FOUNDATION_EXPORT extern "C"
|
||||
#else
|
||||
#define FOUNDATION_EXPORT extern
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
10
ios/Pods/Target Support Files/XCDYouTubeKit/XCDYouTubeKit.xcconfig
generated
Normal file
10
ios/Pods/Target Support Files/XCDYouTubeKit/XCDYouTubeKit.xcconfig
generated
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/XCDYouTubeKit
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/XCDYouTubeKit" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/XCDYouTubeKit"
|
||||
OTHER_LDFLAGS = -framework "JavaScriptCore" -framework "MediaPlayer"
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_ROOT = ${SRCROOT}
|
||||
PODS_TARGET_SRCROOT = ${PODS_ROOT}/XCDYouTubeKit
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||
SKIP_INSTALL = YES
|
||||
5
ios/Pods/Target Support Files/YoutubePlayer-in-WKWebView/YoutubePlayer-in-WKWebView-dummy.m
generated
Normal file
5
ios/Pods/Target Support Files/YoutubePlayer-in-WKWebView/YoutubePlayer-in-WKWebView-dummy.m
generated
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
@interface PodsDummy_YoutubePlayer_in_WKWebView : NSObject
|
||||
@end
|
||||
@implementation PodsDummy_YoutubePlayer_in_WKWebView
|
||||
@end
|
||||
12
ios/Pods/Target Support Files/YoutubePlayer-in-WKWebView/YoutubePlayer-in-WKWebView-prefix.pch
generated
Normal file
12
ios/Pods/Target Support Files/YoutubePlayer-in-WKWebView/YoutubePlayer-in-WKWebView-prefix.pch
generated
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#ifdef __OBJC__
|
||||
#import <UIKit/UIKit.h>
|
||||
#else
|
||||
#ifndef FOUNDATION_EXPORT
|
||||
#if defined(__cplusplus)
|
||||
#define FOUNDATION_EXPORT extern "C"
|
||||
#else
|
||||
#define FOUNDATION_EXPORT extern
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
9
ios/Pods/Target Support Files/YoutubePlayer-in-WKWebView/YoutubePlayer-in-WKWebView.xcconfig
generated
Normal file
9
ios/Pods/Target Support Files/YoutubePlayer-in-WKWebView/YoutubePlayer-in-WKWebView.xcconfig
generated
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/YoutubePlayer-in-WKWebView
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/YoutubePlayer-in-WKWebView" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/YoutubePlayer-in-WKWebView"
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_ROOT = ${SRCROOT}
|
||||
PODS_TARGET_SRCROOT = ${PODS_ROOT}/YoutubePlayer-in-WKWebView
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||
SKIP_INSTALL = YES
|
||||
22
ios/Pods/XCDYouTubeKit/LICENSE
generated
Normal file
22
ios/Pods/XCDYouTubeKit/LICENSE
generated
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2016 Cédric Luthi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
151
ios/Pods/XCDYouTubeKit/README.md
generated
Normal file
151
ios/Pods/XCDYouTubeKit/README.md
generated
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
## About
|
||||
|
||||
[](https://circleci.com/gh/0xced/XCDYouTubeKit)
|
||||
[](https://codecov.io/gh/0xced/XCDYouTubeKit/branch/develop)
|
||||
[](http://cocoadocs.org/docsets/XCDYouTubeKit/)
|
||||
[](https://cocoapods.org/pods/XCDYouTubeKit)
|
||||
[](https://github.com/Carthage/Carthage/)
|
||||
[](LICENSE)
|
||||
|
||||
**XCDYouTubeKit** is a YouTube video player for iOS, tvOS and macOS.
|
||||
|
||||
<img src="Screenshots/XCDYouTubeVideoPlayerViewController.png" width="480" height="320">
|
||||
|
||||
Are you enjoying XCDYouTubeKit? You can say thank you with [a tweet](https://twitter.com/intent/tweet?text=%400xced%20Thank%20you%20for%20XCDYouTubeKit%2E). I am also accepting donations. ;-)
|
||||
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=MGEPRSNQFMV3W)
|
||||
|
||||
## Requirements
|
||||
|
||||
- Runs on iOS 8.0 and later
|
||||
- Runs on macOS 10.9 and later
|
||||
- Runs on tvOS 9.0 and later
|
||||
|
||||
## Warning
|
||||
|
||||
XCDYouTubeKit is against the YouTube [Terms of Service](https://www.youtube.com/t/terms). The only *official* way of playing a YouTube video inside an app is with a web view and the [iframe player API](https://developers.google.com/youtube/iframe_api_reference). Unfortunately, this is very slow and quite ugly, so I wrote this player to give users a better viewing experience.
|
||||
|
||||
## Installation
|
||||
|
||||
XCDYouTubeKit is available through CocoaPods and Carthage.
|
||||
|
||||
CocoaPods:
|
||||
|
||||
```ruby
|
||||
pod "XCDYouTubeKit", "~> 2.7"
|
||||
```
|
||||
|
||||
Carthage:
|
||||
|
||||
```objc
|
||||
github "0xced/XCDYouTubeKit" ~> 2.7
|
||||
```
|
||||
|
||||
Alternatively, you can manually use the provided static library or dynamic framework. In order to use the static library, you must:
|
||||
|
||||
1. Create a workspace (File → New → Workspace…)
|
||||
2. Add your project to the workspace
|
||||
3. Add the XCDYouTubeKit project to the workspace
|
||||
4. Drag and drop the `libXCDYouTubeKit.a` file referenced from XCDYouTubeKit → Products → libXCDYouTubeKit.a into the *Link Binary With Libraries* build phase of your app’s target.
|
||||
|
||||
These steps will ensure that `#import <XCDYouTubeKit/XCDYouTubeKit.h>` will work properly in your project.
|
||||
|
||||
## Usage
|
||||
|
||||
XCDYouTubeKit is [fully documented](http://cocoadocs.org/docsets/XCDYouTubeKit/).
|
||||
|
||||
### iOS 8.0+ & tvOS (AVPlayerViewController)
|
||||
|
||||
```objc
|
||||
AVPlayerViewController *playerViewController = [AVPlayerViewController new];
|
||||
[self presentViewController:playerViewController animated:YES completion:nil];
|
||||
|
||||
__weak AVPlayerViewController *weakPlayerViewController = playerViewController;
|
||||
[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:videoIdentifier completionHandler:^(XCDYouTubeVideo * _Nullable video, NSError * _Nullable error) {
|
||||
if (video)
|
||||
{
|
||||
NSDictionary *streamURLs = video.streamURLs;
|
||||
NSURL *streamURL = streamURLs[XCDYouTubeVideoQualityHTTPLiveStreaming] ?: streamURLs[@(XCDYouTubeVideoQualityHD720)] ?: streamURLs[@(XCDYouTubeVideoQualityMedium360)] ?: streamURLs[@(XCDYouTubeVideoQualitySmall240)];
|
||||
weakPlayerViewController.player = [AVPlayer playerWithURL:streamURL];
|
||||
[weakPlayerViewController.player play];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
}];
|
||||
```
|
||||
|
||||
### iOS, tvOS and macOS
|
||||
|
||||
```objc
|
||||
NSString *videoIdentifier = @"9bZkp7q19f0"; // A 11 characters YouTube video identifier
|
||||
[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:videoIdentifier completionHandler:^(XCDYouTubeVideo *video, NSError *error) {
|
||||
if (video)
|
||||
{
|
||||
// Do something with the `video` object
|
||||
}
|
||||
else
|
||||
{
|
||||
// Handle error
|
||||
}
|
||||
}];
|
||||
```
|
||||
|
||||
### iOS 8.0
|
||||
|
||||
On iOS, you can use the class `XCDYouTubeVideoPlayerViewController` the same way you use a `MPMoviePlayerViewController`, except you initialize it with a YouTube video identifier instead of a content URL.
|
||||
|
||||
#### Present the video in full-screen
|
||||
|
||||
```objc
|
||||
- (void) playVideo
|
||||
{
|
||||
XCDYouTubeVideoPlayerViewController *videoPlayerViewController = [[XCDYouTubeVideoPlayerViewController alloc] initWithVideoIdentifier:@"9bZkp7q19f0"];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerPlaybackDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:videoPlayerViewController.moviePlayer];
|
||||
[self presentMoviePlayerViewControllerAnimated:videoPlayerViewController];
|
||||
}
|
||||
|
||||
- (void) moviePlayerPlaybackDidFinish:(NSNotification *)notification
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:notification.object];
|
||||
MPMovieFinishReason finishReason = [notification.userInfo[MPMoviePlayerPlaybackDidFinishReasonUserInfoKey] integerValue];
|
||||
if (finishReason == MPMovieFinishReasonPlaybackError)
|
||||
{
|
||||
NSError *error = notification.userInfo[XCDMoviePlayerPlaybackDidFinishErrorUserInfoKey];
|
||||
// Handle error
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Present the video in a non full-screen view
|
||||
|
||||
```objc
|
||||
XCDYouTubeVideoPlayerViewController *videoPlayerViewController = [[XCDYouTubeVideoPlayerViewController alloc] initWithVideoIdentifier:@"9bZkp7q19f0"];
|
||||
[videoPlayerViewController presentInView:self.videoContainerView];
|
||||
[videoPlayerViewController.moviePlayer play];
|
||||
```
|
||||
|
||||
See the demo project for more sample code.
|
||||
|
||||
## Logging
|
||||
|
||||
Since version 2.2.0, XCDYouTubeKit produces logs. XCDYouTubeKit supports [CocoaLumberjack](https://github.com/CocoaLumberjack/CocoaLumberjack) but does not require it.
|
||||
|
||||
See the `XCDYouTubeLogger` class [documentation](http://cocoadocs.org/docsets/XCDYouTubeKit/) for more information.
|
||||
|
||||
## Credits
|
||||
|
||||
The URL extraction algorithms in *XCDYouTubeKit* are inspired by the [YouTube extractor](https://github.com/rg3/youtube-dl/blob/master/youtube_dl/extractor/youtube.py) module of the *youtube-dl* project.
|
||||
|
||||
## Contact
|
||||
|
||||
Cédric Luthi
|
||||
|
||||
- http://github.com/0xced
|
||||
- http://twitter.com/0xced
|
||||
|
||||
## License
|
||||
|
||||
XCDYouTubeKit is available under the MIT license. See the [LICENSE](LICENSE) file for more information.
|
||||
98
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeClient.h
generated
Normal file
98
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeClient.h
generated
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
//
|
||||
// Copyright (c) 2013-2016 Cédric Luthi. All rights reserved.
|
||||
//
|
||||
|
||||
#if !__has_feature(nullability)
|
||||
#define NS_ASSUME_NONNULL_BEGIN
|
||||
#define NS_ASSUME_NONNULL_END
|
||||
#define nullable
|
||||
#define __nullable
|
||||
#endif
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <XCDYouTubeKit/XCDYouTubeOperation.h>
|
||||
#import <XCDYouTubeKit/XCDYouTubeVideo.h>
|
||||
#import <XCDYouTubeKit/XCDYouTubeError.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* The `XCDYouTubeClient` class is responsible for interacting with the YouTube API. Given a YouTube video identifier, you will get video information with the `<-getVideoWithIdentifier:completionHandler:>` method.
|
||||
*
|
||||
* On iOS, you probably don’t want to use `XCDYouTubeClient` directly but the higher level class `<XCDYouTubeVideoPlayerViewController>`.
|
||||
*/
|
||||
@interface XCDYouTubeClient : NSObject
|
||||
|
||||
/**
|
||||
* ------------------
|
||||
* @name Initializing
|
||||
* ------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the shared client with the default language, i.e. the preferred language of the main bundle.
|
||||
*
|
||||
* @return The default client.
|
||||
*/
|
||||
+ (instancetype) defaultClient;
|
||||
|
||||
/**
|
||||
* Initializes a client with the specified language identifier.
|
||||
*
|
||||
* @param languageIdentifier An [ISO 639-1 two-letter language code](http://www.loc.gov/standards/iso639-2/php/code_list.php) used for error localization. If you pass a nil language identifier, the preferred language of the main bundle will be used.
|
||||
*
|
||||
* @return A client with the specified language identifier.
|
||||
*/
|
||||
- (instancetype) initWithLanguageIdentifier:(nullable NSString *)languageIdentifier;
|
||||
|
||||
/**
|
||||
* ---------------------------------
|
||||
* @name Accessing client properties
|
||||
* ---------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* The language identifier of the client, used for error localization.
|
||||
*
|
||||
* @see -initWithLanguageIdentifier:
|
||||
*/
|
||||
@property (nonatomic, readonly) NSString *languageIdentifier;
|
||||
|
||||
/**
|
||||
* --------------------------------------
|
||||
* @name Interacting with the YouTube API
|
||||
* --------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Starts an asynchronous operation for the specified video identifier, and calls a handler upon completion.
|
||||
*
|
||||
* @param videoIdentifier A 11 characters YouTube video identifier. If the video identifier is invalid (including nil) the completion handler will be called with an error with `XCDYouTubeVideoErrorDomain` domain and `XCDYouTubeErrorInvalidVideoIdentifier` code.
|
||||
* @param completionHandler A block to execute when the client finishes the operation. The completion handler is executed on the main thread. If the completion handler is nil, this method throws an exception.
|
||||
*
|
||||
* @discussion If the operation completes successfully, the video parameter of the handler block contains a `<XCDYouTubeVideo>` object, and the error parameter is nil. If the operation fails, the video parameter is nil and the error parameter contains information about the failure. The error's domain is always `XCDYouTubeVideoErrorDomain`.
|
||||
*
|
||||
* @see XCDYouTubeErrorCode
|
||||
*
|
||||
* @return An opaque object conforming to the `<XCDYouTubeOperation>` protocol for canceling the asynchronous video information operation. If you call the `cancel` method before the operation is finished, the completion handler will not be called. It is recommended that you store this opaque object as a weak property.
|
||||
*/
|
||||
- (id<XCDYouTubeOperation>) getVideoWithIdentifier:(nullable NSString *)videoIdentifier completionHandler:(void (^)(XCDYouTubeVideo * __nullable video, NSError * __nullable error))completionHandler;
|
||||
|
||||
/**
|
||||
* Starts an asynchronous operation for the specified video identifier, and calls a handler upon completion.
|
||||
*
|
||||
* @param videoIdentifier A 11 characters YouTube video identifier. If the video identifier is invalid (including nil) the completion handler will be called with an error with `XCDYouTubeVideoErrorDomain` domain and `XCDYouTubeErrorInvalidVideoIdentifier` code.
|
||||
* @param cookies An array of `NSHTTPCookie` objects, can be nil. These cookies can be used for certain videos that require a login.
|
||||
* @param completionHandler A block to execute when the client finishes the operation. The completion handler is executed on the main thread. If the completion handler is nil, this method throws an exception.
|
||||
*
|
||||
* @discussion If the operation completes successfully, the video parameter of the handler block contains a `<XCDYouTubeVideo>` object, and the error parameter is nil. If the operation fails, the video parameter is nil and the error parameter contains information about the failure. The error's domain is always `XCDYouTubeVideoErrorDomain`.
|
||||
*
|
||||
* @see XCDYouTubeErrorCode
|
||||
*
|
||||
* @return An opaque object conforming to the `<XCDYouTubeOperation>` protocol for canceling the asynchronous video information operation. If you call the `cancel` method before the operation is finished, the completion handler will not be called. It is recommended that you store this opaque object as a weak property.
|
||||
*/
|
||||
- (id<XCDYouTubeOperation>) getVideoWithIdentifier:(NSString *)videoIdentifier cookies:(nullable NSArray <NSHTTPCookie *>*)cookies completionHandler:(void (^)(XCDYouTubeVideo * __nullable video, NSError * __nullable error))completionHandler;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
83
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeClient.m
generated
Normal file
83
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeClient.m
generated
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
//
|
||||
// Copyright (c) 2013-2016 Cédric Luthi. All rights reserved.
|
||||
//
|
||||
|
||||
#import "XCDYouTubeClient.h"
|
||||
|
||||
#import "XCDYouTubeVideoOperation.h"
|
||||
|
||||
@interface XCDYouTubeClient ()
|
||||
@property (nonatomic, strong) NSOperationQueue *queue;
|
||||
@end
|
||||
|
||||
@implementation XCDYouTubeClient
|
||||
|
||||
@synthesize languageIdentifier = _languageIdentifier;
|
||||
|
||||
+ (instancetype) defaultClient
|
||||
{
|
||||
static XCDYouTubeClient *defaultClient;
|
||||
static dispatch_once_t once;
|
||||
dispatch_once(&once, ^{
|
||||
defaultClient = [self new];
|
||||
});
|
||||
return defaultClient;
|
||||
}
|
||||
|
||||
- (instancetype) init
|
||||
{
|
||||
return [self initWithLanguageIdentifier:nil];
|
||||
}
|
||||
|
||||
- (instancetype) initWithLanguageIdentifier:(NSString *)languageIdentifier
|
||||
{
|
||||
if (!(self = [super init]))
|
||||
return nil; // LCOV_EXCL_LINE
|
||||
|
||||
_languageIdentifier = ^{
|
||||
return languageIdentifier ?: ^{
|
||||
NSArray *preferredLocalizations = [[NSBundle mainBundle] preferredLocalizations];
|
||||
NSString *preferredLocalization = preferredLocalizations.firstObject ?: @"en";
|
||||
return [NSLocale canonicalLanguageIdentifierFromString:preferredLocalization] ?: @"en";
|
||||
}();
|
||||
}();
|
||||
|
||||
_queue = [NSOperationQueue new];
|
||||
_queue.maxConcurrentOperationCount = 6; // paul_irish: Chrome re-confirmed that the 6 connections-per-host limit is the right magic number: https://code.google.com/p/chromium/issues/detail?id=285567#c14 [https://twitter.com/paul_irish/status/422808635698212864]
|
||||
_queue.name = NSStringFromClass(self.class);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id<XCDYouTubeOperation>) getVideoWithIdentifier:(NSString *)videoIdentifier cookies:(NSArray<NSHTTPCookie *> *)cookies completionHandler:(void (^)(XCDYouTubeVideo * _Nullable, NSError * _Nullable))completionHandler
|
||||
{
|
||||
if (!completionHandler)
|
||||
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"The `completionHandler` argument must not be nil." userInfo:nil];
|
||||
|
||||
XCDYouTubeVideoOperation *operation = [[XCDYouTubeVideoOperation alloc] initWithVideoIdentifier:videoIdentifier languageIdentifier:self.languageIdentifier cookies:cookies];
|
||||
operation.completionBlock = ^{
|
||||
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Warc-retain-cycles"
|
||||
if (operation.video || operation.error)
|
||||
{
|
||||
NSAssert(!(operation.video && operation.error), @"One of `video` or `error` must be nil.");
|
||||
completionHandler(operation.video, operation.error);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSAssert(operation.isCancelled, @"Both `video` and `error` can not be nil if the operation was not canceled.");
|
||||
}
|
||||
operation.completionBlock = nil;
|
||||
#pragma clang diagnostic pop
|
||||
}];
|
||||
};
|
||||
[self.queue addOperation:operation];
|
||||
return operation;
|
||||
}
|
||||
- (id<XCDYouTubeOperation>) getVideoWithIdentifier:(NSString *)videoIdentifier completionHandler:(void (^)(XCDYouTubeVideo * __nullable video, NSError * __nullable error))completionHandler
|
||||
{
|
||||
return [self getVideoWithIdentifier:videoIdentifier cookies:nil completionHandler:completionHandler];
|
||||
}
|
||||
|
||||
@end
|
||||
17
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeDashManifestXML.h
generated
Normal file
17
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeDashManifestXML.h
generated
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
//
|
||||
// XCDYouTubeDashManifestXML.h
|
||||
// XCDYouTubeKit
|
||||
//
|
||||
// Created by Soneé John on 10/24/17.
|
||||
// Copyright © 2017 Cédric Luthi. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
__attribute__((visibility("hidden")))
|
||||
@interface XCDYouTubeDashManifestXML : NSObject
|
||||
|
||||
- (instancetype)initWithXMLString:(NSString *)XMLString;
|
||||
|
||||
- (NSDictionary *)streamURLs;
|
||||
|
||||
@end
|
||||
98
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeDashManifestXML.m
generated
Normal file
98
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeDashManifestXML.m
generated
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
//
|
||||
// XCDYouTubeDashManifestXML.m
|
||||
// XCDYouTubeKit
|
||||
//
|
||||
// Created by Soneé John on 10/24/17.
|
||||
// Copyright © 2017 Cédric Luthi. All rights reserved.
|
||||
//
|
||||
|
||||
#import "XCDYouTubeDashManifestXML.h"
|
||||
|
||||
@interface XCDYouTubeDashManifestXML()
|
||||
@property (nonatomic, readonly) NSString *XMLString;
|
||||
@end
|
||||
|
||||
|
||||
@implementation XCDYouTubeDashManifestXML
|
||||
|
||||
- (instancetype)initWithXMLString:(NSString *)XMLString
|
||||
{
|
||||
if (!(self = [super init]))
|
||||
return nil; // LCOV_EXCL_LINE
|
||||
|
||||
_XMLString = XMLString;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSDictionary *)streamURLs
|
||||
{
|
||||
|
||||
//Catch the type
|
||||
NSError *xmlTypeRegexError = NULL;
|
||||
NSRegularExpression *xmlTypeRegex = [NSRegularExpression regularExpressionWithPattern:@"(?<=(type=\"))(\\w|\\d|\\n|[().,\\-:;@#$%^&*\\[\\]\"'+–/\\/®°⁰!?{}|`~]| )+?(?=(\"))" options:NSRegularExpressionAnchorsMatchLines error:&xmlTypeRegexError];
|
||||
if (xmlTypeRegexError)
|
||||
return nil;
|
||||
NSTextCheckingResult *xmlTypeRegexCheckingResult = [xmlTypeRegex firstMatchInString:self.XMLString options:0 range:NSMakeRange(0, self.XMLString.length)];
|
||||
NSString *xmlType = [self.XMLString substringWithRange:xmlTypeRegexCheckingResult.range];
|
||||
|
||||
NSRange staticRange = [xmlType rangeOfString:@"static" options:0];
|
||||
if (staticRange.location == NSNotFound)
|
||||
return nil;
|
||||
|
||||
//Do not process manifests that have DRM protection
|
||||
NSRange contentProtectionRange = [self.XMLString rangeOfString:@"ContentProtection" options:0];
|
||||
NSRange mp4ProtectionRange = [self.XMLString rangeOfString:@"mp4protection" options:0];
|
||||
if (contentProtectionRange.location != NSNotFound || mp4ProtectionRange.location != NSNotFound)
|
||||
return nil;
|
||||
|
||||
//Catch all URLs
|
||||
NSError *error = nil;
|
||||
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?<=(<BaseURL>))(\\w|\\d|\\n|[().,\\-:;@#$%^&*\\[\\]\"'+–/\\/®°⁰!?{}|`~]| )+?(?=(</BaseURL>))" options:0 error:&error];
|
||||
|
||||
if (error)
|
||||
return nil;
|
||||
|
||||
NSArray *checkingResults = [regex matchesInString:self.XMLString options:0 range:NSMakeRange(0, [self.XMLString length])];
|
||||
|
||||
if (checkingResults.count == 0 || checkingResults == nil)
|
||||
return nil;
|
||||
|
||||
NSMutableArray <NSURL *>*URLs = [NSMutableArray new];
|
||||
NSMutableDictionary *streamURLs = [NSMutableDictionary new];
|
||||
|
||||
for (NSTextCheckingResult *checkingResult in checkingResults)
|
||||
{
|
||||
NSString* substringForMatch = [self.XMLString substringWithRange:checkingResult.range];
|
||||
NSURL *url = [NSURL URLWithString:substringForMatch];
|
||||
|
||||
NSRange youtubeRange = [url.absoluteString rangeOfString:@"youtube" options:0];
|
||||
NSRange itagnRange = [url.absoluteString rangeOfString:@"itag" options:0];
|
||||
|
||||
if (youtubeRange.location != NSNotFound && itagnRange.location != NSNotFound )
|
||||
{
|
||||
[URLs addObject:url];
|
||||
}
|
||||
}
|
||||
|
||||
for (NSURL *url in URLs)
|
||||
{
|
||||
NSError *itagRegexError = nil;
|
||||
NSRegularExpression *itagRegex = [NSRegularExpression regularExpressionWithPattern:@"(?<=(/itag/))(\\w|\\d|\\n|[().,\\-:;@#$%^&*\\[\\]\"'+–/\\/®°⁰!?{}|`~]| )+?(?=(/))" options:NSRegularExpressionAnchorsMatchLines error:&itagRegexError];
|
||||
|
||||
if (itagRegexError)
|
||||
continue;
|
||||
|
||||
NSTextCheckingResult *itagCheckingResult = [itagRegex firstMatchInString:(NSString *_Nonnull)url.absoluteString options:0 range:NSMakeRange(0, url.absoluteString.length)];
|
||||
|
||||
NSString *itag = [url.absoluteString substringWithRange:itagCheckingResult.range];
|
||||
streamURLs[@(itag.integerValue)] = url;
|
||||
}
|
||||
|
||||
if (streamURLs.count == 0)
|
||||
return nil;
|
||||
|
||||
return streamURLs;
|
||||
}
|
||||
|
||||
@end
|
||||
47
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeError.h
generated
Normal file
47
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeError.h
generated
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// Copyright (c) 2013-2016 Cédric Luthi. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/**
|
||||
* The error domain used throughout XCDYouTubeKit.
|
||||
*/
|
||||
extern NSString *const XCDYouTubeVideoErrorDomain;
|
||||
|
||||
/**
|
||||
* A key that may be present in the error's userInfo dictionary when the error code is XCDYouTubeErrorRestrictedPlayback.
|
||||
* The object for that key is a NSSet instance containing localized country names.
|
||||
*/
|
||||
extern NSString *const XCDYouTubeAllowedCountriesUserInfoKey;
|
||||
|
||||
/**
|
||||
* These values are returned as the error code property of an NSError object with the domain `XCDYouTubeVideoErrorDomain`.
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, XCDYouTubeErrorCode) {
|
||||
/**
|
||||
* Returned when no suitable video stream is available.
|
||||
*/
|
||||
XCDYouTubeErrorNoStreamAvailable = -2,
|
||||
|
||||
/**
|
||||
* Returned when a network error occurs. See `NSUnderlyingErrorKey` in the userInfo dictionary for more information.
|
||||
*/
|
||||
XCDYouTubeErrorNetwork = -1,
|
||||
|
||||
/**
|
||||
* Returned when the given video identifier string is invalid.
|
||||
*/
|
||||
XCDYouTubeErrorInvalidVideoIdentifier = 2,
|
||||
|
||||
/**
|
||||
* Previously returned when the video was removed as a violation of YouTube's policy or when the video did not exist.
|
||||
* Now replaced by code 150, i.e. `XCDYouTubeErrorRestrictedPlayback`.
|
||||
*/
|
||||
XCDYouTubeErrorRemovedVideo DEPRECATED_MSG_ATTRIBUTE("YouTube has stopped using error code 100.") = 100,
|
||||
|
||||
/**
|
||||
* Returned when the video is not playable because of legal reasons or when the video is private.
|
||||
*/
|
||||
XCDYouTubeErrorRestrictedPlayback = 150
|
||||
};
|
||||
16
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeKit.h
generated
Normal file
16
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeKit.h
generated
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
//
|
||||
// Copyright (c) 2013-2016 Cédric Luthi. All rights reserved.
|
||||
//
|
||||
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#import <XCDYouTubeKit/XCDYouTubeClient.h>
|
||||
#import <XCDYouTubeKit/XCDYouTubeError.h>
|
||||
#import <XCDYouTubeKit/XCDYouTubeLogger.h>
|
||||
#import <XCDYouTubeKit/XCDYouTubeOperation.h>
|
||||
#import <XCDYouTubeKit/XCDYouTubeVideo.h>
|
||||
#import <XCDYouTubeKit/XCDYouTubeVideoOperation.h>
|
||||
|
||||
#if TARGET_OS_IOS || (!defined(TARGET_OS_IOS) && TARGET_OS_IPHONE)
|
||||
#import <XCDYouTubeKit/XCDYouTubeVideoPlayerViewController.h>
|
||||
#endif
|
||||
21
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeLogger+Private.h
generated
Normal file
21
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeLogger+Private.h
generated
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// Copyright (c) 2013-2016 Cédric Luthi. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "XCDYouTubeLogger.h"
|
||||
|
||||
@interface XCDYouTubeLogger ()
|
||||
|
||||
+ (void) logMessage:(NSString * (^)(void))message level:(XCDLogLevel)level file:(const char *)file function:(const char *)function line:(NSUInteger)line;
|
||||
|
||||
@end
|
||||
|
||||
#define XCDYouTubeLog(_level, _message) [XCDYouTubeLogger logMessage:(_message) level:(_level) file:__FILE__ function:__PRETTY_FUNCTION__ line:__LINE__]
|
||||
|
||||
#define XCDYouTubeLogError(format, ...) XCDYouTubeLog(XCDLogLevelError, (^{ return [NSString stringWithFormat:(format), ##__VA_ARGS__]; }))
|
||||
#define XCDYouTubeLogWarning(format, ...) XCDYouTubeLog(XCDLogLevelWarning, (^{ return [NSString stringWithFormat:(format), ##__VA_ARGS__]; }))
|
||||
#define XCDYouTubeLogInfo(format, ...) XCDYouTubeLog(XCDLogLevelInfo, (^{ return [NSString stringWithFormat:(format), ##__VA_ARGS__]; }))
|
||||
#define XCDYouTubeLogDebug(format, ...) XCDYouTubeLog(XCDLogLevelDebug, (^{ return [NSString stringWithFormat:(format), ##__VA_ARGS__]; }))
|
||||
#define XCDYouTubeLogVerbose(format, ...) XCDYouTubeLog(XCDLogLevelVerbose, (^{ return [NSString stringWithFormat:(format), ##__VA_ARGS__]; }))
|
||||
103
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeLogger.h
generated
Normal file
103
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeLogger.h
generated
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
//
|
||||
// Copyright (c) 2013-2016 Cédric Luthi. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/**
|
||||
* The [context][1] used when logging with CocoaLumberjack.
|
||||
*
|
||||
* [1]: https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/CustomContext.md
|
||||
*/
|
||||
extern const NSInteger XCDYouTubeKitLumberjackContext;
|
||||
|
||||
/**
|
||||
* The log levels, closely mirroring the log levels of CocoaLumberjack.
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, XCDLogLevel) {
|
||||
/**
|
||||
* Used when an error is produced, e.g. when a `<XCDYouTubeVideoOperation>` finishes with an error.
|
||||
*/
|
||||
XCDLogLevelError = 0,
|
||||
|
||||
/**
|
||||
* Used on unusual conditions that may eventually lead to an error.
|
||||
*/
|
||||
XCDLogLevelWarning = 1,
|
||||
|
||||
/**
|
||||
* Used when logging normal operational information, e.g. when a `<XCDYouTubeVideoOperation>` starts, is cancelled or finishes.
|
||||
*/
|
||||
XCDLogLevelInfo = 2,
|
||||
|
||||
/**
|
||||
* Used throughout a `<XCDYouTubeVideoOperation>` for debugging purpose, e.g. for HTTP requests.
|
||||
*/
|
||||
XCDLogLevelDebug = 3,
|
||||
|
||||
/**
|
||||
* Used to report large amount of information, e.g. full HTTP responses.
|
||||
*/
|
||||
XCDLogLevelVerbose = 4,
|
||||
};
|
||||
|
||||
/**
|
||||
* You can use the `XCDYouTubeLogger` class to configure how the XCDYouTubeKit framework emits logs.
|
||||
*
|
||||
* By default, logs are emitted through CocoaLumberjack if it is available, i.e. if the `DDLog` class is found at runtime.
|
||||
* The [context][1] used for CocoaLumberjack is the `XCDYouTubeKitLumberjackContext` constant whose value is `(NSInteger)0xced70676`.
|
||||
*
|
||||
* If CocoaLumberjack is not available, logs are emitted with `NSLog`, prefixed with the `[XCDYouTubeKit]` string.
|
||||
*
|
||||
* ## Controlling log levels
|
||||
*
|
||||
* If you are using CocoaLumberjack, you are responsible for controlling the log levels with the CocoaLumberjack APIs.
|
||||
*
|
||||
* If you are not using CocoaLumberjack, you can control the log levels with the `XCDYouTubeKitLogLevel` environment variable. See also the `<XCDLogLevel>` enum.
|
||||
*
|
||||
* Level | Value | Mask
|
||||
* --------|-------|------
|
||||
* Error | 0 | 0x01
|
||||
* Warning | 1 | 0x02
|
||||
* Info | 2 | 0x04
|
||||
* Debug | 3 | 0x08
|
||||
* Verbose | 4 | 0x10
|
||||
*
|
||||
* Use the corresponding bitmask to combine levels. For example, if you want to log *error*, *warning* and *info* levels, set the `XCDYouTubeKitLogLevel` environment variable to `0x7` (0x01 | 0x02 | 0x04).
|
||||
*
|
||||
* If you do not set the `XCDYouTubeKitLogLevel` environment variable, only warning and error levels are logged.
|
||||
*
|
||||
* [1]: https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/CustomContext.md
|
||||
*/
|
||||
@interface XCDYouTubeLogger : NSObject
|
||||
|
||||
/**
|
||||
* -------------------
|
||||
* @name Custom Logger
|
||||
* -------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* If you prefer not to use CocoaLumberjack and want something more advanced than the default `NSLog` implementation, you can use this method to write your own logger.
|
||||
*
|
||||
* @param logHandler The block called when a log is emitted by the XCDYouTubeKit framework. If you set the log handler to nil, logging will be completely disabled.
|
||||
*
|
||||
* @discussion Here is a description of the log handler parameters.
|
||||
*
|
||||
* - The `message` parameter is a block returning a string that you must call to evaluate the log message.
|
||||
* - The `level` parameter is the log level of the message, see `<XCDLogLevel>`.
|
||||
* - The `file` parameter is the full path of the file, captured with the `__FILE__` macro where the log is emitted.
|
||||
* - The `function` parameter is the function name, captured with the `__PRETTY_FUNCTION__` macro where the log is emitted.
|
||||
* - The `line` parameter is the line number, captured with the `__LINE__` macro where the log is emitted.
|
||||
*
|
||||
* Here is how you could implement a custom log handler with [NSLogger](https://github.com/fpillet/NSLogger):
|
||||
*
|
||||
* ```
|
||||
* [XCDYouTubeLogger setLogHandler:^(NSString * (^message)(void), XCDLogLevel level, const char *file, const char *function, NSUInteger line) {
|
||||
* LogMessageRawF(file, (int)line, function, @"XCDYouTubeKit", (int)level, message());
|
||||
* }];
|
||||
* ```
|
||||
*/
|
||||
+ (void) setLogHandler:(void (^)(NSString * (^message)(void), XCDLogLevel level, const char *file, const char *function, NSUInteger line))logHandler;
|
||||
|
||||
@end
|
||||
63
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeLogger.m
generated
Normal file
63
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeLogger.m
generated
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
//
|
||||
// Copyright (c) 2013-2016 Cédric Luthi. All rights reserved.
|
||||
//
|
||||
|
||||
#import "XCDYouTubeLogger.h"
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
const NSInteger XCDYouTubeKitLumberjackContext = (NSInteger)0xced70676;
|
||||
|
||||
@protocol XCDYouTubeLogger_DDLog
|
||||
// Copied from CocoaLumberjack's DDLog interface
|
||||
+ (void) log:(BOOL)asynchronous message:(NSString *)message level:(NSUInteger)level flag:(NSUInteger)flag context:(NSInteger)context file:(const char *)file function:(const char *)function line:(NSUInteger)line tag:(id)tag;
|
||||
@end
|
||||
|
||||
static Class DDLogClass = Nil;
|
||||
|
||||
static void (^const CocoaLumberjackLogHandler)(NSString * (^)(void), XCDLogLevel, const char *, const char *, NSUInteger) = ^(NSString *(^message)(void), XCDLogLevel level, const char *file, const char *function, NSUInteger line)
|
||||
{
|
||||
// The `XCDLogLevel` enum was carefully crafted to match the `DDLogFlag` options from DDLog.h
|
||||
[DDLogClass log:YES message:message() level:NSUIntegerMax flag:(1 << level) context:XCDYouTubeKitLumberjackContext file:file function:function line:line tag:nil];
|
||||
};
|
||||
|
||||
static void (^LogHandler)(NSString * (^)(void), XCDLogLevel, const char *, const char *, NSUInteger) = ^(NSString *(^message)(void), XCDLogLevel level, const char *file, const char *function, NSUInteger line)
|
||||
{
|
||||
char *logLevelString = getenv("XCDYouTubeKitLogLevel");
|
||||
NSUInteger logLevelMask = logLevelString ? strtoul(logLevelString, NULL, 0) : (1 << XCDLogLevelError) | (1 << XCDLogLevelWarning);
|
||||
if ((1 << level) & logLevelMask)
|
||||
NSLog(@"[XCDYouTubeKit] %@", message());
|
||||
};
|
||||
|
||||
@implementation XCDYouTubeLogger
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
static dispatch_once_t once;
|
||||
dispatch_once(&once, ^{
|
||||
DDLogClass = objc_lookUpClass("DDLog");
|
||||
if (DDLogClass)
|
||||
{
|
||||
const SEL logSeletor = @selector(log:message:level:flag:context:file:function:line:tag:);
|
||||
const char *typeEncoding = method_getTypeEncoding((Method)class_getClassMethod(DDLogClass, logSeletor));
|
||||
const char *expectedTypeEncoding = protocol_getMethodDescription(@protocol(XCDYouTubeLogger_DDLog), logSeletor, /* isRequiredMethod: */ YES, /* isInstanceMethod: */ NO).types;
|
||||
if (typeEncoding && expectedTypeEncoding && strcmp(typeEncoding, expectedTypeEncoding) == 0)
|
||||
LogHandler = CocoaLumberjackLogHandler;
|
||||
else
|
||||
NSLog(@"[XCDYouTubeKit] Incompatible CocoaLumberjack version. Expected \"%@\", got \"%@\".", expectedTypeEncoding ? @(expectedTypeEncoding) : @"", typeEncoding ? @(typeEncoding) : @"");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+ (void) setLogHandler:(void (^)(NSString * (^message)(void), XCDLogLevel level, const char *file, const char *function, NSUInteger line))logHandler
|
||||
{
|
||||
LogHandler = logHandler;
|
||||
}
|
||||
|
||||
+ (void) logMessage:(NSString * (^)(void))message level:(XCDLogLevel)level file:(const char *)file function:(const char *)function line:(NSUInteger)line
|
||||
{
|
||||
if (LogHandler)
|
||||
LogHandler(message, level, file, function, line);
|
||||
}
|
||||
|
||||
@end
|
||||
23
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeOperation.h
generated
Normal file
23
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeOperation.h
generated
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
//
|
||||
// Copyright (c) 2013-2016 Cédric Luthi. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/**
|
||||
* The `XCDYouTubeOperation` protocol is adopted by opaque objects returned by the `<-[XCDYouTubeClient getVideoWithIdentifier:completionHandler:]>` method.
|
||||
*/
|
||||
@protocol XCDYouTubeOperation <NSObject>
|
||||
|
||||
/**
|
||||
* ---------------
|
||||
* @name Canceling
|
||||
* ---------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Cancels the operation. If the operation is already finished, does nothing.
|
||||
*/
|
||||
- (void) cancel;
|
||||
|
||||
@end
|
||||
14
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubePlayerScript.h
generated
Normal file
14
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubePlayerScript.h
generated
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
//
|
||||
// Copyright (c) 2013-2016 Cédric Luthi. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
__attribute__((visibility("hidden")))
|
||||
@interface XCDYouTubePlayerScript : NSObject
|
||||
|
||||
- (instancetype) initWithString:(NSString *)string;
|
||||
|
||||
- (NSString *) unscrambleSignature:(NSString *)scrambledSignature;
|
||||
|
||||
@end
|
||||
125
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubePlayerScript.m
generated
Normal file
125
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubePlayerScript.m
generated
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
//
|
||||
// Copyright (c) 2013-2016 Cédric Luthi. All rights reserved.
|
||||
//
|
||||
|
||||
#import "XCDYouTubePlayerScript.h"
|
||||
|
||||
#import <JavaScriptCore/JavaScriptCore.h>
|
||||
|
||||
#import "XCDYouTubeLogger+Private.h"
|
||||
|
||||
@interface XCDYouTubePlayerScript ()
|
||||
@property (nonatomic, strong) JSContext *context;
|
||||
@property (nonatomic, strong) JSValue *signatureFunction;
|
||||
@end
|
||||
|
||||
@implementation XCDYouTubePlayerScript
|
||||
|
||||
- (instancetype) initWithString:(NSString *)string
|
||||
{
|
||||
if (!(self = [super init]))
|
||||
return nil; // LCOV_EXCL_LINE
|
||||
|
||||
_context = [JSContext new];
|
||||
_context.exceptionHandler = ^(JSContext *context, JSValue *exception) {
|
||||
XCDYouTubeLogWarning(@"JavaScript exception: %@", exception);
|
||||
};
|
||||
|
||||
NSDictionary *environment = @{
|
||||
@"document": @{
|
||||
@"documentElement": @{}
|
||||
},
|
||||
@"location": @{
|
||||
@"hash": @""
|
||||
},
|
||||
@"navigator": @{
|
||||
@"userAgent": @""
|
||||
},
|
||||
};
|
||||
_context[@"window"] = @{};
|
||||
for (NSString *propertyName in environment)
|
||||
{
|
||||
JSValue *value = [JSValue valueWithObject:environment[propertyName] inContext:_context];
|
||||
_context[propertyName] = value;
|
||||
_context[@"window"][propertyName] = value;
|
||||
}
|
||||
|
||||
NSString *matchMediaJsFunction = @"var matchMediaWindow=this;matchMediaWindow.matchMedia=function(a){return false;};";
|
||||
NSString *script = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
script=[matchMediaJsFunction stringByAppendingString:(script)];
|
||||
[_context evaluateScript:script];
|
||||
|
||||
NSRegularExpression *anonymousFunctionRegularExpression = [NSRegularExpression regularExpressionWithPattern:@"\\(function\\(([^)]*)\\)\\{(.*)\\}\\)\\(([^)]*)\\)" options:NSRegularExpressionDotMatchesLineSeparators error:NULL];
|
||||
NSTextCheckingResult *anonymousFunctionResult = [anonymousFunctionRegularExpression firstMatchInString:script options:(NSMatchingOptions)0 range:NSMakeRange(0, script.length)];
|
||||
if (anonymousFunctionResult.numberOfRanges > 3)
|
||||
{
|
||||
NSArray *parameters = [[script substringWithRange:[anonymousFunctionResult rangeAtIndex:1]] componentsSeparatedByString:@","];
|
||||
NSArray *arguments = [[script substringWithRange:[anonymousFunctionResult rangeAtIndex:3]] componentsSeparatedByString:@","];
|
||||
if (parameters.count == arguments.count)
|
||||
{
|
||||
for (NSUInteger i = 0; i < parameters.count; i++)
|
||||
{
|
||||
_context[parameters[i]] = _context[arguments[i]];
|
||||
}
|
||||
}
|
||||
NSString *anonymousFunctionBody = [script substringWithRange:[anonymousFunctionResult rangeAtIndex:2]];
|
||||
[_context evaluateScript:anonymousFunctionBody];
|
||||
}
|
||||
else
|
||||
{
|
||||
XCDYouTubeLogWarning(@"Unexpected player script (no anonymous function found)");
|
||||
}
|
||||
|
||||
//See list of regex patterns here https://github.com/rg3/youtube-dl/blob/master/youtube_dl/extractor/youtube.py#L1179
|
||||
NSArray<NSString *>*patterns = @[@"\\.sig\\|\\|([a-zA-Z0-9$]+)\\(",
|
||||
@"[\"']signature[\"']\\s*,\\s*([^\\(]+)",
|
||||
@"yt\\.akamaized\\.net/\\)\\s*\\|\\|\\s*.*?\\s*c\\s*&&d.set\\([^,]+\\s*,\\s*([a-zA-Z0-9$]+)",
|
||||
@"\\bcs*&&\\s*d\\.set\\([^,]+\\s*,\\s*([a-zA-Z0-9$]+)\\C",
|
||||
@"\\bc\\s*&&\\s*d\\.set\\([^,]+\\s*,\\s*\\([^)]*\\)\\s*\\(\\s*([a-zA-Z0-9$]+)\\("
|
||||
];
|
||||
|
||||
NSMutableArray<NSRegularExpression *>*validRegularExpressions = [NSMutableArray new];
|
||||
|
||||
for (NSString *pattern in patterns) {
|
||||
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:NULL];
|
||||
if (regex != nil)
|
||||
{
|
||||
[validRegularExpressions addObject:regex];
|
||||
}
|
||||
}
|
||||
|
||||
for (NSRegularExpression *regularExpression in validRegularExpressions) {
|
||||
|
||||
NSArray<NSTextCheckingResult *> *regexResults = [regularExpression matchesInString:script options:(NSMatchingOptions)0 range:NSMakeRange(0, script.length)];
|
||||
|
||||
for (NSTextCheckingResult *signatureResult in regexResults)
|
||||
{
|
||||
NSString *signatureFunctionName = signatureResult.numberOfRanges > 1 ? [script substringWithRange:[signatureResult rangeAtIndex:1]] : nil;
|
||||
if (!signatureFunctionName)
|
||||
continue;
|
||||
|
||||
JSValue *signatureFunction = self.context[signatureFunctionName];
|
||||
if (signatureFunction.isObject)
|
||||
{
|
||||
_signatureFunction = signatureFunction;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!_signatureFunction)
|
||||
XCDYouTubeLogWarning(@"No signature function in player script");
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *) unscrambleSignature:(NSString *)scrambledSignature
|
||||
{
|
||||
if (!self.signatureFunction || !scrambledSignature)
|
||||
return nil;
|
||||
|
||||
JSValue *unscrambledSignature = [self.signatureFunction callWithArguments:@[ scrambledSignature ]];
|
||||
return [unscrambledSignature isString] ? [unscrambledSignature toString] : nil;
|
||||
}
|
||||
|
||||
@end
|
||||
24
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideo+Private.h
generated
Normal file
24
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideo+Private.h
generated
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// Copyright (c) 2013-2016 Cédric Luthi. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCDYouTubeKit/XCDYouTubeVideo.h>
|
||||
|
||||
#import "XCDYouTubePlayerScript.h"
|
||||
|
||||
#define XCDYouTubeErrorUseCipherSignature -1000
|
||||
|
||||
extern NSString *const XCDYouTubeNoStreamVideoUserInfoKey;
|
||||
|
||||
extern NSDictionary *XCDDictionaryWithQueryString(NSString *string);
|
||||
extern NSString *XCDQueryStringWithDictionary(NSDictionary *dictionary);
|
||||
extern NSArray *XCDCaptionArrayWithString(NSString *string);
|
||||
|
||||
@interface XCDYouTubeVideo ()
|
||||
|
||||
- (instancetype) initWithIdentifier:(NSString *)identifier info:(NSDictionary *)info playerScript:(XCDYouTubePlayerScript *)playerScript response:(NSURLResponse *)response error:(NSError **)error;
|
||||
|
||||
- (void) mergeVideo:(XCDYouTubeVideo *)video;
|
||||
- (void) mergeDashManifestStreamURLs:(NSDictionary *)dashManifestStreamURLs;
|
||||
|
||||
@end
|
||||
147
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideo.h
generated
Normal file
147
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideo.h
generated
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
//
|
||||
// Copyright (c) 2013-2016 Cédric Luthi. All rights reserved.
|
||||
//
|
||||
|
||||
#if !__has_feature(nullability)
|
||||
#define NS_ASSUME_NONNULL_BEGIN
|
||||
#define NS_ASSUME_NONNULL_END
|
||||
#define nullable
|
||||
#endif
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* The quality of YouTube videos. These values are used as keys in the `<[XCDYouTubeVideo streamURLs]>` property.
|
||||
*
|
||||
* The constant numbers are the YouTube [itag](https://en.wikipedia.org/wiki/Talk:YouTube/Archive_22#Moved_from_YouTube#Quality_formats) values.
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, XCDYouTubeVideoQuality) {
|
||||
/**
|
||||
* Video: 240p MPEG-4 Visual | 0.175 Mbit/s
|
||||
* Audio: AAC | 36 kbit/s
|
||||
*/
|
||||
XCDYouTubeVideoQualitySmall240 = 36,
|
||||
|
||||
/**
|
||||
* Video: 360p H.264 | 0.5 Mbit/s
|
||||
* Audio: AAC | 96 kbit/s
|
||||
*/
|
||||
XCDYouTubeVideoQualityMedium360 = 18,
|
||||
|
||||
/**
|
||||
* Video: 720p H.264 | 2-3 Mbit/s
|
||||
* Audio: AAC | 192 kbit/s
|
||||
*/
|
||||
XCDYouTubeVideoQualityHD720 = 22,
|
||||
|
||||
/**
|
||||
* Video: 1080p H.264 | 3–5.9 Mbit/s
|
||||
* Audio: AAC | 192 kbit/s
|
||||
*
|
||||
* @deprecated YouTube has removed 1080p mp4 videos.
|
||||
*/
|
||||
XCDYouTubeVideoQualityHD1080 DEPRECATED_MSG_ATTRIBUTE("YouTube has removed 1080p mp4 videos.") = 37,
|
||||
};
|
||||
|
||||
/**
|
||||
* Used as a key in the `streamURLs` property of the `XCDYouTubeVideo` class for live videos.
|
||||
*/
|
||||
extern NSString *const XCDYouTubeVideoQualityHTTPLiveStreaming;
|
||||
|
||||
/**
|
||||
* Represents a YouTube video. Use the `<-[XCDYouTubeClient getVideoWithIdentifier:completionHandler:]>` method to obtain a `XCDYouTubeVideo` object.
|
||||
*/
|
||||
@interface XCDYouTubeVideo : NSObject <NSCopying>
|
||||
|
||||
/**
|
||||
* --------------------------------
|
||||
* @name Accessing video properties
|
||||
* --------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* The 11 characters YouTube video identifier.
|
||||
*/
|
||||
@property (nonatomic, readonly) NSString *identifier;
|
||||
/**
|
||||
* The title of the video.
|
||||
*/
|
||||
@property (nonatomic, readonly) NSString *title;
|
||||
/**
|
||||
* The duration of the video in seconds.
|
||||
*/
|
||||
@property (nonatomic, readonly) NSTimeInterval duration;
|
||||
/**
|
||||
* A thumbnail URL for an image of small size, i.e. 120×90. May be nil.
|
||||
*/
|
||||
@property (nonatomic, readonly, nullable) NSURL *thumbnailURL;
|
||||
/**
|
||||
* A thumbnail URL for an image of small size, i.e. 120×90. May be nil.
|
||||
*/
|
||||
@property (nonatomic, readonly, nullable) NSURL *smallThumbnailURL DEPRECATED_MSG_ATTRIBUTE("Renamed. Use `thumbnailURL` instead.");
|
||||
/**
|
||||
* A thumbnail URL for an image of medium size, i.e. 320×180, 480×360 or 640×480. May be nil.
|
||||
*/
|
||||
@property (nonatomic, readonly, nullable) NSURL *mediumThumbnailURL DEPRECATED_MSG_ATTRIBUTE("No longer available. Use `thumbnailURL` instead.");
|
||||
/**
|
||||
* A thumbnail URL for an image of large size, i.e. 1'280×720 or 1'980×1'080. May be nil.
|
||||
*/
|
||||
@property (nonatomic, readonly, nullable) NSURL *largeThumbnailURL DEPRECATED_MSG_ATTRIBUTE("No longer available. Use `thumbnailURL` instead.");
|
||||
|
||||
/**
|
||||
* A dictionary of video stream URLs.
|
||||
*
|
||||
* The keys are the YouTube [itag](https://en.wikipedia.org/wiki/YouTube#Quality_and_formats) values as `NSNumber` objects. The values are the video URLs as `NSURL` objects. There is also the special `XCDYouTubeVideoQualityHTTPLiveStreaming` key for live videos.
|
||||
*
|
||||
* You should not store the URLs for later use since they have a limited lifetime and are bound to an IP address.
|
||||
*
|
||||
* @see XCDYouTubeVideoQuality
|
||||
* @see expirationDate
|
||||
*/
|
||||
#if __has_feature(objc_generics)
|
||||
@property (nonatomic, readonly) NSDictionary<id, NSURL *> *streamURLs;
|
||||
#else
|
||||
@property (nonatomic, readonly) NSDictionary *streamURLs;
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
* A dictionary of caption URLs (XML).
|
||||
*
|
||||
* The keys are the [language codes](https://www.loc.gov/standards/iso639-2/php/code_list.php) values as `NSString` objects. The values are the caption URLs as `NSURL` objects.
|
||||
*
|
||||
* You should not store the URLs for later use since they have a limited lifetime.
|
||||
*/
|
||||
#if __has_feature(objc_generics)
|
||||
@property (nonatomic, readonly, nullable) NSDictionary<id, NSURL *> *captionURLs;
|
||||
#else
|
||||
@property (nonatomic, readonly, nullable) NSDictionary *captionURLs;
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
* A dictionary of auto generated caption URLs (XML).
|
||||
*
|
||||
* The keys are the [language codes](https://www.loc.gov/standards/iso639-2/php/code_list.php) values as `NSString` objects. The values are the caption URLs as `NSURL` objects. These URLs are the ones that were automatically generated by YouTube.
|
||||
*
|
||||
* You should not store the URLs for later use since they have a limited lifetime.
|
||||
*/
|
||||
|
||||
#if __has_feature(objc_generics)
|
||||
@property (nonatomic, readonly, nullable) NSDictionary<id, NSURL *> *autoGeneratedCaptionURLs;
|
||||
#else
|
||||
@property (nonatomic, readonly, nullable) NSDictionary *autoGeneratedCaptionURLs;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The expiration date of the video.
|
||||
*
|
||||
* After this date, the stream URLs will not be playable. May be nil if it can not be determined, for example in live videos.
|
||||
*/
|
||||
@property (nonatomic, readonly, nullable) NSDate *expirationDate;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
319
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideo.m
generated
Normal file
319
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideo.m
generated
Normal file
|
|
@ -0,0 +1,319 @@
|
|||
//
|
||||
// Copyright (c) 2013-2016 Cédric Luthi. All rights reserved.
|
||||
//
|
||||
|
||||
#import "XCDYouTubeVideo+Private.h"
|
||||
|
||||
#import "XCDYouTubeError.h"
|
||||
#import "XCDYouTubeLogger+Private.h"
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
NSString *const XCDYouTubeVideoErrorDomain = @"XCDYouTubeVideoErrorDomain";
|
||||
NSString *const XCDYouTubeAllowedCountriesUserInfoKey = @"AllowedCountries";
|
||||
NSString *const XCDYouTubeNoStreamVideoUserInfoKey = @"NoStreamVideo";
|
||||
NSString *const XCDYouTubeVideoQualityHTTPLiveStreaming = @"HTTPLiveStreaming";
|
||||
|
||||
NSArray <NSDictionary *> *XCDCaptionArrayWithString(NSString *string)
|
||||
{
|
||||
NSError *error = nil;
|
||||
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
|
||||
if (!data) { return nil; }
|
||||
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
|
||||
|
||||
if (error) { return nil; }
|
||||
|
||||
NSDictionary *captions = JSON[@"captions"];
|
||||
NSDictionary *playerCaptionsTracklistRenderer = captions[@"playerCaptionsTracklistRenderer"];
|
||||
NSArray *captionTracks = playerCaptionsTracklistRenderer[@"captionTracks"];
|
||||
|
||||
if (captionTracks.count == 0 || captionTracks == nil) { return nil; }
|
||||
return captionTracks;
|
||||
}
|
||||
|
||||
NSDictionary *XCDDictionaryWithQueryString(NSString *string)
|
||||
{
|
||||
NSMutableDictionary *dictionary = [NSMutableDictionary new];
|
||||
NSArray *fields = [string componentsSeparatedByString:@"&"];
|
||||
for (NSString *field in fields)
|
||||
{
|
||||
NSArray *pair = [field componentsSeparatedByString:@"="];
|
||||
if (pair.count == 2)
|
||||
{
|
||||
NSString *key = pair[0];
|
||||
NSString *value = [(NSString *)pair[1] stringByRemovingPercentEncoding];
|
||||
value = [value stringByReplacingOccurrencesOfString:@"+" withString:@" "];
|
||||
if (dictionary[key] && ![(NSObject *)dictionary[key] isEqual:value])
|
||||
{
|
||||
XCDYouTubeLogWarning(@"Using XCDDictionaryWithQueryString is inappropriate because the query string has multiple values for the key '%@'\n"
|
||||
@"Query: %@\n"
|
||||
@"Discarded value: %@", key, string, dictionary[key]);
|
||||
}
|
||||
dictionary[key] = value;
|
||||
}
|
||||
}
|
||||
return [dictionary copy];
|
||||
}
|
||||
|
||||
NSString *XCDQueryStringWithDictionary(NSDictionary *dictionary)
|
||||
{
|
||||
NSArray *keys = [dictionary.allKeys filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
|
||||
return [(NSObject *)evaluatedObject isKindOfClass:[NSString class]];
|
||||
}]];
|
||||
|
||||
NSMutableString *query = [NSMutableString new];
|
||||
for (NSString *key in [keys sortedArrayUsingSelector:@selector(compare:)])
|
||||
{
|
||||
if (query.length > 0)
|
||||
[query appendString:@"&"];
|
||||
|
||||
[query appendFormat:@"%@=%@", key, [(NSObject *)dictionary[key] description]];
|
||||
}
|
||||
|
||||
return [query stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
|
||||
}
|
||||
|
||||
static NSString *SortedDictionaryDescription(NSDictionary *dictionary)
|
||||
{
|
||||
NSArray *sortedKeys = [dictionary.allKeys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
|
||||
return [[(NSObject *)obj1 description] compare:[(NSObject *) obj2 description] options:NSNumericSearch];
|
||||
}];
|
||||
|
||||
NSMutableString *description = [[NSMutableString alloc] initWithString:@"{\n"];
|
||||
for (id key in sortedKeys)
|
||||
{
|
||||
[description appendFormat:@"\t%@ \u2192 %@\n", key, dictionary[key]];
|
||||
}
|
||||
[description appendString:@"}"];
|
||||
|
||||
return [description copy];
|
||||
}
|
||||
|
||||
static NSURL * URLBySettingParameter(NSURL *URL, NSString *key, NSString *percentEncodedValue)
|
||||
{
|
||||
NSString *pattern = [NSString stringWithFormat:@"((?:^|&)%@=)[^&]*", key];
|
||||
NSString *template = [NSString stringWithFormat:@"$1%@", percentEncodedValue];
|
||||
NSURLComponents *components = [NSURLComponents componentsWithURL:URL resolvingAgainstBaseURL:NO];
|
||||
NSRegularExpression *regularExpression = [NSRegularExpression regularExpressionWithPattern:pattern options:(NSRegularExpressionOptions)0 error:NULL];
|
||||
NSMutableString *percentEncodedQuery = [components.percentEncodedQuery ?: @"" mutableCopy];
|
||||
NSUInteger numberOfMatches = [regularExpression replaceMatchesInString:percentEncodedQuery options:(NSMatchingOptions)0 range:NSMakeRange(0, percentEncodedQuery.length) withTemplate:template];
|
||||
if (numberOfMatches == 0)
|
||||
[percentEncodedQuery appendFormat:@"%@%@=%@", percentEncodedQuery.length > 0 ? @"&" : @"", key, percentEncodedValue];
|
||||
components.percentEncodedQuery = percentEncodedQuery;
|
||||
return components.URL;
|
||||
}
|
||||
|
||||
@implementation XCDYouTubeVideo
|
||||
|
||||
static NSDate * ExpirationDate(NSURL *streamURL)
|
||||
{
|
||||
NSDictionary *query = XCDDictionaryWithQueryString(streamURL.query);
|
||||
NSTimeInterval expire = [(NSString *)query[@"expire"] doubleValue];
|
||||
return expire > 0 ? [NSDate dateWithTimeIntervalSince1970:expire] : nil;
|
||||
}
|
||||
|
||||
- (instancetype) initWithIdentifier:(NSString *)identifier info:(NSDictionary *)info playerScript:(XCDYouTubePlayerScript *)playerScript response:(NSURLResponse *)response error:(NSError * __autoreleasing *)error
|
||||
{
|
||||
if (!(self = [super init]))
|
||||
return nil; // LCOV_EXCL_LINE
|
||||
|
||||
_identifier = identifier;
|
||||
|
||||
NSString *streamMap = info[@"url_encoded_fmt_stream_map"];
|
||||
NSString *captionsMap = info[@"player_response"];
|
||||
NSString *httpLiveStream = info[@"hlsvp"];
|
||||
NSString *adaptiveFormats = info[@"adaptive_fmts"];
|
||||
|
||||
NSMutableDictionary *userInfo = response.URL ? [@{ NSURLErrorKey: (id)response.URL } mutableCopy] : [NSMutableDictionary new];
|
||||
|
||||
if (streamMap.length > 0 || httpLiveStream.length > 0)
|
||||
{
|
||||
NSMutableArray *streamQueries = [[streamMap componentsSeparatedByString:@","] mutableCopy];
|
||||
[streamQueries addObjectsFromArray:[adaptiveFormats componentsSeparatedByString:@","]];
|
||||
|
||||
NSString *title = info[@"title"] ?: @"";
|
||||
_title = title;
|
||||
_duration = [(NSString *)info[@"length_seconds"] doubleValue];
|
||||
|
||||
NSString *thumbnail = info[@"thumbnail_url"] ?: info[@"iurl"];
|
||||
_thumbnailURL = thumbnail ? [NSURL URLWithString:thumbnail] : nil;
|
||||
|
||||
NSMutableDictionary *streamURLs = [NSMutableDictionary new];
|
||||
|
||||
if (httpLiveStream)
|
||||
streamURLs[XCDYouTubeVideoQualityHTTPLiveStreaming] = [NSURL URLWithString:httpLiveStream];
|
||||
|
||||
NSMutableDictionary *captionURLs = [NSMutableDictionary new];
|
||||
NSMutableDictionary *autoGeneratedCaptionURLs = [NSMutableDictionary new];
|
||||
|
||||
for (NSDictionary *caption in XCDCaptionArrayWithString(captionsMap))
|
||||
{
|
||||
NSString *languageCode = caption[@"languageCode"];
|
||||
NSString *captionVersion = caption[@"vssId"];
|
||||
NSString *captionURLString = caption[@"baseUrl"];
|
||||
if (!captionURLString)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
NSURL *captionURL = [NSURL URLWithString:captionURLString];
|
||||
if (captionURL && languageCode)
|
||||
|
||||
{
|
||||
if ([languageCode isEqualToString:@"und"])
|
||||
{
|
||||
//Skip because this is a special code than is used to indicate that the lanauage code is undetermined.
|
||||
continue;
|
||||
}
|
||||
if([captionVersion hasPrefix:@"a"])
|
||||
{
|
||||
//Indicates the caption was auto generated
|
||||
autoGeneratedCaptionURLs[languageCode] = captionURL;
|
||||
} else
|
||||
{
|
||||
captionURLs[languageCode] = captionURL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (captionURLs.count > 0)
|
||||
{
|
||||
_captionURLs = [captionURLs copy];
|
||||
}
|
||||
|
||||
if (autoGeneratedCaptionURLs.count > 0)
|
||||
{
|
||||
_autoGeneratedCaptionURLs = [autoGeneratedCaptionURLs copy];
|
||||
}
|
||||
|
||||
for (NSString *streamQuery in streamQueries)
|
||||
{
|
||||
NSDictionary *stream = XCDDictionaryWithQueryString(streamQuery);
|
||||
|
||||
NSString *scrambledSignature = stream[@"s"];
|
||||
if (scrambledSignature && !playerScript)
|
||||
{
|
||||
userInfo[XCDYouTubeNoStreamVideoUserInfoKey] = self;
|
||||
if (error)
|
||||
*error = [NSError errorWithDomain:XCDYouTubeVideoErrorDomain code:XCDYouTubeErrorUseCipherSignature userInfo:userInfo];
|
||||
|
||||
return nil;
|
||||
}
|
||||
NSString *signature = [playerScript unscrambleSignature:scrambledSignature];
|
||||
if (playerScript && scrambledSignature && !signature)
|
||||
continue;
|
||||
|
||||
NSString *urlString = stream[@"url"];
|
||||
NSString *itag = stream[@"itag"];
|
||||
if (urlString && itag)
|
||||
{
|
||||
NSURL *streamURL = [NSURL URLWithString:urlString];
|
||||
if (!_expirationDate)
|
||||
_expirationDate = ExpirationDate(streamURL);
|
||||
|
||||
if (signature)
|
||||
{
|
||||
NSString *escapedSignature = [signature stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
|
||||
streamURL = URLBySettingParameter(streamURL, @"signature", escapedSignature);
|
||||
}
|
||||
|
||||
streamURLs[@(itag.integerValue)] = URLBySettingParameter(streamURL, @"ratebypass", @"yes");
|
||||
}
|
||||
}
|
||||
_streamURLs = [streamURLs copy];
|
||||
|
||||
if (_streamURLs.count == 0)
|
||||
{
|
||||
if (error)
|
||||
*error = [NSError errorWithDomain:XCDYouTubeVideoErrorDomain code:XCDYouTubeErrorNoStreamAvailable userInfo:userInfo];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
NSString *reason = info[@"reason"];
|
||||
if (reason)
|
||||
{
|
||||
reason = [reason stringByReplacingOccurrencesOfString:@"<br\\s*/?>" withString:@" " options:NSRegularExpressionSearch range:NSMakeRange(0, reason.length)];
|
||||
reason = [reason stringByReplacingOccurrencesOfString:@"\n" withString:@" " options:(NSStringCompareOptions)0 range:NSMakeRange(0, reason.length)];
|
||||
NSRange range;
|
||||
while ((range = [reason rangeOfString:@"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound)
|
||||
reason = [reason stringByReplacingCharactersInRange:range withString:@""];
|
||||
|
||||
userInfo[NSLocalizedDescriptionKey] = reason;
|
||||
}
|
||||
|
||||
NSString *errorcode = info[@"errorcode"];
|
||||
NSInteger code = errorcode ? errorcode.integerValue : XCDYouTubeErrorNoStreamAvailable;
|
||||
*error = [NSError errorWithDomain:XCDYouTubeVideoErrorDomain code:code userInfo:userInfo];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) mergeVideo:(XCDYouTubeVideo *)video
|
||||
{
|
||||
unsigned int count;
|
||||
objc_property_t *properties = class_copyPropertyList(self.class, &count);
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
NSString *propertyName = @(property_getName(properties[i]));
|
||||
if (![self valueForKey:propertyName])
|
||||
[self setValue:[video valueForKey:propertyName] forKeyPath:propertyName];
|
||||
}
|
||||
free(properties);
|
||||
}
|
||||
|
||||
- (void) mergeDashManifestStreamURLs:(NSDictionary *)dashManifestStreamURLs {
|
||||
|
||||
NSMutableDictionary *approvedStreams = [NSMutableDictionary new];
|
||||
|
||||
for (NSString *itag in dashManifestStreamURLs) {
|
||||
if (self.streamURLs[itag] == nil)
|
||||
approvedStreams[itag] = dashManifestStreamURLs[itag];
|
||||
}
|
||||
|
||||
NSMutableDictionary *newStreams = [NSMutableDictionary dictionaryWithDictionary:self.streamURLs];
|
||||
[newStreams addEntriesFromDictionary:approvedStreams];
|
||||
[self setValue:newStreams.copy forKeyPath:NSStringFromSelector(@selector(streamURLs))];
|
||||
}
|
||||
|
||||
#pragma mark - NSObject
|
||||
|
||||
- (BOOL) isEqual:(id)object
|
||||
{
|
||||
return [(NSObject *)object isKindOfClass:[XCDYouTubeVideo class]] && [((XCDYouTubeVideo *)object).identifier isEqual:self.identifier];
|
||||
}
|
||||
|
||||
- (NSUInteger) hash
|
||||
{
|
||||
return self.identifier.hash;
|
||||
}
|
||||
|
||||
- (NSString *) description
|
||||
{
|
||||
return [NSString stringWithFormat:@"[%@] %@", self.identifier, self.title];
|
||||
}
|
||||
|
||||
- (NSString *) debugDescription
|
||||
{
|
||||
NSDateComponentsFormatter *dateComponentsFormatter = [NSDateComponentsFormatter new];
|
||||
dateComponentsFormatter.unitsStyle = NSDateComponentsFormatterUnitsStyleAbbreviated;
|
||||
NSString *duration = [dateComponentsFormatter stringFromTimeInterval:self.duration] ?: [NSString stringWithFormat:@"%@ seconds", @(self.duration)];
|
||||
NSString *thumbnailDescription = [NSString stringWithFormat:@"Thumbnail: %@", self.thumbnailURL];
|
||||
NSString *streamsDescription = SortedDictionaryDescription(self.streamURLs);
|
||||
return [NSString stringWithFormat:@"<%@: %p> %@\nDuration: %@\nExpiration date: %@\n%@\nStreams: %@", self.class, self, self.description, duration, self.expirationDate, thumbnailDescription, streamsDescription];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id) copyWithZone:(NSZone *)zone
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
74
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideoOperation.h
generated
Normal file
74
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideoOperation.h
generated
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
//
|
||||
// Copyright (c) 2013-2016 Cédric Luthi. All rights reserved.
|
||||
//
|
||||
|
||||
#if !__has_feature(nullability)
|
||||
#define NS_ASSUME_NONNULL_BEGIN
|
||||
#define NS_ASSUME_NONNULL_END
|
||||
#define nullable
|
||||
#endif
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <XCDYouTubeKit/XCDYouTubeOperation.h>
|
||||
#import <XCDYouTubeKit/XCDYouTubeVideo.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* XCDYouTubeVideoOperation is a subclass of `NSOperation` that connects to the YouTube API and parse the response.
|
||||
*
|
||||
* You should probably use the higher level class `<XCDYouTubeClient>`. Use this class only if you are very familiar with `NSOperation` and need to manage dependencies between operations.
|
||||
*/
|
||||
@interface XCDYouTubeVideoOperation : NSOperation <XCDYouTubeOperation>
|
||||
|
||||
/**
|
||||
* ------------------
|
||||
* @name Initializing
|
||||
* ------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initializes a video operation with the specified video identifier and language identifier.
|
||||
*
|
||||
* @param videoIdentifier A 11 characters YouTube video identifier.
|
||||
* @param languageIdentifier An [ISO 639-1 two-letter language code](http://www.loc.gov/standards/iso639-2/php/code_list.php) used for error localization. If you pass a nil language identifier then English (`en`) is used.
|
||||
*
|
||||
* @return An initialized `XCDYouTubeVideoOperation` object.
|
||||
*/
|
||||
- (instancetype) initWithVideoIdentifier:(NSString *)videoIdentifier languageIdentifier:(nullable NSString *)languageIdentifier;
|
||||
|
||||
|
||||
/**
|
||||
Initializes a video operation with the specified video identifier and language identifier and cookies.
|
||||
|
||||
@param videoIdentifier A 11 characters YouTube video identifier.
|
||||
@param languageIdentifier An [ISO 639-1 two-letter language code](http://www.loc.gov/standards/iso639-2/php/code_list.php) used for error localization. If you pass a nil language identifier then English (`en`) is used.
|
||||
@param cookies An array of `NSHTTPCookie` objects, can be nil. These cookies can be used for certain videos that require a login.
|
||||
|
||||
@return An initialized `XCDYouTubeVideoOperation` object.
|
||||
*/
|
||||
- (instancetype) initWithVideoIdentifier:(NSString *)videoIdentifier languageIdentifier:(nullable NSString *)languageIdentifier cookies:(nullable NSArray <NSHTTPCookie *>*)cookies NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/**
|
||||
* --------------------------------
|
||||
* @name Accessing operation result
|
||||
* --------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns an error of the `XCDYouTubeVideoErrorDomain` domain if the operation failed or nil if it succeeded.
|
||||
*
|
||||
* Returns nil if the operation is not yet finished or if it was canceled.
|
||||
*/
|
||||
@property (atomic, readonly, nullable) NSError *error;
|
||||
/**
|
||||
* Returns a video object if the operation succeeded or nil if it failed.
|
||||
*
|
||||
* Returns nil if the operation is not yet finished or if it was canceled.
|
||||
*/
|
||||
@property (atomic, readonly, nullable) XCDYouTubeVideo *video;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
410
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideoOperation.m
generated
Normal file
410
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideoOperation.m
generated
Normal file
|
|
@ -0,0 +1,410 @@
|
|||
//
|
||||
// Copyright (c) 2013-2016 Cédric Luthi. All rights reserved.
|
||||
//
|
||||
|
||||
#import "XCDYouTubeVideoOperation.h"
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#import "XCDYouTubeVideo+Private.h"
|
||||
#import "XCDYouTubeError.h"
|
||||
#import "XCDYouTubeVideoWebpage.h"
|
||||
#import "XCDYouTubeDashManifestXML.h"
|
||||
#import "XCDYouTubePlayerScript.h"
|
||||
#import "XCDYouTubeLogger+Private.h"
|
||||
|
||||
typedef NS_ENUM(NSUInteger, XCDYouTubeRequestType) {
|
||||
XCDYouTubeRequestTypeGetVideoInfo = 1,
|
||||
XCDYouTubeRequestTypeWatchPage,
|
||||
XCDYouTubeRequestTypeEmbedPage,
|
||||
XCDYouTubeRequestTypeJavaScriptPlayer,
|
||||
XCDYouTubeRequestTypeDashManifest,
|
||||
|
||||
};
|
||||
|
||||
@interface XCDYouTubeVideoOperation ()
|
||||
@property (atomic, copy, readonly) NSString *videoIdentifier;
|
||||
@property (atomic, copy, readonly) NSString *languageIdentifier;
|
||||
@property (atomic, strong, readonly) NSArray <NSHTTPCookie *> *cookies;
|
||||
|
||||
@property (atomic, assign) NSInteger requestCount;
|
||||
@property (atomic, assign) XCDYouTubeRequestType requestType;
|
||||
@property (atomic, strong) NSMutableArray *eventLabels;
|
||||
@property (atomic, strong) XCDYouTubeVideo *lastSuccessfulVideo;
|
||||
@property (atomic, readonly) NSURLSession *session;
|
||||
@property (atomic, strong) NSURLSessionDataTask *dataTask;
|
||||
|
||||
@property (atomic, assign) BOOL isExecuting;
|
||||
@property (atomic, assign) BOOL isFinished;
|
||||
@property (atomic, readonly) dispatch_semaphore_t operationStartSemaphore;
|
||||
|
||||
@property (atomic, strong) XCDYouTubeVideoWebpage *webpage;
|
||||
@property (atomic, strong) XCDYouTubeVideoWebpage *embedWebpage;
|
||||
@property (atomic, strong) XCDYouTubePlayerScript *playerScript;
|
||||
@property (atomic, strong) XCDYouTubeVideo *noStreamVideo;
|
||||
@property (atomic, strong) NSError *lastError;
|
||||
@property (atomic, strong) NSError *youTubeError; // Error actually coming from the YouTube API, i.e. explicit and localized error
|
||||
|
||||
@property (atomic, strong, readwrite) NSError *error;
|
||||
@property (atomic, strong, readwrite) XCDYouTubeVideo *video;
|
||||
@end
|
||||
|
||||
@implementation XCDYouTubeVideoOperation
|
||||
|
||||
static NSError *YouTubeError(NSError *error, NSSet *regionsAllowed, NSString *languageIdentifier)
|
||||
{
|
||||
if (error.code == XCDYouTubeErrorRestrictedPlayback && regionsAllowed.count > 0)
|
||||
{
|
||||
NSLocale *locale = [NSLocale localeWithLocaleIdentifier:languageIdentifier];
|
||||
NSMutableSet *allowedCountries = [NSMutableSet new];
|
||||
for (NSString *countryCode in regionsAllowed)
|
||||
{
|
||||
NSString *country = [locale displayNameForKey:NSLocaleCountryCode value:countryCode];
|
||||
[allowedCountries addObject:country ?: countryCode];
|
||||
}
|
||||
NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithDictionary:error.userInfo];
|
||||
userInfo[XCDYouTubeAllowedCountriesUserInfoKey] = [allowedCountries copy];
|
||||
return [NSError errorWithDomain:error.domain code:error.code userInfo:[userInfo copy]];
|
||||
}
|
||||
else
|
||||
{
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wobjc-designated-initializers"
|
||||
- (instancetype) init
|
||||
{
|
||||
@throw [NSException exceptionWithName:NSGenericException reason:@"Use the `initWithVideoIdentifier:cookies:languageIdentifier:` method instead." userInfo:nil];
|
||||
} // LCOV_EXCL_LINE
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
- (instancetype) initWithVideoIdentifier:(NSString *)videoIdentifier languageIdentifier:(NSString *)languageIdentifier cookies:(NSArray<NSHTTPCookie *> *)cookies
|
||||
{
|
||||
if (!(self = [super init]))
|
||||
return nil; // LCOV_EXCL_LINE
|
||||
|
||||
_videoIdentifier = videoIdentifier ?: @"";
|
||||
_languageIdentifier = languageIdentifier ?: @"en";
|
||||
|
||||
_session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]];
|
||||
_cookies = [cookies copy];
|
||||
for (NSHTTPCookie *cookie in _cookies) {
|
||||
[_session.configuration.HTTPCookieStorage setCookie:cookie];
|
||||
}
|
||||
_operationStartSemaphore = dispatch_semaphore_create(0);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype) initWithVideoIdentifier:(NSString *)videoIdentifier languageIdentifier:(NSString *)languageIdentifier
|
||||
{
|
||||
return [self initWithVideoIdentifier:videoIdentifier languageIdentifier:languageIdentifier cookies:nil];
|
||||
}
|
||||
|
||||
#pragma mark - Requests
|
||||
|
||||
- (void) startNextRequest
|
||||
{
|
||||
if (self.eventLabels.count == 0)
|
||||
{
|
||||
if (self.requestType == XCDYouTubeRequestTypeWatchPage || self.webpage)
|
||||
[self finishWithError];
|
||||
else
|
||||
[self startWatchPageRequest];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSString *eventLabel = [self.eventLabels objectAtIndex:0];
|
||||
[self.eventLabels removeObjectAtIndex:0];
|
||||
|
||||
NSDictionary *query = @{ @"video_id": self.videoIdentifier, @"hl": self.languageIdentifier, @"el": eventLabel, @"ps": @"default" };
|
||||
NSString *queryString = XCDQueryStringWithDictionary(query);
|
||||
NSURL *videoInfoURL = [NSURL URLWithString:[@"https://www.youtube.com/get_video_info?" stringByAppendingString:queryString]];
|
||||
[self startRequestWithURL:videoInfoURL type:XCDYouTubeRequestTypeGetVideoInfo];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) startWatchPageRequest
|
||||
{
|
||||
NSDictionary *query = @{ @"v": self.videoIdentifier, @"hl": self.languageIdentifier, @"has_verified": @YES, @"bpctr": @9999999999 };
|
||||
NSString *queryString = XCDQueryStringWithDictionary(query);
|
||||
NSURL *webpageURL = [NSURL URLWithString:[@"https://www.youtube.com/watch?" stringByAppendingString:queryString]];
|
||||
[self startRequestWithURL:webpageURL type:XCDYouTubeRequestTypeWatchPage];
|
||||
}
|
||||
|
||||
- (void) startRequestWithURL:(NSURL *)url type:(XCDYouTubeRequestType)requestType
|
||||
{
|
||||
if (self.isCancelled)
|
||||
return;
|
||||
|
||||
// Max (age-restricted VEVO) = 2×GetVideoInfo + 1×WatchPage + 1×EmbedPage + 1×JavaScriptPlayer + 1×GetVideoInfo + 1xDashManifest
|
||||
if (++self.requestCount > 7)
|
||||
{
|
||||
// This condition should never happen but the request flow is quite complex so better abort here than go into an infinite loop of requests
|
||||
[self finishWithError];
|
||||
return;
|
||||
}
|
||||
|
||||
XCDYouTubeLogDebug(@"Starting request: %@", url);
|
||||
|
||||
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
|
||||
[request setValue:self.languageIdentifier forHTTPHeaderField:@"Accept-Language"];
|
||||
[request setValue:[NSString stringWithFormat:@"https://youtube.com/watch?v=%@", self.videoIdentifier] forHTTPHeaderField:@"Referer"];
|
||||
|
||||
self.dataTask = [self.session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
|
||||
{
|
||||
if (self.isCancelled)
|
||||
return;
|
||||
|
||||
if (error)
|
||||
[self handleConnectionError:error requestType:requestType];
|
||||
else
|
||||
[self handleConnectionSuccessWithData:data response:response requestType:requestType];
|
||||
}];
|
||||
[self.dataTask resume];
|
||||
|
||||
self.requestType = requestType;
|
||||
}
|
||||
|
||||
#pragma mark - Response Dispatch
|
||||
|
||||
- (void) handleConnectionSuccessWithData:(NSData *)data response:(NSURLResponse *)response requestType:(XCDYouTubeRequestType)requestType
|
||||
{
|
||||
CFStringEncoding encoding = CFStringConvertIANACharSetNameToEncoding((__bridge CFStringRef)response.textEncodingName ?: CFSTR(""));
|
||||
// Use kCFStringEncodingMacRoman as fallback because it defines characters for every byte value and is ASCII compatible. See https://mikeash.com/pyblog/friday-qa-2010-02-19-character-encodings.html
|
||||
NSString *responseString = CFBridgingRelease(CFStringCreateWithBytes(kCFAllocatorDefault, data.bytes, (CFIndex)data.length, encoding != kCFStringEncodingInvalidId ? encoding : kCFStringEncodingMacRoman, false)) ?: @"";
|
||||
NSAssert(responseString.length > 0, @"Failed to decode response from %@ (response.textEncodingName = %@, data.length = %@)", response.URL, response.textEncodingName, @(data.length));
|
||||
|
||||
XCDYouTubeLogVerbose(@"Response: %@\n%@", response, responseString);
|
||||
|
||||
switch (requestType)
|
||||
{
|
||||
case XCDYouTubeRequestTypeGetVideoInfo:
|
||||
[self handleVideoInfoResponseWithInfo:XCDDictionaryWithQueryString(responseString) response:response];
|
||||
break;
|
||||
case XCDYouTubeRequestTypeWatchPage:
|
||||
[self handleWebPageWithHTMLString:responseString];
|
||||
break;
|
||||
case XCDYouTubeRequestTypeEmbedPage:
|
||||
[self handleEmbedWebPageWithHTMLString:responseString];
|
||||
break;
|
||||
case XCDYouTubeRequestTypeJavaScriptPlayer:
|
||||
[self handleJavaScriptPlayerWithScript:responseString];
|
||||
break;
|
||||
case XCDYouTubeRequestTypeDashManifest:
|
||||
[self handleDashManifestWithXMLString:responseString response:response];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) handleConnectionError:(NSError *)connectionError requestType:(XCDYouTubeRequestType)requestType
|
||||
{
|
||||
//Shoud not return a connection error if was as a result of requesting the Dash Manifiest (we have a sucessfully created `XCDYouTubeVideo` and should just finish the operation as if were a 'sucessful' one
|
||||
if (requestType == XCDYouTubeRequestTypeDashManifest)
|
||||
{
|
||||
[self finishWithVideo:self.lastSuccessfulVideo];
|
||||
return;
|
||||
}
|
||||
|
||||
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey: connectionError.localizedDescription,
|
||||
NSUnderlyingErrorKey: connectionError };
|
||||
self.lastError = [NSError errorWithDomain:XCDYouTubeVideoErrorDomain code:XCDYouTubeErrorNetwork userInfo:userInfo];
|
||||
|
||||
[self startNextRequest];
|
||||
}
|
||||
|
||||
#pragma mark - Response Parsing
|
||||
|
||||
- (void) handleVideoInfoResponseWithInfo:(NSDictionary *)info response:(NSURLResponse *)response
|
||||
{
|
||||
XCDYouTubeLogDebug(@"Handling video info response");
|
||||
|
||||
NSError *error = nil;
|
||||
XCDYouTubeVideo *video = [[XCDYouTubeVideo alloc] initWithIdentifier:self.videoIdentifier info:info playerScript:self.playerScript response:response error:&error];
|
||||
if (video)
|
||||
{
|
||||
self.lastSuccessfulVideo = video;
|
||||
|
||||
if (info[@"dashmpd"])
|
||||
{
|
||||
NSURL *dashmpdURL = [NSURL URLWithString:(NSString *_Nonnull)info[@"dashmpd"]];
|
||||
[self startRequestWithURL:dashmpdURL type:XCDYouTubeRequestTypeDashManifest];
|
||||
return;
|
||||
}
|
||||
[video mergeVideo:self.noStreamVideo];
|
||||
[self finishWithVideo:video];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([error.domain isEqual:XCDYouTubeVideoErrorDomain] && error.code == XCDYouTubeErrorUseCipherSignature)
|
||||
{
|
||||
self.noStreamVideo = error.userInfo[XCDYouTubeNoStreamVideoUserInfoKey];
|
||||
|
||||
[self startWatchPageRequest];
|
||||
}
|
||||
else
|
||||
{
|
||||
self.lastError = error;
|
||||
if (error.code > 0)
|
||||
self.youTubeError = error;
|
||||
|
||||
[self startNextRequest];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) handleWebPageWithHTMLString:(NSString *)html
|
||||
{
|
||||
XCDYouTubeLogDebug(@"Handling web page response");
|
||||
|
||||
self.webpage = [[XCDYouTubeVideoWebpage alloc] initWithHTMLString:html];
|
||||
|
||||
if (self.webpage.javaScriptPlayerURL)
|
||||
{
|
||||
[self startRequestWithURL:self.webpage.javaScriptPlayerURL type:XCDYouTubeRequestTypeJavaScriptPlayer];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self.webpage.isAgeRestricted)
|
||||
{
|
||||
NSString *embedURLString = [NSString stringWithFormat:@"https://www.youtube.com/embed/%@", self.videoIdentifier];
|
||||
[self startRequestWithURL:[NSURL URLWithString:embedURLString] type:XCDYouTubeRequestTypeEmbedPage];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self startNextRequest];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) handleEmbedWebPageWithHTMLString:(NSString *)html
|
||||
{
|
||||
XCDYouTubeLogDebug(@"Handling embed web page response");
|
||||
|
||||
self.embedWebpage = [[XCDYouTubeVideoWebpage alloc] initWithHTMLString:html];
|
||||
|
||||
if (self.embedWebpage.javaScriptPlayerURL)
|
||||
{
|
||||
[self startRequestWithURL:self.embedWebpage.javaScriptPlayerURL type:XCDYouTubeRequestTypeJavaScriptPlayer];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self startNextRequest];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) handleJavaScriptPlayerWithScript:(NSString *)script
|
||||
{
|
||||
XCDYouTubeLogDebug(@"Handling JavaScript player response");
|
||||
|
||||
self.playerScript = [[XCDYouTubePlayerScript alloc] initWithString:script];
|
||||
|
||||
if (self.webpage.isAgeRestricted && self.cookies.count == 0)
|
||||
{
|
||||
NSString *eurl = [@"https://youtube.googleapis.com/v/" stringByAppendingString:self.videoIdentifier];
|
||||
NSString *sts = [(NSObject *)self.embedWebpage.playerConfiguration[@"sts"] description] ?: [(NSObject *)self.webpage.playerConfiguration[@"sts"] description] ?: @"";
|
||||
NSDictionary *query = @{ @"video_id": self.videoIdentifier, @"hl": self.languageIdentifier, @"eurl": eurl, @"sts": sts};
|
||||
NSString *queryString = XCDQueryStringWithDictionary(query);
|
||||
NSURL *videoInfoURL = [NSURL URLWithString:[@"https://www.youtube.com/get_video_info?" stringByAppendingString:queryString]];
|
||||
[self startRequestWithURL:videoInfoURL type:XCDYouTubeRequestTypeGetVideoInfo];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self handleVideoInfoResponseWithInfo:self.webpage.videoInfo response:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) handleDashManifestWithXMLString:(NSString *)XMLString response:(NSURLResponse *)response
|
||||
{
|
||||
XCDYouTubeLogDebug(@"Handling Dash Manifest response");
|
||||
|
||||
XCDYouTubeDashManifestXML *dashManifestXML = [[XCDYouTubeDashManifestXML alloc]initWithXMLString:XMLString];
|
||||
NSDictionary *dashhManifestStreamURLs = dashManifestXML.streamURLs;
|
||||
if (dashhManifestStreamURLs)
|
||||
[self.lastSuccessfulVideo mergeDashManifestStreamURLs:dashhManifestStreamURLs];
|
||||
|
||||
[self finishWithVideo:self.lastSuccessfulVideo];
|
||||
}
|
||||
|
||||
#pragma mark - Finish Operation
|
||||
|
||||
- (void) finishWithVideo:(XCDYouTubeVideo *)video
|
||||
{
|
||||
self.video = video;
|
||||
XCDYouTubeLogInfo(@"Video operation finished with success: %@", video);
|
||||
XCDYouTubeLogDebug(@"%@", ^{ return video.debugDescription; }());
|
||||
[self finish];
|
||||
}
|
||||
|
||||
- (void) finishWithError
|
||||
{
|
||||
self.error = self.youTubeError ? YouTubeError(self.youTubeError, self.webpage.regionsAllowed, self.languageIdentifier) : self.lastError;
|
||||
XCDYouTubeLogError(@"Video operation finished with error: %@\nDomain: %@\nCode: %@\nUser Info: %@", self.error.localizedDescription, self.error.domain, @(self.error.code), self.error.userInfo);
|
||||
[self finish];
|
||||
}
|
||||
|
||||
- (void) finish
|
||||
{
|
||||
self.isExecuting = NO;
|
||||
self.isFinished = YES;
|
||||
}
|
||||
|
||||
#pragma mark - NSOperation
|
||||
|
||||
+ (BOOL) automaticallyNotifiesObserversForKey:(NSString *)key
|
||||
{
|
||||
SEL selector = NSSelectorFromString(key);
|
||||
return selector == @selector(isExecuting) || selector == @selector(isFinished) || [super automaticallyNotifiesObserversForKey:key];
|
||||
}
|
||||
|
||||
- (BOOL) isConcurrent
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) start
|
||||
{
|
||||
dispatch_semaphore_signal(self.operationStartSemaphore);
|
||||
|
||||
if (self.isCancelled)
|
||||
return;
|
||||
|
||||
if (self.videoIdentifier.length != 11)
|
||||
{
|
||||
XCDYouTubeLogWarning(@"Video identifier length should be 11. [%@]", self.videoIdentifier);
|
||||
}
|
||||
|
||||
XCDYouTubeLogInfo(@"Starting video operation: %@", self);
|
||||
|
||||
self.isExecuting = YES;
|
||||
|
||||
self.eventLabels = [[NSMutableArray alloc] initWithArray:@[ @"embedded", @"detailpage" ]];
|
||||
[self startNextRequest];
|
||||
}
|
||||
|
||||
- (void) cancel
|
||||
{
|
||||
if (self.isCancelled || self.isFinished)
|
||||
return;
|
||||
|
||||
XCDYouTubeLogInfo(@"Canceling video operation: %@", self);
|
||||
|
||||
[super cancel];
|
||||
|
||||
[self.dataTask cancel];
|
||||
|
||||
// Wait for `start` to be called in order to avoid this warning: *** XCDYouTubeVideoOperation 0x7f8b18c84880 went isFinished=YES without being started by the queue it is in
|
||||
dispatch_semaphore_wait(self.operationStartSemaphore, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(200 * NSEC_PER_MSEC)));
|
||||
[self finish];
|
||||
}
|
||||
|
||||
#pragma mark - NSObject
|
||||
|
||||
- (NSString *) description
|
||||
{
|
||||
return [NSString stringWithFormat:@"<%@: %p> %@ (%@)", self.class, self, self.videoIdentifier, self.languageIdentifier];
|
||||
}
|
||||
|
||||
@end
|
||||
126
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideoPlayerViewController.h
generated
Normal file
126
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideoPlayerViewController.h
generated
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
//
|
||||
// Copyright (c) 2013-2016 Cédric Luthi. All rights reserved.
|
||||
//
|
||||
|
||||
#if !__has_feature(nullability)
|
||||
#define NS_ASSUME_NONNULL_BEGIN
|
||||
#define NS_ASSUME_NONNULL_END
|
||||
#define nullable
|
||||
#define null_resettable
|
||||
#endif
|
||||
|
||||
#import <MediaPlayer/MediaPlayer.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* -------------------
|
||||
* @name Notifications
|
||||
* -------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* NSError key for the `MPMoviePlayerPlaybackDidFinishNotification` userInfo dictionary.
|
||||
*
|
||||
* Ideally, there should be a `MPMoviePlayerPlaybackDidFinishErrorUserInfoKey` declared near to `MPMoviePlayerPlaybackDidFinishReasonUserInfoKey` in MPMoviePlayerController.h but since it doesn't exist, here is a convenient constant key.
|
||||
*/
|
||||
MP_EXTERN NSString *const XCDMoviePlayerPlaybackDidFinishErrorUserInfoKey;
|
||||
|
||||
/**
|
||||
* Posted when the video player has received the video information. The `object` of the notification is the `XCDYouTubeVideoPlayerViewController` instance. The `userInfo` dictionary contains the `XCDYouTubeVideo` object.
|
||||
*/
|
||||
MP_EXTERN NSString *const XCDYouTubeVideoPlayerViewControllerDidReceiveVideoNotification;
|
||||
/**
|
||||
* The key for the `XCDYouTubeVideo` object in the user info dictionary of `XCDYouTubeVideoPlayerViewControllerDidReceiveVideoNotification`.
|
||||
*/
|
||||
MP_EXTERN NSString *const XCDYouTubeVideoUserInfoKey;
|
||||
|
||||
/**
|
||||
* A subclass of `MPMoviePlayerViewController` for playing YouTube videos.
|
||||
*
|
||||
* Use UIViewController’s `presentMoviePlayerViewControllerAnimated:` method to play a YouTube video fullscreen.
|
||||
*
|
||||
* Use the `<presentInView:>` method to play a YouTube video inline.
|
||||
*/
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
DEPRECATED_MSG_ATTRIBUTE("Use `AVFoundation` or `AVKit` APIs instead.")
|
||||
@interface XCDYouTubeVideoPlayerViewController : MPMoviePlayerViewController
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
/**
|
||||
* ------------------
|
||||
* @name Initializing
|
||||
* ------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initializes a YouTube video player view controller
|
||||
*
|
||||
* @param videoIdentifier A 11 characters YouTube video identifier. If the video identifier is invalid the `MPMoviePlayerPlaybackDidFinishNotification` will be posted with a `MPMovieFinishReasonPlaybackError` reason.
|
||||
*
|
||||
* @return An initialized YouTube video player view controller with the specified video identifier.
|
||||
*
|
||||
* @discussion You can pass a nil *videoIdentifier* (or use the standard `init` method instead) and set the `<videoIdentifier>` property later.
|
||||
*/
|
||||
- (instancetype) initWithVideoIdentifier:(nullable NSString *)videoIdentifier NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/**
|
||||
* ------------------------------------
|
||||
* @name Accessing the video identifier
|
||||
* ------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* The 11 characters YouTube video identifier.
|
||||
*/
|
||||
@property (nonatomic, copy, nullable) NSString *videoIdentifier;
|
||||
|
||||
/**
|
||||
* ------------------------------------------
|
||||
* @name Defining the preferred video quality
|
||||
* ------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* The preferred order for the quality of the video to play. Plays the first match when multiple video streams are available.
|
||||
*
|
||||
* Defaults to @[ XCDYouTubeVideoQualityHTTPLiveStreaming, @(XCDYouTubeVideoQualityHD720), @(XCDYouTubeVideoQualityMedium360), @(XCDYouTubeVideoQualitySmall240) ]
|
||||
*
|
||||
* You should set this property right after calling the `<initWithVideoIdentifier:>` method. Setting this property to nil restores its default values.
|
||||
*
|
||||
* @see XCDYouTubeVideoQuality
|
||||
*/
|
||||
@property (nonatomic, copy, null_resettable) NSArray *preferredVideoQualities;
|
||||
|
||||
/**
|
||||
* ------------------------
|
||||
* @name Presenting a video
|
||||
* ------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Present the video inside a view.
|
||||
*
|
||||
* @param view The view inside which you want to present the video.
|
||||
*
|
||||
* @discussion The video view is added as a subview of the specified view. The video does not start playing immediately, you have to call `[videoPlayerViewController.moviePlayer play]` for playback to start. See `MPMoviePlayerController` documentation for more information.
|
||||
*
|
||||
* Ownership of the XCDYouTubeVideoPlayerViewController instance is transferred to the view.
|
||||
*/
|
||||
- (void) presentInView:(UIView *)view;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
* ------------------------------
|
||||
* @name Deprecated notifications
|
||||
* ------------------------------
|
||||
*/
|
||||
MP_EXTERN NSString *const XCDYouTubeVideoPlayerViewControllerDidReceiveMetadataNotification DEPRECATED_MSG_ATTRIBUTE("Use XCDYouTubeVideoPlayerViewControllerDidReceiveVideoNotification instead.");
|
||||
MP_EXTERN NSString *const XCDMetadataKeyTitle DEPRECATED_MSG_ATTRIBUTE("Use XCDYouTubeVideoUserInfoKey instead.");
|
||||
MP_EXTERN NSString *const XCDMetadataKeySmallThumbnailURL DEPRECATED_MSG_ATTRIBUTE("Use XCDYouTubeVideoUserInfoKey instead.");
|
||||
MP_EXTERN NSString *const XCDMetadataKeyMediumThumbnailURL DEPRECATED_MSG_ATTRIBUTE("Use XCDYouTubeVideoUserInfoKey instead.");
|
||||
MP_EXTERN NSString *const XCDMetadataKeyLargeThumbnailURL DEPRECATED_MSG_ATTRIBUTE("Use XCDYouTubeVideoUserInfoKey instead.");
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
209
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideoPlayerViewController.m
generated
Normal file
209
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideoPlayerViewController.m
generated
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
//
|
||||
// Copyright (c) 2013-2016 Cédric Luthi. All rights reserved.
|
||||
//
|
||||
|
||||
#import "XCDYouTubeVideoPlayerViewController.h"
|
||||
|
||||
#import "XCDYouTubeClient.h"
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
NSString *const XCDMoviePlayerPlaybackDidFinishErrorUserInfoKey = @"error"; // documented in -[MPMoviePlayerController initWithContentURL:]
|
||||
|
||||
NSString *const XCDYouTubeVideoPlayerViewControllerDidReceiveMetadataNotification = @"XCDYouTubeVideoPlayerViewControllerDidReceiveMetadataNotification";
|
||||
NSString *const XCDMetadataKeyTitle = @"Title";
|
||||
NSString *const XCDMetadataKeySmallThumbnailURL = @"SmallThumbnailURL";
|
||||
NSString *const XCDMetadataKeyMediumThumbnailURL = @"MediumThumbnailURL";
|
||||
NSString *const XCDMetadataKeyLargeThumbnailURL = @"LargeThumbnailURL";
|
||||
|
||||
NSString *const XCDYouTubeVideoPlayerViewControllerDidReceiveVideoNotification = @"XCDYouTubeVideoPlayerViewControllerDidReceiveVideoNotification";
|
||||
NSString *const XCDYouTubeVideoUserInfoKey = @"Video";
|
||||
|
||||
@interface XCDYouTubeVideoPlayerViewController ()
|
||||
@property (nonatomic, weak) id<XCDYouTubeOperation> videoOperation;
|
||||
@property (nonatomic, assign, getter = isEmbedded) BOOL embedded;
|
||||
@end
|
||||
|
||||
@implementation XCDYouTubeVideoPlayerViewController
|
||||
|
||||
/*
|
||||
* MPMoviePlayerViewController on iOS 7 and earlier
|
||||
* - (id) init
|
||||
* `-- [super init]
|
||||
*
|
||||
* - (id) initWithContentURL:(NSURL *)contentURL
|
||||
* |-- [self init]
|
||||
* `-- [self.moviePlayer setContentURL:contentURL]
|
||||
*
|
||||
* MPMoviePlayerViewController on iOS 8 and later
|
||||
* - (id) init
|
||||
* `-- [self initWithContentURL:nil]
|
||||
*
|
||||
* - (id) initWithContentURL:(NSURL *)contentURL
|
||||
* |-- [super init]
|
||||
* `-- [self.moviePlayer setContentURL:contentURL]
|
||||
*/
|
||||
|
||||
- (instancetype) init
|
||||
{
|
||||
return [self initWithVideoIdentifier:nil];
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wobjc-designated-initializers"
|
||||
- (instancetype) initWithContentURL:(NSURL *)contentURL
|
||||
{
|
||||
@throw [NSException exceptionWithName:NSGenericException reason:@"Use the `initWithVideoIdentifier:` method instead." userInfo:nil];
|
||||
} // LCOV_EXCL_LINE
|
||||
|
||||
- (instancetype) initWithVideoIdentifier:(NSString *)videoIdentifier
|
||||
{
|
||||
#if defined(DEBUG) && DEBUG
|
||||
NSString *callStackSymbols = [[NSThread callStackSymbols] componentsJoinedByString:@"\n"];
|
||||
if (([callStackSymbols rangeOfString:@"-[XCDYouTubeClient getVideoWithIdentifier:completionHandler:]_block_invoke"].length > 0) || ([callStackSymbols rangeOfString:@"-[XCDYouTubeClient getVideoWithIdentifier:cookies:completionHandler:]_block_invoke"].length > 0))
|
||||
{
|
||||
NSString *reason = @"XCDYouTubeVideoPlayerViewController must not be used in the completion handler of `-[XCDYouTubeClient getVideoWithIdentifier:completionHandler:]` or `-[XCDYouTubeClient getVideoWithIdentifier:cookies:completionHandler:]`. Please read the documentation and sample code to properly use XCDYouTubeVideoPlayerViewController.";
|
||||
@throw [NSException exceptionWithName:NSGenericException reason:reason userInfo:nil];
|
||||
}
|
||||
#endif
|
||||
|
||||
if ([[[UIDevice currentDevice] systemVersion] integerValue] >= 8)
|
||||
self = [super initWithContentURL:nil];
|
||||
else
|
||||
self = [super init]; // LCOV_EXCL_LINE
|
||||
|
||||
if (!self)
|
||||
return nil; // LCOV_EXCL_LINE
|
||||
|
||||
// See https://github.com/0xced/XCDYouTubeKit/commit/cadec1c3857d6a302f71b9ce7d1ae48e389e6890
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
|
||||
|
||||
if (videoIdentifier)
|
||||
self.videoIdentifier = videoIdentifier;
|
||||
|
||||
return self;
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
#pragma mark - Public
|
||||
|
||||
- (NSArray *) preferredVideoQualities
|
||||
{
|
||||
if (!_preferredVideoQualities)
|
||||
_preferredVideoQualities = @[ XCDYouTubeVideoQualityHTTPLiveStreaming, @(XCDYouTubeVideoQualityHD720), @(XCDYouTubeVideoQualityMedium360), @(XCDYouTubeVideoQualitySmall240) ];
|
||||
|
||||
return _preferredVideoQualities;
|
||||
}
|
||||
|
||||
- (void) setVideoIdentifier:(NSString *)videoIdentifier
|
||||
{
|
||||
if ([videoIdentifier isEqual:self.videoIdentifier])
|
||||
return;
|
||||
|
||||
_videoIdentifier = [videoIdentifier copy];
|
||||
|
||||
[self.videoOperation cancel];
|
||||
self.videoOperation = [[XCDYouTubeClient defaultClient] getVideoWithIdentifier:videoIdentifier completionHandler:^(XCDYouTubeVideo *video, NSError *error)
|
||||
{
|
||||
if (video)
|
||||
{
|
||||
NSURL *streamURL = nil;
|
||||
for (NSNumber *videoQuality in self.preferredVideoQualities)
|
||||
{
|
||||
streamURL = video.streamURLs[videoQuality];
|
||||
if (streamURL)
|
||||
{
|
||||
[self startVideo:video streamURL:streamURL];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!streamURL)
|
||||
{
|
||||
NSError *noStreamError = [NSError errorWithDomain:XCDYouTubeVideoErrorDomain code:XCDYouTubeErrorNoStreamAvailable userInfo:nil];
|
||||
[self stopWithError:noStreamError];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[self stopWithError:error];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void) presentInView:(UIView *)view
|
||||
{
|
||||
static const void * const XCDYouTubeVideoPlayerViewControllerKey = &XCDYouTubeVideoPlayerViewControllerKey;
|
||||
|
||||
self.embedded = YES;
|
||||
|
||||
self.moviePlayer.controlStyle = MPMovieControlStyleEmbedded;
|
||||
self.moviePlayer.view.frame = CGRectMake(0, 0, view.bounds.size.width, view.bounds.size.height);
|
||||
self.moviePlayer.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
if (![view.subviews containsObject:self.moviePlayer.view])
|
||||
[view addSubview:self.moviePlayer.view];
|
||||
objc_setAssociatedObject(view, XCDYouTubeVideoPlayerViewControllerKey, self, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
- (void) startVideo:(XCDYouTubeVideo *)video streamURL:(NSURL *)streamURL
|
||||
{
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
NSMutableDictionary *userInfo = [NSMutableDictionary new];
|
||||
if (video.title)
|
||||
userInfo[XCDMetadataKeyTitle] = video.title;
|
||||
if (video.smallThumbnailURL)
|
||||
userInfo[XCDMetadataKeySmallThumbnailURL] = video.smallThumbnailURL;
|
||||
if (video.mediumThumbnailURL)
|
||||
userInfo[XCDMetadataKeyMediumThumbnailURL] = video.mediumThumbnailURL;
|
||||
if (video.largeThumbnailURL)
|
||||
userInfo[XCDMetadataKeyLargeThumbnailURL] = video.largeThumbnailURL;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:XCDYouTubeVideoPlayerViewControllerDidReceiveMetadataNotification object:self userInfo:userInfo];
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
self.moviePlayer.contentURL = streamURL;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:XCDYouTubeVideoPlayerViewControllerDidReceiveVideoNotification object:self userInfo:@{ XCDYouTubeVideoUserInfoKey: video }];
|
||||
}
|
||||
|
||||
- (void) stopWithError:(NSError *)error
|
||||
{
|
||||
NSDictionary *userInfo = @{ MPMoviePlayerPlaybackDidFinishReasonUserInfoKey: @(MPMovieFinishReasonPlaybackError),
|
||||
XCDMoviePlayerPlaybackDidFinishErrorUserInfoKey: error };
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:MPMoviePlayerPlaybackDidFinishNotification object:self.moviePlayer userInfo:userInfo];
|
||||
|
||||
if (self.isEmbedded)
|
||||
[self.moviePlayer.view removeFromSuperview];
|
||||
else
|
||||
[self.presentingViewController dismissMoviePlayerViewControllerAnimated];
|
||||
}
|
||||
|
||||
#pragma mark - UIViewController
|
||||
|
||||
- (void) viewWillAppear:(BOOL)animated
|
||||
{
|
||||
[super viewWillAppear:animated];
|
||||
|
||||
if (![self isBeingPresented])
|
||||
return;
|
||||
|
||||
self.moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
|
||||
[self.moviePlayer play];
|
||||
}
|
||||
|
||||
- (void) viewWillDisappear:(BOOL)animated
|
||||
{
|
||||
[super viewWillDisappear:animated];
|
||||
|
||||
if (![self isBeingDismissed])
|
||||
return;
|
||||
|
||||
[self.videoOperation cancel];
|
||||
}
|
||||
|
||||
@end
|
||||
18
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideoWebpage.h
generated
Normal file
18
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideoWebpage.h
generated
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
//
|
||||
// Copyright (c) 2013-2016 Cédric Luthi. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
__attribute__((visibility("hidden")))
|
||||
@interface XCDYouTubeVideoWebpage : NSObject
|
||||
|
||||
- (instancetype) initWithHTMLString:(NSString *)html;
|
||||
|
||||
@property (nonatomic, readonly) NSDictionary *playerConfiguration;
|
||||
@property (nonatomic, readonly) NSDictionary *videoInfo;
|
||||
@property (nonatomic, readonly) NSURL *javaScriptPlayerURL;
|
||||
@property (nonatomic, readonly) BOOL isAgeRestricted;
|
||||
@property (nonatomic, readonly) NSSet *regionsAllowed;
|
||||
|
||||
@end
|
||||
124
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideoWebpage.m
generated
Normal file
124
ios/Pods/XCDYouTubeKit/XCDYouTubeKit/XCDYouTubeVideoWebpage.m
generated
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
//
|
||||
// Copyright (c) 2013-2016 Cédric Luthi. All rights reserved.
|
||||
//
|
||||
|
||||
#import "XCDYouTubeVideoWebpage.h"
|
||||
|
||||
@interface XCDYouTubeVideoWebpage ()
|
||||
@property (nonatomic, readonly) NSString *html;
|
||||
@end
|
||||
|
||||
@implementation XCDYouTubeVideoWebpage
|
||||
|
||||
@synthesize playerConfiguration = _playerConfiguration;
|
||||
@synthesize videoInfo = _videoInfo;
|
||||
@synthesize javaScriptPlayerURL = _javaScriptPlayerURL;
|
||||
@synthesize isAgeRestricted = _isAgeRestricted;
|
||||
@synthesize regionsAllowed = _regionsAllowed;
|
||||
|
||||
- (instancetype) initWithHTMLString:(NSString *)html
|
||||
{
|
||||
if (!(self = [super init]))
|
||||
return nil; // LCOV_EXCL_LINE
|
||||
|
||||
_html = html;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSDictionary *) playerConfiguration
|
||||
{
|
||||
if (!_playerConfiguration)
|
||||
{
|
||||
__block NSDictionary *playerConfigurationDictionary;
|
||||
NSRegularExpression *playerConfigRegularExpression = [NSRegularExpression regularExpressionWithPattern:@"ytplayer.config\\s*=\\s*(\\{.*?\\});|[\\({]\\s*'PLAYER_CONFIG'[,:]\\s*(\\{.*?\\})\\s*(?:,'|\\))" options:NSRegularExpressionCaseInsensitive error:NULL];
|
||||
[playerConfigRegularExpression enumerateMatchesInString:self.html options:(NSMatchingOptions)0 range:NSMakeRange(0, self.html.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop)
|
||||
{
|
||||
for (NSUInteger i = 1; i < result.numberOfRanges; i++)
|
||||
{
|
||||
NSRange range = [result rangeAtIndex:i];
|
||||
if (range.length == 0)
|
||||
continue;
|
||||
|
||||
NSString *configString = [self.html substringWithRange:range];
|
||||
NSData *configData = [configString dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSDictionary *playerConfiguration = [NSJSONSerialization JSONObjectWithData:configData ?: [NSData new] options:(NSJSONReadingOptions)0 error:NULL];
|
||||
if ([playerConfiguration isKindOfClass:[NSDictionary class]])
|
||||
{
|
||||
playerConfigurationDictionary = playerConfiguration;
|
||||
*stop = YES;
|
||||
}
|
||||
}
|
||||
}];
|
||||
_playerConfiguration = playerConfigurationDictionary;
|
||||
}
|
||||
return _playerConfiguration;
|
||||
}
|
||||
|
||||
- (NSDictionary *) videoInfo
|
||||
{
|
||||
if (!_videoInfo)
|
||||
{
|
||||
NSDictionary *args = self.playerConfiguration[@"args"];
|
||||
if ([args isKindOfClass:[NSDictionary class]])
|
||||
{
|
||||
NSMutableDictionary *info = [NSMutableDictionary new];
|
||||
[args enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop)
|
||||
{
|
||||
if ([(NSObject *)value isKindOfClass:[NSString class]] || [(NSObject *)value isKindOfClass:[NSNumber class]])
|
||||
info[key] = [(NSObject *)value description];
|
||||
}];
|
||||
_videoInfo = [info copy];
|
||||
}
|
||||
}
|
||||
return _videoInfo;
|
||||
}
|
||||
|
||||
- (NSURL *) javaScriptPlayerURL
|
||||
{
|
||||
if (!_javaScriptPlayerURL)
|
||||
{
|
||||
NSString *jsAssets = [self.playerConfiguration valueForKeyPath:@"assets.js"];
|
||||
if ([jsAssets isKindOfClass:[NSString class]])
|
||||
{
|
||||
NSString *javaScriptPlayerURLString = jsAssets;
|
||||
if ([jsAssets hasPrefix:@"//"])
|
||||
javaScriptPlayerURLString = [@"https:" stringByAppendingString:jsAssets];
|
||||
else if ([jsAssets hasPrefix:@"/"])
|
||||
javaScriptPlayerURLString = [@"https://www.youtube.com" stringByAppendingString:jsAssets];
|
||||
|
||||
_javaScriptPlayerURL = [NSURL URLWithString:javaScriptPlayerURLString];
|
||||
}
|
||||
}
|
||||
return _javaScriptPlayerURL;
|
||||
}
|
||||
|
||||
- (BOOL) isAgeRestricted
|
||||
{
|
||||
if (!_isAgeRestricted)
|
||||
{
|
||||
NSStringCompareOptions options = (NSStringCompareOptions)0;
|
||||
NSRange range = NSMakeRange(0, self.html.length);
|
||||
_isAgeRestricted = [self.html rangeOfString:@"og:restrictions:age" options:options range:range].location != NSNotFound;
|
||||
}
|
||||
return _isAgeRestricted;
|
||||
}
|
||||
|
||||
- (NSSet *) regionsAllowed
|
||||
{
|
||||
if (!_regionsAllowed)
|
||||
{
|
||||
_regionsAllowed = [NSSet set];
|
||||
NSRegularExpression *regionsAllowedRegularExpression = [NSRegularExpression regularExpressionWithPattern:@"meta\\s+itemprop=\"regionsAllowed\"\\s+content=\"(.*)\"" options:(NSRegularExpressionOptions)0 error:NULL];
|
||||
NSTextCheckingResult *regionsAllowedResult = [regionsAllowedRegularExpression firstMatchInString:self.html options:(NSMatchingOptions)0 range:NSMakeRange(0, self.html.length)];
|
||||
if (regionsAllowedResult.numberOfRanges > 1)
|
||||
{
|
||||
NSString *regionsAllowed = [self.html substringWithRange:[regionsAllowedResult rangeAtIndex:1]];
|
||||
if (regionsAllowed.length > 0)
|
||||
_regionsAllowed = [NSSet setWithArray:[regionsAllowed componentsSeparatedByString:@","]];
|
||||
}
|
||||
}
|
||||
return _regionsAllowed;
|
||||
}
|
||||
|
||||
@end
|
||||
13
ios/Pods/YoutubePlayer-in-WKWebView/LICENSE
generated
Normal file
13
ios/Pods/YoutubePlayer-in-WKWebView/LICENSE
generated
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
Copyright 2014 Google Inc. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
59
ios/Pods/YoutubePlayer-in-WKWebView/README.md
generated
Normal file
59
ios/Pods/YoutubePlayer-in-WKWebView/README.md
generated
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
# YoutubePlayer-in-WKWebView
|
||||
|
||||
[](http://cocoadocs.org/docsets/YoutubePlayer-in-WKWebView) [](http://cocoadocs.org/docsets/YoutubePlayer-in-WKWebView) [](http://cocoadocs.org/docsets/YoutubePlayer-in-WKWebView)
|
||||
|
||||
YoutubePlayer-in-WKWebView is forked from [youtube-ios-player-helper](https://github.com/youtube/youtube-ios-player-helper) For using WKWebView.
|
||||
|
||||
## Changes from [youtube-ios-player-helper](https://github.com/youtube/youtube-ios-player-helper)
|
||||
|
||||
- class prefix changed to WKYT from YT. `YTPlayerView` -> `WKYTPlayerView`
|
||||
- using WKWebView instead of UIWebView.
|
||||
- getting properties asynchronously.
|
||||
|
||||
```
|
||||
// YTPlayerView
|
||||
NSTimeInterval duration = self.playerView.duration;
|
||||
|
||||
// WKYTPlayerView
|
||||
[self.playerView getDuration:^(NSTimeInterval duration, NSError * _Nullable error) {
|
||||
if (!error) {
|
||||
float seekToTime = duration * self.slider.value;
|
||||
}
|
||||
}];
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
To run the example project; clone the repo, and run `pod install` from the Project directory first. For a simple tutorial see this Google Developers article - [Using the YouTube Helper Library to embed YouTube videos in your iOS application](https://developers.google.com/youtube/v3/guides/ios_youtube_helper).
|
||||
|
||||
## Requirements
|
||||
|
||||
## Installation
|
||||
|
||||
YouTube-Player-iOS-Helper is available through [CocoaPods](http://cocoapods.org), to install
|
||||
it simply add the following line to your Podfile:
|
||||
|
||||
pod "YoutubePlayer-in-WKWebView", "~> 0.3.0"
|
||||
|
||||
After installing in your project and opening the workspace, to use the library:
|
||||
|
||||
1. Drag a UIView the desired size of your player onto your Storyboard.
|
||||
2. Change the UIView's class in the Identity Inspector tab to WKYTPlayerView
|
||||
3. Import "WKYTPlayerView.h" in your ViewController.
|
||||
4. Add the following property to your ViewController's header file:
|
||||
```objc
|
||||
@property(nonatomic, strong) IBOutlet WKYTPlayerView *playerView;
|
||||
```
|
||||
5. Load the video into the player in your controller's code with the following code:
|
||||
```objc
|
||||
[self.playerView loadWithVideoId:@"M7lc1UVf-VE"];
|
||||
```
|
||||
6. Run your code!
|
||||
|
||||
See the sample project for more advanced uses, including passing additional player parameters, custom html and
|
||||
working with callbacks via WKYTPlayerViewDelegate.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
YoutubePlayer-in-WKWebView is available under the Apache 2.0 license. See the LICENSE file for more info.
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
<!--
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body { margin: 0; width:100%%; height:100%%; background-color:#000000; }
|
||||
html { width:100%%; height:100%%; background-color:#000000; }
|
||||
|
||||
.embed-container iframe,
|
||||
.embed-container object,
|
||||
.embed-container embed {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%% !important;
|
||||
height: 100%% !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="embed-container">
|
||||
<div id="player"></div>
|
||||
</div>
|
||||
<script src="https://www.youtube.com/iframe_api" onerror="window.location.href='ytplayer://onYouTubeIframeAPIFailedToLoad'"></script>
|
||||
<script>
|
||||
var player;
|
||||
var error = false;
|
||||
|
||||
YT.ready(function() {
|
||||
player = new YT.Player('player', %@);
|
||||
player.setSize(window.innerWidth, window.innerHeight);
|
||||
window.location.href = 'ytplayer://onYouTubeIframeAPIReady';
|
||||
|
||||
// this will transmit playTime frequently while playng
|
||||
function getCurrentTime() {
|
||||
var state = player.getPlayerState();
|
||||
if (state == YT.PlayerState.PLAYING) {
|
||||
time = player.getCurrentTime()
|
||||
window.location.href = 'ytplayer://onPlayTime?data=' + time;
|
||||
}
|
||||
}
|
||||
|
||||
window.setInterval(getCurrentTime, 500);
|
||||
|
||||
});
|
||||
|
||||
function onReady(event) {
|
||||
window.location.href = 'ytplayer://onReady?data=' + event.data;
|
||||
}
|
||||
|
||||
function onStateChange(event) {
|
||||
if (!error) {
|
||||
window.location.href = 'ytplayer://onStateChange?data=' + event.data;
|
||||
}
|
||||
else {
|
||||
error = false;
|
||||
}
|
||||
}
|
||||
|
||||
function onPlaybackQualityChange(event) {
|
||||
window.location.href = 'ytplayer://onPlaybackQualityChange?data=' + event.data;
|
||||
}
|
||||
|
||||
function onPlayerError(event) {
|
||||
if (event.data == 100) {
|
||||
error = true;
|
||||
}
|
||||
window.location.href = 'ytplayer://onError?data=' + event.data;
|
||||
}
|
||||
|
||||
window.onresize = function() {
|
||||
player.setSize(window.innerWidth, window.innerHeight);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
734
ios/Pods/YoutubePlayer-in-WKWebView/WKYTPlayerView/WKYTPlayerView.h
generated
Normal file
734
ios/Pods/YoutubePlayer-in-WKWebView/WKYTPlayerView/WKYTPlayerView.h
generated
Normal file
|
|
@ -0,0 +1,734 @@
|
|||
// Copyright © 2014 Google Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <WebKit/WebKit.h>
|
||||
|
||||
@class WKYTPlayerView;
|
||||
|
||||
/** These enums represent the state of the current video in the player. */
|
||||
typedef NS_ENUM(NSInteger, WKYTPlayerState) {
|
||||
kWKYTPlayerStateUnstarted,
|
||||
kWKYTPlayerStateEnded,
|
||||
kWKYTPlayerStatePlaying,
|
||||
kWKYTPlayerStatePaused,
|
||||
kWKYTPlayerStateBuffering,
|
||||
kWKYTPlayerStateQueued,
|
||||
kWKYTPlayerStateUnknown
|
||||
};
|
||||
|
||||
/** These enums represent the resolution of the currently loaded video. */
|
||||
typedef NS_ENUM(NSInteger, WKYTPlaybackQuality) {
|
||||
kWKYTPlaybackQualitySmall,
|
||||
kWKYTPlaybackQualityMedium,
|
||||
kWKYTPlaybackQualityLarge,
|
||||
kWKYTPlaybackQualityHD720,
|
||||
kWKYTPlaybackQualityHD1080,
|
||||
kWKYTPlaybackQualityHighRes,
|
||||
kWKYTPlaybackQualityAuto, /** Addition for YouTube Live Events. */
|
||||
kWKYTPlaybackQualityDefault,
|
||||
kWKYTPlaybackQualityUnknown /** This should never be returned. It is here for future proofing. */
|
||||
};
|
||||
|
||||
/** These enums represent error codes thrown by the player. */
|
||||
typedef NS_ENUM(NSInteger, WKYTPlayerError) {
|
||||
kWKYTPlayerErrorInvalidParam,
|
||||
kWKYTPlayerErrorHTML5Error,
|
||||
kWKYTPlayerErrorVideoNotFound, // Functionally equivalent error codes 100 and
|
||||
// 105 have been collapsed into |kWKYTPlayerErrorVideoNotFound|.
|
||||
kWKYTPlayerErrorNotEmbeddable, // Functionally equivalent error codes 101 and
|
||||
// 150 have been collapsed into |kWKYTPlayerErrorNotEmbeddable|.
|
||||
kWKYTPlayerErrorUnknown
|
||||
};
|
||||
|
||||
/**
|
||||
* A delegate for ViewControllers to respond to YouTube player events outside
|
||||
* of the view, such as changes to video playback state or playback errors.
|
||||
* The callback functions correlate to the events fired by the IFrame API.
|
||||
* For the full documentation, see the IFrame documentation here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#Events
|
||||
*/
|
||||
@protocol WKYTPlayerViewDelegate<NSObject>
|
||||
|
||||
@optional
|
||||
/**
|
||||
* Invoked when the player view is ready to receive API calls.
|
||||
*
|
||||
* @param playerView The WKYTPlayerView instance that has become ready.
|
||||
*/
|
||||
- (void)playerViewDidBecomeReady:(nonnull WKYTPlayerView *)playerView;
|
||||
|
||||
/**
|
||||
* Callback invoked when player state has changed, e.g. stopped or started playback.
|
||||
*
|
||||
* @param playerView The WKYTPlayerView instance where playback state has changed.
|
||||
* @param state WKYTPlayerState designating the new playback state.
|
||||
*/
|
||||
- (void)playerView:(nonnull WKYTPlayerView *)playerView didChangeToState:(WKYTPlayerState)state;
|
||||
|
||||
/**
|
||||
* Callback invoked when playback quality has changed.
|
||||
*
|
||||
* @param playerView The WKYTPlayerView instance where playback quality has changed.
|
||||
* @param quality WKYTPlaybackQuality designating the new playback quality.
|
||||
*/
|
||||
- (void)playerView:(nonnull WKYTPlayerView *)playerView didChangeToQuality:(WKYTPlaybackQuality)quality;
|
||||
|
||||
/**
|
||||
* Callback invoked when an error has occured.
|
||||
*
|
||||
* @param playerView The WKYTPlayerView instance where the error has occurred.
|
||||
* @param error WKYTPlayerError containing the error state.
|
||||
*/
|
||||
- (void)playerView:(nonnull WKYTPlayerView *)playerView receivedError:(WKYTPlayerError)error;
|
||||
|
||||
/**
|
||||
* Callback invoked frequently when playBack is plaing.
|
||||
*
|
||||
* @param playerView The WKYTPlayerView instance where the error has occurred.
|
||||
* @param playTime float containing curretn playback time.
|
||||
*/
|
||||
- (void)playerView:(nonnull WKYTPlayerView *)playerView didPlayTime:(float)playTime;
|
||||
|
||||
/**
|
||||
* Callback invoked when setting up the webview to allow custom colours so it fits in
|
||||
* with app color schemes. If a transparent view is required specify clearColor and
|
||||
* the code will handle the opacity etc.
|
||||
*
|
||||
* @param playerView The WKYTPlayerView instance where the error has occurred.
|
||||
* @return A color object that represents the background color of the webview.
|
||||
*/
|
||||
- (nonnull UIColor *)playerViewPreferredWebViewBackgroundColor:(nonnull WKYTPlayerView *)playerView;
|
||||
|
||||
/**
|
||||
* Callback invoked when initially loading the YouTube iframe to the webview to display a custom
|
||||
* loading view while the player view is not ready. This loading view will be dismissed just before
|
||||
* -playerViewDidBecomeReady: callback is invoked. The loading view will be automatically resized
|
||||
* to cover the entire player view.
|
||||
*
|
||||
* The default implementation does not display any custom loading views so the player will display
|
||||
* a blank view with a background color of (-playerViewPreferredWebViewBackgroundColor:).
|
||||
*
|
||||
* Note that the custom loading view WILL NOT be displayed after iframe is loaded. It will be
|
||||
* handled by YouTube iframe API. This callback is just intended to tell users the view is actually
|
||||
* doing something while iframe is being loaded, which will take some time if users are in poor networks.
|
||||
*
|
||||
* @param playerView The WKYTPlayerView instance where the error has occurred.
|
||||
* @return A view object that will be displayed while YouTube iframe API is being loaded.
|
||||
* Pass nil to display no custom loading view. Default implementation returns nil.
|
||||
*/
|
||||
- (nullable UIView *)playerViewPreferredInitialLoadingView:(nonnull WKYTPlayerView *)playerView;
|
||||
|
||||
/**
|
||||
* Callback invoked when an api loading error has occured.
|
||||
*
|
||||
* @param playerView The WKYTPlayerView instance where the error has occurred.
|
||||
*/
|
||||
- (void)playerViewIframeAPIDidFailedToLoad:(nonnull WKYTPlayerView *)playerView;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
* WKYTPlayerView is a custom UIView that client developers will use to include YouTube
|
||||
* videos in their iOS applications. It can be instantiated programmatically, or via
|
||||
* Interface Builder. Use the methods WKYTPlayerView::loadWithVideoId:,
|
||||
* WKYTPlayerView::loadWithPlaylistId: or their variants to set the video or playlist
|
||||
* to populate the view with.
|
||||
*/
|
||||
@interface WKYTPlayerView : UIView<WKNavigationDelegate, WKUIDelegate>
|
||||
|
||||
@property(nonatomic, strong, nullable, readonly) WKWebView *webView;
|
||||
|
||||
/** A delegate to be notified on playback events. */
|
||||
@property(nonatomic, weak, nullable) id<WKYTPlayerViewDelegate> delegate;
|
||||
|
||||
/**
|
||||
* This method loads the player with the given video ID.
|
||||
* This is a convenience method for calling WKYTPlayerView::loadPlayerWithVideoId:withPlayerVars:
|
||||
* without player variables.
|
||||
*
|
||||
* This method reloads the entire contents of the WKWebView and regenerates its HTML contents.
|
||||
* To change the currently loaded video without reloading the entire WKWebView, use the
|
||||
* WKYTPlayerView::cueVideoById:startSeconds:suggestedQuality: family of methods.
|
||||
*
|
||||
* @param videoId The YouTube video ID of the video to load in the player view.
|
||||
* @return YES if player has been configured correctly, NO otherwise.
|
||||
*/
|
||||
- (BOOL)loadWithVideoId:(nonnull NSString *)videoId;
|
||||
|
||||
/**
|
||||
* This method loads the player with the given playlist ID.
|
||||
* This is a convenience method for calling WKYTPlayerView::loadWithPlaylistId:withPlayerVars:
|
||||
* without player variables.
|
||||
*
|
||||
* This method reloads the entire contents of the WKWebView and regenerates its HTML contents.
|
||||
* To change the currently loaded video without reloading the entire WKWebView, use the
|
||||
* WKYTPlayerView::cuePlaylistByPlaylistId:index:startSeconds:suggestedQuality:
|
||||
* family of methods.
|
||||
*
|
||||
* @param playlistId The YouTube playlist ID of the playlist to load in the player view.
|
||||
* @return YES if player has been configured correctly, NO otherwise.
|
||||
*/
|
||||
- (BOOL)loadWithPlaylistId:(nonnull NSString *)playlistId;
|
||||
|
||||
/**
|
||||
* This method loads the player with the given video ID and player variables. Player variables
|
||||
* specify optional parameters for video playback. For instance, to play a YouTube
|
||||
* video inline, the following playerVars dictionary would be used:
|
||||
*
|
||||
* @code
|
||||
* @{ @"playsinline" : @1 };
|
||||
* @endcode
|
||||
*
|
||||
* Note that when the documentation specifies a valid value as a number (typically 0, 1 or 2),
|
||||
* both strings and integers are valid values. The full list of parameters is defined at:
|
||||
* https://developers.google.com/youtube/player_parameters?playerVersion=HTML5.
|
||||
*
|
||||
* This method reloads the entire contents of the WKWebView and regenerates its HTML contents.
|
||||
* To change the currently loaded video without reloading the entire WKWebView, use the
|
||||
* WKYTPlayerView::cueVideoById:startSeconds:suggestedQuality: family of methods.
|
||||
*
|
||||
* @param videoId The YouTube video ID of the video to load in the player view.
|
||||
* @param playerVars An NSDictionary of player parameters.
|
||||
* @return YES if player has been configured correctly, NO otherwise.
|
||||
*/
|
||||
- (BOOL)loadWithVideoId:(nonnull NSString *)videoId playerVars:(nullable NSDictionary *)playerVars;
|
||||
|
||||
/**
|
||||
* This method loads the player with the given video ID and player variables. Player variables
|
||||
* specify optional parameters for video playback. For instance, to play a YouTube
|
||||
* video inline, the following playerVars dictionary would be used:
|
||||
*
|
||||
* @code
|
||||
* @{ @"playsinline" : @1 };
|
||||
* @endcode
|
||||
*
|
||||
* Note that when the documentation specifies a valid value as a number (typically 0, 1 or 2),
|
||||
* both strings and integers are valid values. The full list of parameters is defined at:
|
||||
* https://developers.google.com/youtube/player_parameters?playerVersion=HTML5.
|
||||
*
|
||||
* This method reloads the entire contents of the WKWebView and regenerates its HTML contents.
|
||||
* To change the currently loaded video without reloading the entire WKWebView, use the
|
||||
* WKYTPlayerView::cueVideoById:startSeconds:suggestedQuality: family of methods.
|
||||
*
|
||||
* @param videoId The YouTube video ID of the video to load in the player view.
|
||||
* @param playerVars An NSDictionary of player parameters.
|
||||
* @param path String with the path for HTML template used for viewing video.
|
||||
* @return YES if player has been configured correctly, NO otherwise.
|
||||
*/
|
||||
- (BOOL)loadWithVideoId:(nonnull NSString *)videoId playerVars:(nullable NSDictionary *)playerVars templatePath:(nullable NSString *)path;
|
||||
|
||||
/**
|
||||
* This method loads the player with the given playlist ID and player variables. Player variables
|
||||
* specify optional parameters for video playback. For instance, to play a YouTube
|
||||
* video inline, the following playerVars dictionary would be used:
|
||||
*
|
||||
* @code
|
||||
* @{ @"playsinline" : @1 };
|
||||
* @endcode
|
||||
*
|
||||
* Note that when the documentation specifies a valid value as a number (typically 0, 1 or 2),
|
||||
* both strings and integers are valid values. The full list of parameters is defined at:
|
||||
* https://developers.google.com/youtube/player_parameters?playerVersion=HTML5.
|
||||
*
|
||||
* This method reloads the entire contents of the WKWebView and regenerates its HTML contents.
|
||||
* To change the currently loaded video without reloading the entire WKWebView, use the
|
||||
* WKYTPlayerView::cuePlaylistByPlaylistId:index:startSeconds:suggestedQuality:
|
||||
* family of methods.
|
||||
*
|
||||
* @param playlistId The YouTube playlist ID of the playlist to load in the player view.
|
||||
* @param playerVars An NSDictionary of player parameters.
|
||||
* @return YES if player has been configured correctly, NO otherwise.
|
||||
*/
|
||||
- (BOOL)loadWithPlaylistId:(nonnull NSString *)playlistId playerVars:(nullable NSDictionary *)playerVars;
|
||||
|
||||
/**
|
||||
* This method loads an iframe player with the given player parameters. Usually you may want to use
|
||||
* -loadWithVideoId:playerVars: or -loadWithPlaylistId:playerVars: instead of this method does not handle
|
||||
* video_id or playlist_id at all. The full list of parameters is defined at:
|
||||
* https://developers.google.com/youtube/player_parameters?playerVersion=HTML5.
|
||||
*
|
||||
* @param additionalPlayerParams An NSDictionary of parameters in addition to required parameters
|
||||
* to instantiate the HTML5 player with. This differs depending on
|
||||
* whether a single video or playlist is being loaded.
|
||||
* @return YES if successful, NO if not.
|
||||
*/
|
||||
- (BOOL)loadWithPlayerParams:(nullable NSDictionary *)additionalPlayerParams;
|
||||
|
||||
#pragma mark - Player controls
|
||||
|
||||
// These methods correspond to their JavaScript equivalents as documented here:
|
||||
// https://developers.google.com/youtube/iframe_api_reference#Playback_controls
|
||||
|
||||
/**
|
||||
* Starts or resumes playback on the loaded video. Corresponds to this method from
|
||||
* the JavaScript API:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#playVideo
|
||||
*/
|
||||
- (void)playVideo;
|
||||
|
||||
/**
|
||||
* Pauses playback on a playing video. Corresponds to this method from
|
||||
* the JavaScript API:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#pauseVideo
|
||||
*/
|
||||
- (void)pauseVideo;
|
||||
|
||||
/**
|
||||
* Stops playback on a playing video. Corresponds to this method from
|
||||
* the JavaScript API:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#stopVideo
|
||||
*/
|
||||
- (void)stopVideo;
|
||||
|
||||
/**
|
||||
* Seek to a given time on a playing video. Corresponds to this method from
|
||||
* the JavaScript API:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#seekTo
|
||||
*
|
||||
* @param seekToSeconds The time in seconds to seek to in the loaded video.
|
||||
* @param allowSeekAhead Whether to make a new request to the server if the time is
|
||||
* outside what is currently buffered. Recommended to set to YES.
|
||||
*/
|
||||
- (void)seekToSeconds:(float)seekToSeconds allowSeekAhead:(BOOL)allowSeekAhead;
|
||||
|
||||
#pragma mark - Queuing videos
|
||||
|
||||
// Queueing functions for videos. These methods correspond to their JavaScript
|
||||
// equivalents as documented here:
|
||||
// https://developers.google.com/youtube/iframe_api_reference#Queueing_Functions
|
||||
|
||||
/**
|
||||
* Cues a given video by its video ID for playback starting at the given time and with the
|
||||
* suggested quality. Cueing loads a video, but does not start video playback. This method
|
||||
* corresponds with its JavaScript API equivalent as documented here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#cueVideoById
|
||||
*
|
||||
* @param videoId A video ID to cue.
|
||||
* @param startSeconds Time in seconds to start the video when WKYTPlayerView::playVideo is called.
|
||||
* @param suggestedQuality WKYTPlaybackQuality value suggesting a playback quality.
|
||||
*/
|
||||
- (void)cueVideoById:(nonnull NSString *)videoId
|
||||
startSeconds:(float)startSeconds
|
||||
suggestedQuality:(WKYTPlaybackQuality)suggestedQuality;
|
||||
|
||||
/**
|
||||
* Cues a given video by its video ID for playback starting and ending at the given times
|
||||
* with the suggested quality. Cueing loads a video, but does not start video playback. This
|
||||
* method corresponds with its JavaScript API equivalent as documented here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#cueVideoById
|
||||
*
|
||||
* @param videoId A video ID to cue.
|
||||
* @param startSeconds Time in seconds to start the video when playVideo() is called.
|
||||
* @param endSeconds Time in seconds to end the video after it begins playing.
|
||||
* @param suggestedQuality WKYTPlaybackQuality value suggesting a playback quality.
|
||||
*/
|
||||
- (void)cueVideoById:(nonnull NSString *)videoId
|
||||
startSeconds:(float)startSeconds
|
||||
endSeconds:(float)endSeconds
|
||||
suggestedQuality:(WKYTPlaybackQuality)suggestedQuality;
|
||||
|
||||
/**
|
||||
* Loads a given video by its video ID for playback starting at the given time and with the
|
||||
* suggested quality. Loading a video both loads it and begins playback. This method
|
||||
* corresponds with its JavaScript API equivalent as documented here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#loadVideoById
|
||||
*
|
||||
* @param videoId A video ID to load and begin playing.
|
||||
* @param startSeconds Time in seconds to start the video when it has loaded.
|
||||
* @param suggestedQuality WKYTPlaybackQuality value suggesting a playback quality.
|
||||
*/
|
||||
- (void)loadVideoById:(nonnull NSString *)videoId
|
||||
startSeconds:(float)startSeconds
|
||||
suggestedQuality:(WKYTPlaybackQuality)suggestedQuality;
|
||||
|
||||
/**
|
||||
* Loads a given video by its video ID for playback starting and ending at the given times
|
||||
* with the suggested quality. Loading a video both loads it and begins playback. This method
|
||||
* corresponds with its JavaScript API equivalent as documented here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#loadVideoById
|
||||
*
|
||||
* @param videoId A video ID to load and begin playing.
|
||||
* @param startSeconds Time in seconds to start the video when it has loaded.
|
||||
* @param endSeconds Time in seconds to end the video after it begins playing.
|
||||
* @param suggestedQuality WKYTPlaybackQuality value suggesting a playback quality.
|
||||
*/
|
||||
- (void)loadVideoById:(nonnull NSString *)videoId
|
||||
startSeconds:(float)startSeconds
|
||||
endSeconds:(float)endSeconds
|
||||
suggestedQuality:(WKYTPlaybackQuality)suggestedQuality;
|
||||
|
||||
/**
|
||||
* Cues a given video by its URL on YouTube.com for playback starting at the given time
|
||||
* and with the suggested quality. Cueing loads a video, but does not start video playback.
|
||||
* This method corresponds with its JavaScript API equivalent as documented here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#cueVideoByUrl
|
||||
*
|
||||
* @param videoURL URL of a YouTube video to cue for playback.
|
||||
* @param startSeconds Time in seconds to start the video when WKYTPlayerView::playVideo is called.
|
||||
* @param suggestedQuality WKYTPlaybackQuality value suggesting a playback quality.
|
||||
*/
|
||||
- (void)cueVideoByURL:(nonnull NSString *)videoURL
|
||||
startSeconds:(float)startSeconds
|
||||
suggestedQuality:(WKYTPlaybackQuality)suggestedQuality;
|
||||
|
||||
/**
|
||||
* Cues a given video by its URL on YouTube.com for playback starting at the given time
|
||||
* and with the suggested quality. Cueing loads a video, but does not start video playback.
|
||||
* This method corresponds with its JavaScript API equivalent as documented here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#cueVideoByUrl
|
||||
*
|
||||
* @param videoURL URL of a YouTube video to cue for playback.
|
||||
* @param startSeconds Time in seconds to start the video when WKYTPlayerView::playVideo is called.
|
||||
* @param endSeconds Time in seconds to end the video after it begins playing.
|
||||
* @param suggestedQuality WKYTPlaybackQuality value suggesting a playback quality.
|
||||
*/
|
||||
- (void)cueVideoByURL:(nonnull NSString *)videoURL
|
||||
startSeconds:(float)startSeconds
|
||||
endSeconds:(float)endSeconds
|
||||
suggestedQuality:(WKYTPlaybackQuality)suggestedQuality;
|
||||
|
||||
/**
|
||||
* Loads a given video by its video ID for playback starting at the given time
|
||||
* with the suggested quality. Loading a video both loads it and begins playback. This method
|
||||
* corresponds with its JavaScript API equivalent as documented here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#loadVideoByUrl
|
||||
*
|
||||
* @param videoURL URL of a YouTube video to load and play.
|
||||
* @param startSeconds Time in seconds to start the video when it has loaded.
|
||||
* @param suggestedQuality WKYTPlaybackQuality value suggesting a playback quality.
|
||||
*/
|
||||
- (void)loadVideoByURL:(nonnull NSString *)videoURL
|
||||
startSeconds:(float)startSeconds
|
||||
suggestedQuality:(WKYTPlaybackQuality)suggestedQuality;
|
||||
|
||||
/**
|
||||
* Loads a given video by its video ID for playback starting and ending at the given times
|
||||
* with the suggested quality. Loading a video both loads it and begins playback. This method
|
||||
* corresponds with its JavaScript API equivalent as documented here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#loadVideoByUrl
|
||||
*
|
||||
* @param videoURL URL of a YouTube video to load and play.
|
||||
* @param startSeconds Time in seconds to start the video when it has loaded.
|
||||
* @param endSeconds Time in seconds to end the video after it begins playing.
|
||||
* @param suggestedQuality WKYTPlaybackQuality value suggesting a playback quality.
|
||||
*/
|
||||
- (void)loadVideoByURL:(nonnull NSString *)videoURL
|
||||
startSeconds:(float)startSeconds
|
||||
endSeconds:(float)endSeconds
|
||||
suggestedQuality:(WKYTPlaybackQuality)suggestedQuality;
|
||||
|
||||
#pragma mark - Queuing functions for playlists
|
||||
|
||||
// Queueing functions for playlists. These methods correspond to
|
||||
// the JavaScript methods defined here:
|
||||
// https://developers.google.com/youtube/js_api_reference#Playlist_Queueing_Functions
|
||||
|
||||
/**
|
||||
* Cues a given playlist with the given ID. The |index| parameter specifies the 0-indexed
|
||||
* position of the first video to play, starting at the given time and with the
|
||||
* suggested quality. Cueing loads a playlist, but does not start video playback. This method
|
||||
* corresponds with its JavaScript API equivalent as documented here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#cuePlaylist
|
||||
*
|
||||
* @param playlistId Playlist ID of a YouTube playlist to cue.
|
||||
* @param index A 0-indexed position specifying the first video to play.
|
||||
* @param startSeconds Time in seconds to start the video when WKYTPlayerView::playVideo is called.
|
||||
* @param suggestedQuality WKYTPlaybackQuality value suggesting a playback quality.
|
||||
*/
|
||||
- (void)cuePlaylistByPlaylistId:(nonnull NSString *)playlistId
|
||||
index:(int)index
|
||||
startSeconds:(float)startSeconds
|
||||
suggestedQuality:(WKYTPlaybackQuality)suggestedQuality;
|
||||
|
||||
/**
|
||||
* Cues a playlist of videos with the given video IDs. The |index| parameter specifies the
|
||||
* 0-indexed position of the first video to play, starting at the given time and with the
|
||||
* suggested quality. Cueing loads a playlist, but does not start video playback. This method
|
||||
* corresponds with its JavaScript API equivalent as documented here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#cuePlaylist
|
||||
*
|
||||
* @param videoIds An NSArray of video IDs to compose the playlist of.
|
||||
* @param index A 0-indexed position specifying the first video to play.
|
||||
* @param startSeconds Time in seconds to start the video when WKYTPlayerView::playVideo is called.
|
||||
* @param suggestedQuality WKYTPlaybackQuality value suggesting a playback quality.
|
||||
*/
|
||||
- (void)cuePlaylistByVideos:(nonnull NSArray *)videoIds
|
||||
index:(int)index
|
||||
startSeconds:(float)startSeconds
|
||||
suggestedQuality:(WKYTPlaybackQuality)suggestedQuality;
|
||||
|
||||
/**
|
||||
* Loads a given playlist with the given ID. The |index| parameter specifies the 0-indexed
|
||||
* position of the first video to play, starting at the given time and with the
|
||||
* suggested quality. Loading a playlist starts video playback. This method
|
||||
* corresponds with its JavaScript API equivalent as documented here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#loadPlaylist
|
||||
*
|
||||
* @param playlistId Playlist ID of a YouTube playlist to cue.
|
||||
* @param index A 0-indexed position specifying the first video to play.
|
||||
* @param startSeconds Time in seconds to start the video when WKYTPlayerView::playVideo is called.
|
||||
* @param suggestedQuality WKYTPlaybackQuality value suggesting a playback quality.
|
||||
*/
|
||||
- (void)loadPlaylistByPlaylistId:(nonnull NSString *)playlistId
|
||||
index:(int)index
|
||||
startSeconds:(float)startSeconds
|
||||
suggestedQuality:(WKYTPlaybackQuality)suggestedQuality;
|
||||
|
||||
/**
|
||||
* Loads a playlist of videos with the given video IDs. The |index| parameter specifies the
|
||||
* 0-indexed position of the first video to play, starting at the given time and with the
|
||||
* suggested quality. Loading a playlist starts video playback. This method
|
||||
* corresponds with its JavaScript API equivalent as documented here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#loadPlaylist
|
||||
*
|
||||
* @param videoIds An NSArray of video IDs to compose the playlist of.
|
||||
* @param index A 0-indexed position specifying the first video to play.
|
||||
* @param startSeconds Time in seconds to start the video when WKYTPlayerView::playVideo is called.
|
||||
* @param suggestedQuality WKYTPlaybackQuality value suggesting a playback quality.
|
||||
*/
|
||||
- (void)loadPlaylistByVideos:(nonnull NSArray *)videoIds
|
||||
index:(int)index
|
||||
startSeconds:(float)startSeconds
|
||||
suggestedQuality:(WKYTPlaybackQuality)suggestedQuality;
|
||||
|
||||
#pragma mark - Playing a video in a playlist
|
||||
|
||||
// These methods correspond to the JavaScript API as defined under the
|
||||
// "Playing a video in a playlist" section here:
|
||||
// https://developers.google.com/youtube/iframe_api_reference#Playback_status
|
||||
|
||||
/**
|
||||
* Loads and plays the next video in the playlist. Corresponds to this method from
|
||||
* the JavaScript API:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#nextVideo
|
||||
*/
|
||||
- (void)nextVideo;
|
||||
|
||||
/**
|
||||
* Loads and plays the previous video in the playlist. Corresponds to this method from
|
||||
* the JavaScript API:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#previousVideo
|
||||
*/
|
||||
- (void)previousVideo;
|
||||
|
||||
/**
|
||||
* Loads and plays the video at the given 0-indexed position in the playlist.
|
||||
* Corresponds to this method from the JavaScript API:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#playVideoAt
|
||||
*
|
||||
* @param index The 0-indexed position of the video in the playlist to load and play.
|
||||
*/
|
||||
- (void)playVideoAt:(int)index;
|
||||
|
||||
#pragma mark - Setting the playback rate
|
||||
|
||||
/**
|
||||
* Gets the playback rate. The default value is 1.0, which represents a video
|
||||
* playing at normal speed. Other values may include 0.25 or 0.5 for slower
|
||||
* speeds, and 1.5 or 2.0 for faster speeds. This method corresponds to the
|
||||
* JavaScript API defined here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#getPlaybackRate
|
||||
*/
|
||||
- (void)getPlaybackRate:(void (^ __nullable)(float playbackRate, NSError * __nullable error))completionHandler;
|
||||
|
||||
/**
|
||||
* Sets the playback rate. The default value is 1.0, which represents a video
|
||||
* playing at normal speed. Other values may include 0.25 or 0.5 for slower
|
||||
* speeds, and 1.5 or 2.0 for faster speeds. To fetch a list of valid values for
|
||||
* this method, call WKYTPlayerView::getAvailablePlaybackRates. This method does not
|
||||
* guarantee that the playback rate will change.
|
||||
* This method corresponds to the JavaScript API defined here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#setPlaybackRate
|
||||
*
|
||||
* @param suggestedRate A playback rate to suggest for the player.
|
||||
*/
|
||||
- (void)setPlaybackRate:(float)suggestedRate;
|
||||
|
||||
/**
|
||||
* Gets a list of the valid playback rates, useful in conjunction with
|
||||
* WKYTPlayerView::setPlaybackRate. This method corresponds to the
|
||||
* JavaScript API defined here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#getPlaybackRate
|
||||
*/
|
||||
- (void)getAvailablePlaybackRates:(void (^ __nullable)(NSArray * __nullable availablePlaybackRates, NSError * __nullable error))completionHandler;
|
||||
|
||||
#pragma mark - Setting playback behavior for playlists
|
||||
|
||||
/**
|
||||
* Sets whether the player should loop back to the first video in the playlist
|
||||
* after it has finished playing the last video. This method corresponds to the
|
||||
* JavaScript API defined here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#loopPlaylist
|
||||
*
|
||||
* @param loop A boolean representing whether the player should loop.
|
||||
*/
|
||||
- (void)setLoop:(BOOL)loop;
|
||||
|
||||
/**
|
||||
* Sets whether the player should shuffle through the playlist. This method
|
||||
* corresponds to the JavaScript API defined here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#shufflePlaylist
|
||||
*
|
||||
* @param shuffle A boolean representing whether the player should
|
||||
* shuffle through the playlist.
|
||||
*/
|
||||
- (void)setShuffle:(BOOL)shuffle;
|
||||
|
||||
#pragma mark - Playback status
|
||||
// These methods correspond to the JavaScript methods defined here:
|
||||
// https://developers.google.com/youtube/js_api_reference#Playback_status
|
||||
|
||||
/**
|
||||
* Returns a number between 0 and 1 that specifies the percentage of the video
|
||||
* that the player shows as buffered. This method corresponds to the
|
||||
* JavaScript API defined here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#getVideoLoadedFraction
|
||||
*
|
||||
*/
|
||||
- (void)getVideoLoadedFraction:(void (^ __nullable)(float videoLoadedFraction, NSError * __nullable error))completionHandler;
|
||||
|
||||
/**
|
||||
* Returns the state of the player. This method corresponds to the
|
||||
* JavaScript API defined here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#getPlayerState
|
||||
*
|
||||
*/
|
||||
- (void)getPlayerState:(void (^ __nullable)(WKYTPlayerState playerState, NSError * __nullable error))completionHandler;
|
||||
|
||||
/**
|
||||
* Returns the elapsed time in seconds since the video started playing. This
|
||||
* method corresponds to the JavaScript API defined here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#getCurrentTime
|
||||
*
|
||||
*/
|
||||
- (void)getCurrentTime:(void (^ __nullable)(float currentTime, NSError * __nullable error))completionHandler;
|
||||
|
||||
#pragma mark - Playback quality
|
||||
|
||||
// Playback quality. These methods correspond to the JavaScript
|
||||
// methods defined here:
|
||||
// https://developers.google.com/youtube/js_api_reference#Playback_quality
|
||||
|
||||
/**
|
||||
* Returns the playback quality. This method corresponds to the
|
||||
* JavaScript API defined here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#getPlaybackQuality
|
||||
*
|
||||
*/
|
||||
- (void)getPlaybackQuality:(void (^ __nullable)(WKYTPlaybackQuality playbackQuality, NSError * __nullable error))completionHandler;
|
||||
|
||||
/**
|
||||
* Suggests playback quality for the video. It is recommended to leave this setting to
|
||||
* |default|. This method corresponds to the JavaScript API defined here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#setPlaybackQuality
|
||||
*
|
||||
*/
|
||||
- (void)setPlaybackQuality:(WKYTPlaybackQuality)suggestedQuality;
|
||||
|
||||
/**
|
||||
* Gets a list of the valid playback quality values, useful in conjunction with
|
||||
* WKYTPlayerView::setPlaybackQuality. This method corresponds to the
|
||||
* JavaScript API defined here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#getAvailableQualityLevels
|
||||
*
|
||||
*/
|
||||
- (void)getAvailableQualityLevels:(void (^ __nullable)(NSArray * __nullable availableQualityLevels, NSError * __nullable error))completionHandler;
|
||||
|
||||
#pragma mark - Retrieving video information
|
||||
|
||||
// Retrieving video information. These methods correspond to the JavaScript
|
||||
// methods defined here:
|
||||
// https://developers.google.com/youtube/js_api_reference#Retrieving_video_information
|
||||
|
||||
/**
|
||||
* Returns the duration in seconds since the video of the video. This
|
||||
* method corresponds to the JavaScript API defined here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#getDuration
|
||||
*
|
||||
*/
|
||||
- (void)getDuration:(void (^ __nullable)(NSTimeInterval duration, NSError * __nullable error))completionHandler;
|
||||
|
||||
/**
|
||||
* Returns the YouTube.com URL for the video. This method corresponds
|
||||
* to the JavaScript API defined here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#getVideoUrl
|
||||
*
|
||||
*/
|
||||
- (void)getVideoUrl:(void (^ __nullable)(NSURL * __nullable videoUrl, NSError * __nullable error))completionHandler;
|
||||
|
||||
/**
|
||||
* Returns the embed code for the current video. This method corresponds
|
||||
* to the JavaScript API defined here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#getVideoEmbedCode
|
||||
*
|
||||
*/
|
||||
- (void)getVideoEmbedCode:(void (^ __nullable)(NSString * __nullable videoEmbedCode, NSError * __nullable error))completionHandler;
|
||||
|
||||
#pragma mark - Retrieving playlist information
|
||||
|
||||
// Retrieving playlist information. These methods correspond to the
|
||||
// JavaScript defined here:
|
||||
// https://developers.google.com/youtube/js_api_reference#Retrieving_playlist_information
|
||||
|
||||
/**
|
||||
* Returns an ordered array of video IDs in the playlist. This method corresponds
|
||||
* to the JavaScript API defined here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#getPlaylist
|
||||
*
|
||||
*/
|
||||
- (void)getPlaylist:(void (^ __nullable)(NSArray * __nullable playlist, NSError * __nullable error))completionHandler;
|
||||
|
||||
/**
|
||||
* Returns the 0-based index of the currently playing item in the playlist.
|
||||
* This method corresponds to the JavaScript API defined here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#getPlaylistIndex
|
||||
*
|
||||
*/
|
||||
- (void)getPlaylistIndex:(void (^ __nullable)(int playlistIndex, NSError * __nullable error))completionHandler;
|
||||
|
||||
#pragma mark - Mute
|
||||
|
||||
/**
|
||||
* Mutes the player. Corresponds to this method from
|
||||
* the JavaScript API:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#mute
|
||||
*/
|
||||
- (void)mute;
|
||||
|
||||
/**
|
||||
* Unmutes the player. Corresponds to this method from
|
||||
* the JavaScript API:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#unMute
|
||||
*/
|
||||
- (void)unMute;
|
||||
|
||||
/**
|
||||
* Returns true if the player is muted, false if not.
|
||||
* This method corresponds to the JavaScript API defined here:
|
||||
* https://developers.google.com/youtube/iframe_api_reference#getVolume
|
||||
*
|
||||
*/
|
||||
- (void)isMuted:(void (^ __nullable)(BOOL isMuted, NSError * __nullable error))completionHandler;
|
||||
|
||||
|
||||
#pragma mark - Exposed for Testing
|
||||
|
||||
/**
|
||||
* Removes the internal web view from this player view.
|
||||
* Intended to use for testing, should not be used in production code.
|
||||
*/
|
||||
- (void)removeWebView;
|
||||
|
||||
@end
|
||||
1123
ios/Pods/YoutubePlayer-in-WKWebView/WKYTPlayerView/WKYTPlayerView.m
generated
Normal file
1123
ios/Pods/YoutubePlayer-in-WKWebView/WKYTPlayerView/WKYTPlayerView.m
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -40,6 +40,7 @@ const config = {
|
|||
};
|
||||
},
|
||||
},
|
||||
maxWorkers: 4,
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
|
|
|
|||
Loading…
Reference in a new issue