cocoapods-privacy 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +74 -2
- data/lib/cocoapods-privacy/gem_version.rb +1 -1
- data/lib/cocoapods-privacy/privacy/PrivacyHunter.rb +27 -8
- data/lib/cocoapods-privacy/privacy/PrivacyModule.rb +8 -3
- data/lib/cocoapods-privacy/privacy/PrivacyUtils.rb +6 -0
- data/lib/cocoapods-privacy/privacy/privacy_installer_hook.rb +3 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 84dea61fc2bc984ef88adabe1aa4de41f27b05dbea00a570ae1dc2e2a43966e3
|
4
|
+
data.tar.gz: 61ba57f0692ca5c5034379f0c1abc02c7dd6b69048c3fe033981115b2f729c63
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f5c68b15d9089e1cd43732c1f33e302748e4d8bbb6abf6c74394d5ce3bdd4bf57e5fe1a26dfba9ce6530b9f12e9b1deda38fc73e3089f8f0778b746a94d75867
|
7
|
+
data.tar.gz: 76a55bb3e4486e640ff20a909863f49cdf3e19b120c06e28346e6898a9cc9d745a8568b197d230abc925b240660cf3c11de18fd8b7756fdf8346c23805f4dc27
|
data/README.md
CHANGED
@@ -1,11 +1,83 @@
|
|
1
1
|
# cocoapods-privacy
|
2
2
|
|
3
|
-
|
3
|
+
Apple 2024 will review the App's privacy list in the spring, and any apps that don't submit a privacy list may be called back. For now, the privacy list is broken down by component, to facilitate the maintenance of component privacy, cocoapods-privacy is developed for management.
|
4
|
+
[Click to view details on Apple](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files)
|
4
5
|
|
5
6
|
## Installation
|
6
7
|
|
7
8
|
$ gem install cocoapods-privacy
|
8
9
|
|
9
10
|
## Usage
|
11
|
+
#### init
|
12
|
+
First of all, you must set a json config to cocoapods-privacy, this is a defalut config.json
|
13
|
+
```
|
14
|
+
$ pod privacy config https://raw.githubusercontent.com/ymoyao/cocoapods-privacy/main/resources/config.json
|
15
|
+
```
|
16
|
+
|
17
|
+
There has 3 keys in defalut config, you should custom it!
|
18
|
+
* source.white.list : a white list of source, defalut is empty, so, you should add you self component sources, and it work in command 'pod privacy install' or 'pod install --privacy', will search white list for NSPrivacyAccessedAPITypes.
|
19
|
+
* source.black.list : a black list of source, defalut is empty, it work in command 'pod privacy install' or 'pod install --privacy'.
|
20
|
+
* api.template.url : its required, a template for search NSPrivacyAccessedAPITypes
|
21
|
+
```
|
22
|
+
"source.white.list": ["replace me with yourserver"],
|
23
|
+
"source.black.list": ["replace me such as github.com"],
|
24
|
+
"api.template.url": "https://raw.githubusercontent.com/ymoyao/cocoapods-privacy/main/resources/NSPrivacyAccessedAPITypes.plist"
|
25
|
+
```
|
26
|
+
|
27
|
+
#### To Component
|
28
|
+
```
|
29
|
+
$ pod privacy spec [podspec_file_path]
|
30
|
+
```
|
31
|
+
This command will auto create privacy file, and search the path of podspec' source_files' define relate to NSPrivacyAccessedAPITypes, finaly, write to PrivacyInfo.xcprivacy file.
|
32
|
+
if your component has much subspec, all subspec that define ‘source_files’ will create PrivacyInfo.xcprivacy, and auto modify .podspec link .xcprivacy to 'resource_bundle' key.
|
33
|
+
For example
|
34
|
+
* origin podspec
|
35
|
+
|
36
|
+
```
|
37
|
+
Pod::Spec.new do |s|
|
38
|
+
s.name = 'Demo'
|
39
|
+
...
|
40
|
+
s.source_files = 'xxxx'
|
41
|
+
s.subspec 'idfa' do |sp|
|
42
|
+
sp.source_files = 'xxxxx'
|
43
|
+
end
|
44
|
+
s.subspec 'noidfa' do |sp|
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
```
|
49
|
+
|
50
|
+
* podspec after commad 👇👇👇👇👇👇
|
51
|
+
```
|
52
|
+
Pod::Spec.new do |s|
|
53
|
+
s.name = 'Demo'
|
54
|
+
...
|
55
|
+
s.source_files = 'xxxx'
|
56
|
+
s.resource_bundle = {"Demo.privacy"=>"Pod/Privacy/Demo/PrivacyInfo.xcprivacy"}
|
57
|
+
s.subspec 'idfa' do |sp|
|
58
|
+
sp.source_files = 'xxxxx'
|
59
|
+
sp.resource_bundle = {"Demo.idfa.privacy"=>"Pod/Privacy/Demo.idfa/PrivacyInfo.xcprivacy"}
|
60
|
+
end
|
61
|
+
s.subspec 'noidfa' do |sp|
|
62
|
+
end
|
63
|
+
end
|
64
|
+
```
|
65
|
+
<img width="961" alt="截屏2024-02-02 11 23 21" src="https://github.com/ymoyao/cocoapods-privacy/assets/13619221/a6678c8e-c4aa-4f7d-8881-657c6d703657">
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
#### To Project
|
70
|
+
```
|
71
|
+
$ pod install --privacy
|
72
|
+
or
|
73
|
+
$ pod privacy install
|
74
|
+
```
|
75
|
+
<img width="298" alt="截屏2024-02-02 10 59 59" src="https://github.com/ymoyao/cocoapods-privacy/assets/13619221/c6f10e36-0f62-497a-93d4-f8b336dc8df4">
|
76
|
+
|
77
|
+
After command, a PrivacyInfo.xcprivacy will create to you project Resources if empty. and it will search component that configuration files allow and do not have their own privacy manifest file.
|
78
|
+
|
79
|
+
## Notice
|
80
|
+
The plugin is focus on NSPrivacyAccessedAPITypes and automatically search and create workflow.
|
81
|
+
you should manager NSPrivacyCollectedDataTypes by yourself!
|
82
|
+
|
10
83
|
|
11
|
-
$ pod spec privacy POD_NAME
|
@@ -116,35 +116,54 @@ module PrivacyHunter
|
|
116
116
|
local_file_path = File.join(PrivacyUtils.cache_privacy_fold, 'NSPrivacyAccessedAPITypes.plist')
|
117
117
|
|
118
118
|
# 获取远程文件更新时间
|
119
|
-
remote_file_time =
|
119
|
+
remote_file_time,etag = remoteFile?(template_url)
|
120
120
|
|
121
121
|
# 判断本地文件的最后修改时间是否与远端文件一致,如果一致则不进行下载
|
122
|
-
if File.exist?(local_file_path) && file_identical?(local_file_path, remote_file_time)
|
122
|
+
if File.exist?(local_file_path) && file_identical?(local_file_path, remote_file_time,etag)
|
123
123
|
else
|
124
124
|
# 使用 curl 下载文件
|
125
125
|
system("curl -o #{local_file_path} #{template_url}")
|
126
126
|
puts "隐私清单模版文件已更新到: #{local_file_path}"
|
127
127
|
|
128
|
-
#
|
129
|
-
|
128
|
+
# 同步远程文件标识(时间或者etag)
|
129
|
+
syncFile?(local_file_path,remote_file_time,etag)
|
130
130
|
end
|
131
131
|
|
132
132
|
local_file_path
|
133
133
|
end
|
134
134
|
|
135
135
|
# 获取远程文件更新时间
|
136
|
-
def self.
|
136
|
+
def self.remoteFile?(remote_url)
|
137
137
|
uri = URI.parse(remote_url)
|
138
138
|
http = Net::HTTP.new(uri.host, uri.port)
|
139
139
|
http.use_ssl = (uri.scheme == 'https')
|
140
140
|
response = http.request_head(uri.path)
|
141
141
|
|
142
|
-
response['Last-Modified']
|
142
|
+
last_modified = response['Last-Modified']
|
143
|
+
etag = response['ETag']
|
144
|
+
|
145
|
+
[last_modified,etag]
|
143
146
|
end
|
144
147
|
|
145
148
|
# 判断本地文件的最后修改时间与远端文件的最后修改时间是否一致
|
146
|
-
def self.file_identical?(local_file_path, remote_file_time)
|
147
|
-
|
149
|
+
def self.file_identical?(local_file_path, remote_file_time, etag)
|
150
|
+
if remote_file_time
|
151
|
+
remote_file_time && Time.parse(remote_file_time) == File.mtime(local_file_path)
|
152
|
+
elsif etag
|
153
|
+
File.exist?(File.join(PrivacyUtils.cache_privacy_etag_fold,etag))
|
154
|
+
else
|
155
|
+
false
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
# 同步文件标识
|
161
|
+
def self.syncFile?(local_file_path, remote_file_time, etag)
|
162
|
+
if remote_file_time
|
163
|
+
syncFileTime?(local_file_path,remote_file_time)
|
164
|
+
elsif etag
|
165
|
+
PrivacyUtils.create_file_and_fold_if_no_exit(File.join(PrivacyUtils.cache_privacy_etag_fold,etag))
|
166
|
+
end
|
148
167
|
end
|
149
168
|
|
150
169
|
# 同步远程文件时间到本地文件
|
@@ -147,16 +147,19 @@ module PrivacyModule
|
|
147
147
|
# 打开 Xcode 项目,在Resources 下创建
|
148
148
|
project = Xcodeproj::Project.open(File.basename(project_path))
|
149
149
|
main_group = project.main_group
|
150
|
-
resources_group =
|
150
|
+
resources_group = main_group.find_subpath('Resources',false)
|
151
151
|
if resources_group.nil?
|
152
152
|
resources_group = main_group.new_group('Resources',resources_folder_path)
|
153
153
|
end
|
154
154
|
|
155
155
|
# 如果不存在引用,创建新的引入xcode引用
|
156
156
|
if resources_group.find_file_by_path(PrivacyUtils.privacy_name).nil?
|
157
|
-
privacy_file_ref = resources_group.new_reference(PrivacyUtils.privacy_name)
|
157
|
+
privacy_file_ref = resources_group.new_reference(PrivacyUtils.privacy_name,:group)
|
158
|
+
privacy_file_ref.last_known_file_type = 'text.xml'
|
158
159
|
target = project.targets.first
|
159
|
-
|
160
|
+
resources_build_phase = target.resources_build_phase
|
161
|
+
resources_build_phase.add_file_reference(privacy_file_ref) # 将文件引用添加到 resources 构建阶段中
|
162
|
+
# target.add_file_references([privacy_file_ref]) # 将文件引用添加到 target 中
|
160
163
|
# resources_group.new_file(privacy_file_path)
|
161
164
|
end
|
162
165
|
|
@@ -171,11 +174,13 @@ module PrivacyModule
|
|
171
174
|
|
172
175
|
# 处理组件
|
173
176
|
def self.load_module(podspec_file_path)
|
177
|
+
puts "👇👇👇👇👇👇 Start analysis component privacy 👇👇👇👇👇👇"
|
174
178
|
privacy_hash = PrivacyModule.check(podspec_file_path)
|
175
179
|
privacy_hash.each do |privacy_file_path, source_files|
|
176
180
|
data = PrivacyHunter.search_pricacy_apis(source_files)
|
177
181
|
PrivacyHunter.write_to_privacy(data,privacy_file_path) unless data.empty?
|
178
182
|
end
|
183
|
+
puts "👆👆👆👆👆👆 End analysis component privacy 👆👆👆👆👆👆"
|
179
184
|
end
|
180
185
|
|
181
186
|
def self.check(podspec_file_path)
|
@@ -61,6 +61,12 @@ module PrivacyUtils
|
|
61
61
|
target_directory
|
62
62
|
end
|
63
63
|
|
64
|
+
# etag 文件夹
|
65
|
+
def self.cache_privacy_etag_fold
|
66
|
+
File.join(cache_privacy_fold,'etag')
|
67
|
+
end
|
68
|
+
|
69
|
+
# config.json 文件
|
64
70
|
def self.cache_config_file
|
65
71
|
config_file = File.join(cache_privacy_fold, 'config.json')
|
66
72
|
end
|
@@ -74,6 +74,8 @@ module Pod
|
|
74
74
|
|
75
75
|
|
76
76
|
def privacy_handle(custom_folds)
|
77
|
+
|
78
|
+
puts "👇👇👇👇👇👇 Start analysis project privacy 👇👇👇👇👇👇"
|
77
79
|
# 过滤出自身组件 && 自身没有隐私协议文件的spec
|
78
80
|
modules = @analysis_result.specifications.select {
|
79
81
|
|obj| obj.is_need_search_module && !obj.has_privacy
|
@@ -118,6 +120,7 @@ module Pod
|
|
118
120
|
# 处理工程隐私协议
|
119
121
|
PrivacyModule.load_project(pod_folds)
|
120
122
|
end
|
123
|
+
puts "👆👆👆👆👆👆 End analysis project privacy 👆👆👆👆👆👆"
|
121
124
|
end
|
122
125
|
end
|
123
126
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cocoapods-privacy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- youhui
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-02-
|
11
|
+
date: 2024-02-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|