Compare commits

...

189 commits

Author SHA1 Message Date
fmodf dfa9ce3ec5 roster get 2024-03-03 20:07:16 +04:00
fmodf ed82109382 Merge pull request 'feature/calls-maket' (#5) from feature/calls-maket into xmpp-lib
Reviewed-on: #5
2024-01-28 07:30:10 +00:00
fmodf 0f5019252b implement SCRAM-SHA-1 SASL 2024-01-15 19:20:13 +04:00
fmodf 2e16f4a879 wip 2024-01-12 23:14:50 +04:00
fmodf 930a73168d wip 2024-01-12 23:14:41 +04:00
fmodf 2de949c410 wip 2024-01-12 19:26:59 +04:00
fmodf f6a9b6b163 wip 2024-01-09 22:22:07 +04:00
fmodf 8026771490 wip 2024-01-09 22:16:43 +04:00
fmodf c559fab590 wip 2024-01-09 22:16:22 +04:00
fmodf 865b2881ba reg upd 2023-12-05 17:14:07 +04:00
fmodf 4a64621746 wip 2023-12-05 14:53:07 +04:00
fmodf d948a10117 wip 2023-11-28 17:36:57 +04:00
fmodf 9850213f80 wip 2023-11-28 17:36:39 +04:00
fmodf 4c03959aa8 wip 2023-11-21 20:14:02 +04:00
fmodf 93df47b6ae wip 2023-11-21 17:40:13 +04:00
fmodf b55dfe98fd wip 2023-11-21 16:39:39 +04:00
fmodf 089c47c1a4 wip 2023-11-21 16:18:24 +04:00
fmodf 7f3ec8b754 wip 2023-11-21 15:55:34 +04:00
fmodf d9e8b01b2f wip 2023-11-21 13:26:35 +04:00
fmodf bba24a4929 wip 2023-11-21 12:57:44 +04:00
fmodf ba93689d26 wip 2023-11-21 12:36:16 +04:00
fmodf 64d948eea9 wip 2023-11-15 16:01:04 +04:00
fmodf b0ee26bd62 webrtc 2023-11-14 20:09:33 +04:00
fmodf a68a0b781c wip 2023-11-14 18:11:52 +04:00
fmodf c7997f438d prepare call 2023-11-14 17:41:30 +04:00
fmodf 389d9d44a1 discovering external services 2023-11-14 17:08:45 +04:00
fmodf a09087ffe4 resource binding 2023-11-14 16:12:32 +04:00
fmodf 016b3511b6 wip 2023-11-14 15:38:55 +04:00
fmodf 6a6a077b85 quick resource binding 2023-11-14 15:37:50 +04:00
fmodf 46a358e926 fix stream 2023-11-13 21:24:26 +04:00
fmodf 601d2b9152 request ext services 2023-11-13 19:15:39 +04:00
fmodf b1604ab115 Merge pull request 'feature/auth' (#4) from feature/auth into xmpp-lib
Reviewed-on: #4
2023-11-08 17:06:33 +00:00
fmodf 6c911652d5 wip 2023-11-08 21:04:29 +04:00
fmodf 58aa50e730 wip 2023-11-08 16:57:46 +04:00
fmodf 4af286ecee wip 2023-11-08 14:44:26 +04:00
fmodf 8d85a81e70 wip 2023-11-07 00:18:40 +04:00
fmodf 8fadc53470 wip 2023-11-06 23:55:21 +04:00
fmodf e45bbbecd2 wip 2023-11-06 22:26:28 +04:00
fmodf 0b7e1e5b81 fix parser 2023-10-23 14:25:24 +04:00
fmodf df2ea2eefb Merge pull request 'feature/way-around' (#3) from feature/way-around into xmpp-lib
Reviewed-on: #3
2023-10-12 05:33:33 +00:00
fmodf 8f9eced353 fix 2023-10-12 09:32:23 +04:00
fmodf e1d7393139 wip 2023-10-12 09:15:10 +04:00
fmodf afad9d9641 wip 2023-10-12 08:41:13 +04:00
fmodf 5df60e82cd wip 2023-10-12 08:37:26 +04:00
fmodf 697624e2f9 wip 2023-10-12 08:22:15 +04:00
fmodf 9e6a3cc5c7 wip 2023-10-12 07:00:19 +04:00
fmodf e288e44d45 wip 2023-10-12 05:33:30 +04:00
fmodf d5872f47db wip 2023-10-12 05:07:21 +04:00
fmodf 673097831e wip 2023-10-12 04:57:09 +04:00
fmodf 9c4f8b9f4e wip 2023-10-12 04:19:24 +04:00
fmodf 4afea365a2 wip 2023-10-11 23:55:11 +04:00
fmodf 4cd68fa756 wip 2023-10-11 23:44:39 +04:00
fmodf d655e72336 wip 2023-10-11 20:43:14 +04:00
fmodf d5f97dbf24 wip 2023-10-11 09:41:26 +04:00
fmodf aaaa8a3dd8 wip 2023-10-11 09:24:42 +04:00
fmodf 6373ded7c0 wip 2023-10-10 10:59:11 +04:00
fmodf b48686ec9e wip 2023-10-10 05:30:25 +04:00
fmodf 1a397a4643 wip 2023-10-10 05:14:24 +04:00
fmodf d81094c024 wip 2023-10-09 18:23:02 +04:00
fmodf e781e76f43 wip 2023-10-06 17:58:45 +04:00
fmodf df56001998 wip 2023-10-06 17:24:48 +04:00
fmodf 8b4e50de7c wip 2023-10-06 16:56:26 +04:00
fmodf 2b1674a35e wip 2023-10-04 16:16:34 +04:00
fmodf de5f593072 wip 2023-10-04 06:07:30 +04:00
fmodf 50633b2f7a wip 2023-10-04 03:28:53 +04:00
fmodf 4ed380afd1 wip 2023-10-04 00:31:09 +04:00
fmodf 87ca6b0978 wip 2023-10-03 20:36:42 +04:00
fmodf 9c6522839f wip 2023-10-01 17:58:43 +04:00
fmodf aaf2a0a39d wip 2023-09-30 17:19:03 +04:00
fmodf 423c1be232 wip 2023-09-30 16:16:57 +04:00
fmodf 3cf73bfdea wip 2023-09-28 15:51:08 +04:00
fmodf 8845370bf0 wip 2023-09-28 12:16:58 +04:00
fmodf 89765241a3 wip 2023-09-27 19:16:24 +04:00
fmodf 9654667af0 wip 2023-09-27 15:05:35 +04:00
fmodf 354e9df0ef wip 2023-09-27 11:48:47 +04:00
fmodf 0554b1d262 wip 2023-09-27 10:26:18 +04:00
fmodf 70446adbd1 wip 2023-09-27 10:05:14 +04:00
fmodf 5925e07011 wip 2023-09-27 09:59:19 +04:00
fmodf 7da120521b wip 2023-09-27 02:20:40 +04:00
fmodf 446271d7ba wip 2023-09-27 01:35:31 +04:00
fmodf 5c9143b9dc wip 2023-09-27 01:02:03 +04:00
fmodf 768378e05f wip 2023-09-27 00:21:12 +04:00
fmodf ae9843b61c wip 2023-09-26 23:53:46 +04:00
fmodf f38560fb2d wip 2023-09-26 22:39:36 +04:00
fmodf f45fb69997 wip 2023-09-26 22:10:22 +04:00
fmodf 64047eb936 wip 2023-09-26 21:35:36 +04:00
fmodf 57010e7fae wip 2023-09-26 20:21:52 +04:00
fmodf ad94afa92b wip 2023-09-26 19:22:13 +04:00
fmodf 79272bc220 wip 2023-09-26 00:13:49 +04:00
fmodf 51122902a3 wip 2023-09-25 23:58:40 +04:00
fmodf 6ef0e3ec33 refactoring xml parser 2023-09-25 21:49:48 +04:00
fmodf 68ce04fd1f wip 2023-09-25 20:54:35 +04:00
fmodf 6bffcedb0d wip 2023-09-25 19:08:28 +04:00
fmodf 9397f83f95 wip 2023-09-25 18:19:26 +04:00
fmodf 1c0ce668a4 wip 2023-09-25 17:58:35 +04:00
fmodf b0031d1e50 wip 2023-09-25 16:51:07 +04:00
fmodf d7b597ca0d wip 2023-09-25 15:12:20 +04:00
fmodf 5e9e53dbce wip 2023-09-24 19:55:01 +04:00
fmodf a8bca45732 wip 2023-09-24 19:17:40 +04:00
fmodf e1e4095589 wip 2023-09-24 18:02:13 +04:00
fmodf f92929c829 wip 2023-09-24 17:26:08 +04:00
fmodf 0d30dd199f back to in-app udf 2023-09-24 17:14:58 +04:00
fmodf 0fc7f682d8 wip 2023-09-24 16:20:49 +04:00
fmodf 20265255e7 wip 2023-09-24 16:15:32 +04:00
fmodf 2fed518d81 wip 2023-09-24 02:45:40 +04:00
fmodf eb74ad27e3 wip 2023-09-23 20:39:11 +04:00
fmodf c400da7fb8 wip 2023-09-23 19:41:57 +04:00
fmodf 05c6a5698a wip 2023-09-23 19:35:34 +04:00
fmodf 332b903d6d wip 2023-09-23 19:00:24 +04:00
fmodf 27e6096042 wip 2023-09-23 18:59:45 +04:00
fmodf de06b3c323 wip 2023-09-23 18:39:04 +04:00
fmodf a764385379 wip 2023-09-23 18:30:31 +04:00
fmodf a1f8aa0a82 wip 2023-09-23 18:03:17 +04:00
fmodf 4f4e8b0a89 wip 2023-09-23 15:55:09 +04:00
fmodf 752d8ee4af wip 2023-09-23 15:30:44 +04:00
fmodf 5a87fd419d socket connector 2023-09-22 17:40:08 +04:00
fmodf a7928efbf2 wip 2023-09-22 06:15:17 +04:00
fmodf 8f4d574f19 add dns resolver 2023-09-19 23:35:13 +04:00
fmodf ff891869be wip 2023-09-19 18:58:51 +04:00
fmodf be0061921e wip 2023-09-19 05:53:31 +04:00
fmodf 58c612d6a2 migrate to realm, safe checkpoint 2023-09-19 03:13:33 +04:00
fmodf affc5afdc9 wip 2023-09-18 23:40:48 +04:00
fmodf 57dc5e1d81 UI wip 2023-09-18 19:37:53 +04:00
fmodf 7eae6c295c wip 2023-09-18 01:04:55 +04:00
fmodf 73f0f8762f wip 2023-09-17 23:30:27 +04:00
fmodf 16c0208f21 wip 2023-09-17 19:30:32 +04:00
fmodf 26269c6118 wip 2023-09-17 19:25:03 +04:00
fmodf 118c9b6efa UI go brrr 2023-09-17 18:04:00 +04:00
fmodf 4be16a9656 ui 2023-09-16 03:51:01 +04:00
fmodf ec3092f199 fix db 2023-09-16 00:40:16 +04:00
fmodf de7be9ea68 wip 2023-09-15 23:14:49 +04:00
fmodf fbf8df2c9a update db 2023-09-15 20:24:57 +04:00
fmodf 3f4a2d4cde update sqlite database, add migration mechanism 2023-09-15 20:03:55 +04:00
fmodf 3d4ade5346 wip 2023-09-15 18:10:12 +04:00
fmodf c0a19d86fd wip 2023-09-15 00:28:03 +04:00
fmodf a45479d0c6 fix build errors 2023-09-14 20:11:40 +04:00
fmodf 48d7030090 Merge pull request 'feature/new-target' (#2) from feature/new-target into develop
Reviewed-on: #2
2023-09-14 15:00:23 +00:00
fmodf 2d8019217a add local package 2023-09-14 18:58:53 +04:00
fmodf 43dde437c5 add packages 2023-09-14 16:29:48 +04:00
fmodf 20db5d5f2d add colors from dino, add swiftgen 2023-09-12 22:04:56 +04:00
fmodf 7424e9171a app template 2023-09-11 18:40:58 +04:00
fmodf 6906c094ea upd project 2023-09-11 17:32:07 +04:00
fmodf 3ab551e8de wip 2023-09-11 17:06:34 +04:00
fmodf 1c745f2b25 wip 2023-09-11 16:45:34 +04:00
fmodf 4717aa8649 linter update 2023-09-11 16:24:37 +04:00
fmodf f387236d9d wip 2023-09-11 16:22:16 +04:00
fmodf 80c56f1d48 wip 2023-09-11 16:21:44 +04:00
fmodf 43f01272ab wip 2023-09-11 16:13:44 +04:00
fmodf 1a51090b03 wip 2023-09-11 15:41:19 +04:00
fmodf dba6463116 wip 2023-09-11 15:37:44 +04:00
fmodf 1f414b9344 new multiplatform target 2023-09-11 15:11:45 +04:00
fmodf fc4610192b move old sources 2023-09-11 14:45:21 +04:00
fmodf 50feee4f74 Merge pull request 'feature/project-update' (#1) from feature/project-update into develop
Reviewed-on: #1
2023-09-06 09:05:48 +00:00
fmodf 9df49aa422 wip 2023-09-06 13:02:52 +04:00
fmodf 2736e72e9d fix linter warnings 2023-09-06 12:58:09 +04:00
fmodf 4d7e8d2fbd fix linter warnings 2023-09-06 12:43:28 +04:00
fmodf 4c6aaea4d8 fix linter warnings 2023-09-06 12:24:39 +04:00
fmodf cad4d3dcb0 fix linter warnings 2023-09-06 12:03:57 +04:00
fmodf 3e668aa808 fix linter errors 2023-09-05 18:46:24 +04:00
fmodf 54f2b3b825 fix linter warnings 2023-09-05 18:43:42 +04:00
fmodf f33c3de839 fix linter warnings 2023-09-05 18:25:31 +04:00
fmodf c95460b80e fix linter errors 2023-09-05 18:21:07 +04:00
fmodf cc20619e2c fix linter errors 2023-09-05 18:05:11 +04:00
fmodf f1fd81841e fix linter errors 2023-09-05 18:00:40 +04:00
fmodf 7603ace54e fix linter errors 2023-09-05 17:52:31 +04:00
fmodf b75eed2677 fix linter errors 2023-09-05 17:15:14 +04:00
fmodf d62937af4b fix linter errors 2023-09-05 17:00:08 +04:00
fmodf ab08d43225 fix linter errors 2023-09-05 16:46:12 +04:00
fmodf 507bc16846 fix linter errors 2023-09-05 16:40:40 +04:00
fmodf ac6eb97b16 fix linter errors 2023-09-05 16:33:35 +04:00
fmodf f31f0c54c5 fix linter errors 2023-09-05 13:50:58 +04:00
fmodf 8cbd60d30d fix linter errors 2023-09-05 13:41:32 +04:00
fmodf 93ee79ee20 fix linter error 2023-09-05 13:20:11 +04:00
fmodf a7fddc9022 fix linter errors 2023-09-05 12:32:09 +04:00
fmodf 4316eb2ca1 fix linter errors 2023-09-04 17:39:13 +04:00
fmodf 4b4de74eda fix linter error 2023-09-04 17:31:49 +04:00
fmodf 4d02aaea5b fix linter errors 2023-09-04 17:24:32 +04:00
fmodf 97ac8373c9 fix linter errors 2023-09-04 17:20:18 +04:00
fmodf 68a136e4b7 fix linter errors 2023-08-30 17:33:07 +04:00
fmodf aaa5428bfc fix linter errors 2023-08-30 17:28:14 +04:00
fmodf 39b8a4c6bc fix linter errors 2023-08-30 17:20:46 +04:00
fmodf 050a12b1cc fix linter errors 2023-08-30 17:07:51 +04:00
fmodf f9d776da64 fix linter errors 2023-08-30 16:54:00 +04:00
fmodf 129b63fd16 fix linter errors 2023-08-30 16:28:00 +04:00
fmodf 0535e59bb3 fix linter errors 2023-08-30 16:23:07 +04:00
fmodf 05d79d058f fix linter errors 2023-08-30 16:18:21 +04:00
fmodf eefce61e3a fix linter errors 2023-08-30 16:07:36 +04:00
fmodf 44f3c598cd up to iOS 15 2023-08-28 19:17:55 +04:00
fmodf ac15a7e8c5 move WebRTC and OpenSSL to SPM 2023-08-28 17:18:46 +04:00
1086 changed files with 31722 additions and 63415 deletions

View file

@ -1,26 +0,0 @@
[update]
tasks = ["interfaces", "code", "normalize"]
[update.interfaces]
paths = ["."]
defaultToBase = true
ignoreEmptyStrings = false
unstripped = false
[update.code]
codePaths = ["."]
localizablePaths = ["."]
defaultToKeys = true
additive = false
unstripped = false
[update.normalize]
paths = ["."]
sourceLocale = "en"
harmonizeWithSource = true
sortByKeys = true
[lint]
paths = ["."]
duplicateKeys = true
emptyValues = true

12
.gitignore vendored
View file

@ -110,4 +110,14 @@ xcuserdata
#
# We're using source-control, so this is a "feature" that we do not want!
*.moved-aside
*.moved-aside
/.idea
/Snikket/.idea
/Snikket.xcodeproj
/Info.plist
/old/.idea
/Engine/Info.plist
/Snikket/Snikket.entitlements
/XMPPSwift/Client/VoIP/rickroll.mp4
/.nvim
/buildServer.json

View file

@ -0,0 +1,42 @@
<?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>BuildMachineOSBuild</key>
<string></string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>SwiftGen_SwiftGenCLI</string>
<key>CFBundleIdentifier</key>
<string>SwiftGen.SwiftGenCLI.resources</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>SwiftGen_SwiftGenCLI</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>13A233</string>
<key>DTPlatformName</key>
<string>macosx</string>
<key>DTPlatformVersion</key>
<string>11.3</string>
<key>DTSDKBuild</key>
<string>20E214</string>
<key>DTSDKName</key>
<string>macosx11.3</string>
<key>DTXcode</key>
<string>1300</string>
<key>DTXcodeBuild</key>
<string>13A233</string>
<key>LSMinimumSystemVersion</key>
<string>10.11</string>
</dict>
</plist>

View file

@ -0,0 +1,43 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if palettes %}
{% set enumName %}{{param.enumName|default:"ColorName"}}{% endset %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
#if os(macOS)
import AppKit
{% if enumName != 'NSColor' %}{{accessModifier}} enum {{enumName}} { }{% endif %}
#elseif os(iOS) || os(tvOS) || os(watchOS)
import UIKit
{% if enumName != 'UIColor' %}{{accessModifier}} enum {{enumName}} { }{% endif %}
#endif
// swiftlint:disable superfluous_disable_command
// swiftlint:disable file_length
// MARK: - Colors
// swiftlint:disable identifier_name line_length type_body_length
{{accessModifier}} extension {{enumName}} {
{% macro h2f hex %}{{hex|hexToInt|int255toFloat}}{% endmacro %}
{% macro enumBlock colors accessPrefix %}
{% for color in colors %}
/// 0x{{color.red}}{{color.green}}{{color.blue}}{{color.alpha}} (r: {{color.red|hexToInt}}, g: {{color.green|hexToInt}}, b: {{color.blue|hexToInt}}, a: {{color.alpha|hexToInt}})
{{accessPrefix}}static let {{color.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = #colorLiteral(red: {% call h2f color.red %}, green: {% call h2f color.green %}, blue: {% call h2f color.blue %}, alpha: {% call h2f color.alpha %})
{% endfor %}
{% endmacro %}
{% if palettes.count > 1 or param.forceFileNameEnum %}
{% set accessPrefix %}{{accessModifier}} {% endset %}
{% for palette in palettes %}
enum {{palette.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call enumBlock palette.colors accessPrefix %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call enumBlock palettes.first.colors "" %}
{% endif %}
}
// swiftlint:enable identifier_name line_length type_body_length
{% else %}
// No color found
{% endif %}

View file

@ -0,0 +1,43 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if palettes %}
{% set enumName %}{{param.enumName|default:"ColorName"}}{% endset %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
#if os(macOS)
import AppKit
{% if enumName != 'NSColor' %}{{accessModifier}} enum {{enumName}} { }{% endif %}
#elseif os(iOS) || os(tvOS) || os(watchOS)
import UIKit
{% if enumName != 'UIColor' %}{{accessModifier}} enum {{enumName}} { }{% endif %}
#endif
// swiftlint:disable superfluous_disable_command
// swiftlint:disable file_length
// MARK: - Colors
// swiftlint:disable identifier_name line_length type_body_length
{{accessModifier}} extension {{enumName}} {
{% macro h2f hex %}{{hex|hexToInt|int255toFloat}}{% endmacro %}
{% macro enumBlock colors accessPrefix %}
{% for color in colors %}
/// 0x{{color.red}}{{color.green}}{{color.blue}}{{color.alpha}} (r: {{color.red|hexToInt}}, g: {{color.green|hexToInt}}, b: {{color.blue|hexToInt}}, a: {{color.alpha|hexToInt}})
{{accessPrefix}}static let {{color.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = #colorLiteral(red: {% call h2f color.red %}, green: {% call h2f color.green %}, blue: {% call h2f color.blue %}, alpha: {% call h2f color.alpha %})
{% endfor %}
{% endmacro %}
{% if palettes.count > 1 or param.forceFileNameEnum %}
{% set accessPrefix %}{{accessModifier}} {% endset %}
{% for palette in palettes %}
enum {{palette.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call enumBlock palette.colors accessPrefix %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call enumBlock palettes.first.colors "" %}
{% endif %}
}
// swiftlint:enable identifier_name line_length type_body_length
{% else %}
// No color found
{% endif %}

View file

@ -0,0 +1,84 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if palettes %}
{% set colorAlias %}{{param.colorAliasName|default:"Color"}}{% endset %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
#if os(macOS)
import AppKit.NSColor
{{accessModifier}} typealias {{colorAlias}} = NSColor
#elseif os(iOS) || os(tvOS) || os(watchOS)
import UIKit.UIColor
{{accessModifier}} typealias {{colorAlias}} = UIColor
#endif
// swiftlint:disable superfluous_disable_command file_length implicit_return
// MARK: - Colors
// swiftlint:disable identifier_name line_length type_body_length
{% set enumName %}{{param.enumName|default:"ColorName"}}{% endset %}
{{accessModifier}} struct {{enumName}} {
{{accessModifier}} let rgbaValue: UInt32
{{accessModifier}} var color: {{colorAlias}} { return {{colorAlias}}(named: self) }
{% macro rgbaValue color %}0x{{color.red}}{{color.green}}{{color.blue}}{{color.alpha}}{% endmacro %}
{% macro enumBlock colors %}
{% for color in colors %}
/// <span style="display:block;width:3em;height:2em;border:1px solid black;background:#{{color.red}}{{color.green}}{{color.blue}}"></span>
/// Alpha: {{color.alpha|hexToInt|int255toFloat|percent}} <br/> (0x{{color.red}}{{color.green}}{{color.blue}}{{color.alpha}})
{{accessModifier}} static let {{color.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{enumName}}(rgbaValue: {% call rgbaValue color %})
{% endfor %}
{% endmacro %}
{% if palettes.count > 1 or param.forceFileNameEnum %}
{% for palette in palettes %}
{{accessModifier}} enum {{palette.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call enumBlock palette.colors %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call enumBlock palettes.first.colors %}
{% endif %}
}
// swiftlint:enable identifier_name line_length type_body_length
// MARK: - Implementation Details
internal extension {{colorAlias}} {
convenience init(rgbaValue: UInt32) {
let components = RGBAComponents(rgbaValue: rgbaValue).normalized
self.init(red: components[0], green: components[1], blue: components[2], alpha: components[3])
}
}
private struct RGBAComponents {
let rgbaValue: UInt32
private var shifts: [UInt32] {
[
rgbaValue >> 24, // red
rgbaValue >> 16, // green
rgbaValue >> 8, // blue
rgbaValue // alpha
]
}
private var components: [CGFloat] {
shifts.map {
CGFloat($0 & 0xff)
}
}
var normalized: [CGFloat] {
components.map { $0 / 255.0 }
}
}
{{accessModifier}} extension {{colorAlias}} {
convenience init(named color: {{enumName}}) {
self.init(rgbaValue: color.rgbaValue)
}
}
{% else %}
// No color found
{% endif %}

View file

@ -0,0 +1,84 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if palettes %}
{% set colorAlias %}{{param.colorAliasName|default:"Color"}}{% endset %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
#if os(macOS)
import AppKit.NSColor
{{accessModifier}} typealias {{colorAlias}} = NSColor
#elseif os(iOS) || os(tvOS) || os(watchOS)
import UIKit.UIColor
{{accessModifier}} typealias {{colorAlias}} = UIColor
#endif
// swiftlint:disable superfluous_disable_command file_length implicit_return
// MARK: - Colors
// swiftlint:disable identifier_name line_length type_body_length
{% set enumName %}{{param.enumName|default:"ColorName"}}{% endset %}
{{accessModifier}} struct {{enumName}} {
{{accessModifier}} let rgbaValue: UInt32
{{accessModifier}} var color: {{colorAlias}} { return {{colorAlias}}(named: self) }
{% macro rgbaValue color %}0x{{color.red}}{{color.green}}{{color.blue}}{{color.alpha}}{% endmacro %}
{% macro enumBlock colors %}
{% for color in colors %}
/// <span style="display:block;width:3em;height:2em;border:1px solid black;background:#{{color.red}}{{color.green}}{{color.blue}}"></span>
/// Alpha: {{color.alpha|hexToInt|int255toFloat|percent}} <br/> (0x{{color.red}}{{color.green}}{{color.blue}}{{color.alpha}})
{{accessModifier}} static let {{color.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{enumName}}(rgbaValue: {% call rgbaValue color %})
{% endfor %}
{% endmacro %}
{% if palettes.count > 1 or param.forceFileNameEnum %}
{% for palette in palettes %}
{{accessModifier}} enum {{palette.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call enumBlock palette.colors %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call enumBlock palettes.first.colors %}
{% endif %}
}
// swiftlint:enable identifier_name line_length type_body_length
// MARK: - Implementation Details
internal extension {{colorAlias}} {
convenience init(rgbaValue: UInt32) {
let components = RGBAComponents(rgbaValue: rgbaValue).normalized
self.init(red: components[0], green: components[1], blue: components[2], alpha: components[3])
}
}
private struct RGBAComponents {
let rgbaValue: UInt32
private var shifts: [UInt32] {
[
rgbaValue >> 24, // red
rgbaValue >> 16, // green
rgbaValue >> 8, // blue
rgbaValue // alpha
]
}
private var components: [CGFloat] {
shifts.map {
CGFloat($0 & 0xff)
}
}
var normalized: [CGFloat] {
components.map { $0 / 255.0 }
}
}
{{accessModifier}} extension {{colorAlias}} {
convenience init(named color: {{enumName}}) {
self.init(rgbaValue: color.rgbaValue)
}
}
{% else %}
// No color found
{% endif %}

View file

@ -0,0 +1,211 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
// swiftlint:disable superfluous_disable_command implicit_return
// swiftlint:disable sorted_imports
import CoreData
import Foundation
{% for import in param.extraImports %}
import {{ import }}
{% empty %}
{# If extraImports is a single String instead of an array, `for` considers it empty but we still have to check if there's a single String value #}
{% if param.extraImports %}import {{ param.extraImports }}{% endif %}
{% endfor %}
// swiftlint:disable attributes file_length vertical_whitespace_closing_braces
// swiftlint:disable identifier_name line_length type_body_length
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
{% for model in models %}
{% for name, entity in model.entities %}
{% set superclass %}{{ model.entities[entity.superEntity].className|default:"NSManagedObject" }}{% endset %}
{% set entityClassName %}{{ entity.className|default:"NSManagedObject" }}{% endset %}
// MARK: - {{ entity.name }}
{% if not entity.shouldGenerateCode %}
// Note: '{{ entity.name }}' has codegen enabled for Xcode, skipping code generation.
{% elif entityClassName|contains:"." %}
// Warning: '{{ entityClassName }}' cannot be a valid type name, skipping code generation.
{% else %}
{% if param.generateObjcName %}
@objc({{ entityClassName }})
{% endif %}
{{ accessModifier }} class {{ entityClassName }}: {{ superclass }} {
{% set override %}{% if superclass != "NSManagedObject" %}override {% endif %}{% endset %}
{{ override }}{{ accessModifier }} class var entityName: String {
return "{{ entity.name }}"
}
{{ override }}{{ accessModifier }} class func entity(in managedObjectContext: NSManagedObjectContext) -> NSEntityDescription? {
return NSEntityDescription.entity(forEntityName: entityName, in: managedObjectContext)
}
@available(*, deprecated, renamed: "makeFetchRequest", message: "To avoid collisions with the less concrete method in `NSManagedObject`, please use `makeFetchRequest()` instead.")
@nonobjc {{ accessModifier }} class func fetchRequest() -> NSFetchRequest<{{ entityClassName }}> {
return NSFetchRequest<{{ entityClassName }}>(entityName: entityName)
}
@nonobjc {{ accessModifier }} class func makeFetchRequest() -> NSFetchRequest<{{ entityClassName }}> {
return NSFetchRequest<{{ entityClassName }}>(entityName: entityName)
}
// swiftlint:disable discouraged_optional_boolean discouraged_optional_collection
{% for attribute in entity.attributes %}
{% if attribute.userInfo.RawType %}
{% set rawType attribute.userInfo.RawType %}
{% set unwrapOptional attribute.userInfo.unwrapOptional %}
{{ accessModifier }} var {{ attribute.name }}: {{ rawType }}{% if not unwrapOptional %}?{% endif %} {
get {
let key = "{{ attribute.name }}"
willAccessValue(forKey: key)
defer { didAccessValue(forKey: key) }
{% if unwrapOptional %}
guard let value = primitiveValue(forKey: key) as? {{ rawType }}.RawValue,
let result = {{ rawType }}(rawValue: value) else {
fatalError("Could not convert value for key '\(key)' to type '{{ rawType }}'")
}
return result
{% else %}
guard let value = primitiveValue(forKey: key) as? {{ rawType }}.RawValue else {
return nil
}
return {{ rawType }}(rawValue: value)
{% endif %}
}
set {
let key = "{{ attribute.name }}"
willChangeValue(forKey: key)
defer { didChangeValue(forKey: key) }
setPrimitiveValue(newValue{% if not unwrapOptional %}?{% endif %}.rawValue, forKey: key)
}
}
{% elif attribute.usesScalarValueType and attribute.isOptional %}
{{ accessModifier }} var {{ attribute.name }}: {{ attribute.typeName }}? {
get {
let key = "{{ attribute.name }}"
willAccessValue(forKey: key)
defer { didAccessValue(forKey: key) }
return primitiveValue(forKey: key) as? {{ attribute.typeName }}
}
set {
let key = "{{ attribute.name }}"
willChangeValue(forKey: key)
defer { didChangeValue(forKey: key) }
setPrimitiveValue(newValue, forKey: key)
}
}
{% else %}
@NSManaged {{ accessModifier }} var {{ attribute.name }}: {{ attribute.typeName }}{% if attribute.isOptional %}?{% endif %}
{% endif %}
{% endfor %}
{% for relationship in entity.relationships %}
{% if relationship.isToMany %}
@NSManaged {{ accessModifier }} var {{ relationship.name }}: {% if relationship.isOrdered %}NSOrderedSet{% else %}Set<{{ model.entities[relationship.destinationEntity].className|default:"NSManagedObject" }}>{% endif %}{% if relationship.isOptional %}?{% endif %}
{% else %}
@NSManaged {{ accessModifier }} var {{ relationship.name }}: {{ model.entities[relationship.destinationEntity].className|default:"NSManagedObject" }}{% if relationship.isOptional %}?{% endif %}
{% endif %}
{% endfor %}
{% for fetchedProperty in entity.fetchedProperties %}
@NSManaged {{ accessModifier }} var {{ fetchedProperty.name }}: [{{ fetchedProperty.fetchRequest.entity }}]
{% endfor %}
// swiftlint:enable discouraged_optional_boolean discouraged_optional_collection
}
{% for relationship in entity.relationships where relationship.isToMany %}
{% set destinationEntityClassName %}{{ model.entities[relationship.destinationEntity].className|default:"NSManagedObject" }}{% endset %}
{% set collectionClassName %}{% if relationship.isOrdered %}NSOrderedSet{% else %}Set<{{ destinationEntityClassName }}>{% endif %}{% endset %}
{% set relationshipName %}{{ relationship.name | upperFirstLetter }}{% endset %}
// MARK: Relationship {{ relationshipName }}
extension {{ entityClassName }} {
{% if relationship.isOrdered %}
@objc(insertObject:in{{ relationshipName }}AtIndex:)
@NSManaged public func insertInto{{ relationshipName }}(_ value: {{ destinationEntityClassName }}, at idx: Int)
@objc(removeObjectFrom{{ relationshipName }}AtIndex:)
@NSManaged public func removeFrom{{ relationshipName }}(at idx: Int)
@objc(insert{{ relationshipName }}:atIndexes:)
@NSManaged public func insertInto{{ relationshipName }}(_ values: [{{ destinationEntityClassName }}], at indexes: NSIndexSet)
@objc(remove{{ relationshipName }}AtIndexes:)
@NSManaged public func removeFrom{{ relationshipName }}(at indexes: NSIndexSet)
@objc(replaceObjectIn{{ relationshipName }}AtIndex:withObject:)
@NSManaged public func replace{{ relationshipName }}(at idx: Int, with value: {{ destinationEntityClassName }})
@objc(replace{{ relationshipName }}AtIndexes:with{{ relationshipName }}:)
@NSManaged public func replace{{ relationshipName }}(at indexes: NSIndexSet, with values: [{{ destinationEntityClassName }}])
{% endif %}
@objc(add{{ relationshipName }}Object:)
@NSManaged public func addTo{{ relationshipName }}(_ value: {{ destinationEntityClassName }})
@objc(remove{{ relationshipName }}Object:)
@NSManaged public func removeFrom{{ relationshipName }}(_ value: {{ destinationEntityClassName }})
@objc(add{{ relationshipName }}:)
@NSManaged public func addTo{{ relationshipName }}(_ values: {{ collectionClassName }})
@objc(remove{{ relationshipName }}:)
@NSManaged public func removeFrom{{ relationshipName }}(_ values: {{ collectionClassName }})
}
{% endfor %}
{% if model.fetchRequests[entity.name].count > 0 %}
// MARK: Fetch Requests
extension {{ entityClassName }} {
{% for fetchRequest in model.fetchRequests[entity.name] %}
{% set resultTypeName %}{% filter removeNewlines:"leading" %}
{% if fetchRequest.resultType == "Object" %}
{{ entityClassName }}
{% elif fetchRequest.resultType == "Object ID" %}
NSManagedObjectID
{% elif fetchRequest.resultType == "Dictionary" %}
[String: Any]
{% endif %}
{% endfilter %}{% endset %}
class func fetch{{ fetchRequest.name | upperFirstLetter }}({% filter removeNewlines:"leading" %}
managedObjectContext: NSManagedObjectContext
{% for variableName, variableType in fetchRequest.substitutionVariables %}
, {{ variableName | lowerFirstWord }}: {{ variableType }}
{% endfor %}
{% endfilter %}) throws -> [{{ resultTypeName }}] {
guard let persistentStoreCoordinator = managedObjectContext.persistentStoreCoordinator else {
fatalError("Managed object context has no persistent store coordinator for getting fetch request templates")
}
let model = persistentStoreCoordinator.managedObjectModel
let substitutionVariables: [String: Any] = [
{% for variableName, variableType in fetchRequest.substitutionVariables %}
"{{ variableName }}": {{ variableName | lowerFirstWord }}{{ "," if not forloop.last }}
{% empty %}
:
{% endfor %}
]
guard let fetchRequest = model.fetchRequestFromTemplate(withName: "{{ fetchRequest.name }}", substitutionVariables: substitutionVariables) else {
fatalError("No fetch request template named '{{ fetchRequest.name }}' found.")
}
guard let result = try managedObjectContext.fetch(fetchRequest) as? [{{ resultTypeName }}] else {
fatalError("Unable to cast fetch result to correct result type.")
}
return result
}
{% endfor %}
}
{% endif %}
{% endif %}
{% endfor %}
{% endfor %}
// swiftlint:enable identifier_name line_length type_body_length

View file

@ -0,0 +1,211 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
// swiftlint:disable superfluous_disable_command implicit_return
// swiftlint:disable sorted_imports
import CoreData
import Foundation
{% for import in param.extraImports %}
import {{ import }}
{% empty %}
{# If extraImports is a single String instead of an array, `for` considers it empty but we still have to check if there's a single String value #}
{% if param.extraImports %}import {{ param.extraImports }}{% endif %}
{% endfor %}
// swiftlint:disable attributes file_length vertical_whitespace_closing_braces
// swiftlint:disable identifier_name line_length type_body_length
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
{% for model in models %}
{% for name, entity in model.entities %}
{% set superclass %}{{ model.entities[entity.superEntity].className|default:"NSManagedObject" }}{% endset %}
{% set entityClassName %}{{ entity.className|default:"NSManagedObject" }}{% endset %}
// MARK: - {{ entity.name }}
{% if not entity.shouldGenerateCode %}
// Note: '{{ entity.name }}' has codegen enabled for Xcode, skipping code generation.
{% elif entityClassName|contains:"." %}
// Warning: '{{ entityClassName }}' cannot be a valid type name, skipping code generation.
{% else %}
{% if param.generateObjcName %}
@objc({{ entityClassName }})
{% endif %}
{{ accessModifier }} class {{ entityClassName }}: {{ superclass }} {
{% set override %}{% if superclass != "NSManagedObject" %}override {% endif %}{% endset %}
{{ override }}{{ accessModifier }} class var entityName: String {
return "{{ entity.name }}"
}
{{ override }}{{ accessModifier }} class func entity(in managedObjectContext: NSManagedObjectContext) -> NSEntityDescription? {
return NSEntityDescription.entity(forEntityName: entityName, in: managedObjectContext)
}
@available(*, deprecated, renamed: "makeFetchRequest", message: "To avoid collisions with the less concrete method in `NSManagedObject`, please use `makeFetchRequest()` instead.")
@nonobjc {{ accessModifier }} class func fetchRequest() -> NSFetchRequest<{{ entityClassName }}> {
return NSFetchRequest<{{ entityClassName }}>(entityName: entityName)
}
@nonobjc {{ accessModifier }} class func makeFetchRequest() -> NSFetchRequest<{{ entityClassName }}> {
return NSFetchRequest<{{ entityClassName }}>(entityName: entityName)
}
// swiftlint:disable discouraged_optional_boolean discouraged_optional_collection
{% for attribute in entity.attributes %}
{% if attribute.userInfo.RawType %}
{% set rawType attribute.userInfo.RawType %}
{% set unwrapOptional attribute.userInfo.unwrapOptional %}
{{ accessModifier }} var {{ attribute.name }}: {{ rawType }}{% if not unwrapOptional %}?{% endif %} {
get {
let key = "{{ attribute.name }}"
willAccessValue(forKey: key)
defer { didAccessValue(forKey: key) }
{% if unwrapOptional %}
guard let value = primitiveValue(forKey: key) as? {{ rawType }}.RawValue,
let result = {{ rawType }}(rawValue: value) else {
fatalError("Could not convert value for key '\(key)' to type '{{ rawType }}'")
}
return result
{% else %}
guard let value = primitiveValue(forKey: key) as? {{ rawType }}.RawValue else {
return nil
}
return {{ rawType }}(rawValue: value)
{% endif %}
}
set {
let key = "{{ attribute.name }}"
willChangeValue(forKey: key)
defer { didChangeValue(forKey: key) }
setPrimitiveValue(newValue{% if not unwrapOptional %}?{% endif %}.rawValue, forKey: key)
}
}
{% elif attribute.usesScalarValueType and attribute.isOptional %}
{{ accessModifier }} var {{ attribute.name }}: {{ attribute.typeName }}? {
get {
let key = "{{ attribute.name }}"
willAccessValue(forKey: key)
defer { didAccessValue(forKey: key) }
return primitiveValue(forKey: key) as? {{ attribute.typeName }}
}
set {
let key = "{{ attribute.name }}"
willChangeValue(forKey: key)
defer { didChangeValue(forKey: key) }
setPrimitiveValue(newValue, forKey: key)
}
}
{% else %}
@NSManaged {{ accessModifier }} var {{ attribute.name }}: {{ attribute.typeName }}{% if attribute.isOptional %}?{% endif %}
{% endif %}
{% endfor %}
{% for relationship in entity.relationships %}
{% if relationship.isToMany %}
@NSManaged {{ accessModifier }} var {{ relationship.name }}: {% if relationship.isOrdered %}NSOrderedSet{% else %}Set<{{ model.entities[relationship.destinationEntity].className|default:"NSManagedObject" }}>{% endif %}{% if relationship.isOptional %}?{% endif %}
{% else %}
@NSManaged {{ accessModifier }} var {{ relationship.name }}: {{ model.entities[relationship.destinationEntity].className|default:"NSManagedObject" }}{% if relationship.isOptional %}?{% endif %}
{% endif %}
{% endfor %}
{% for fetchedProperty in entity.fetchedProperties %}
@NSManaged {{ accessModifier }} var {{ fetchedProperty.name }}: [{{ fetchedProperty.fetchRequest.entity }}]
{% endfor %}
// swiftlint:enable discouraged_optional_boolean discouraged_optional_collection
}
{% for relationship in entity.relationships where relationship.isToMany %}
{% set destinationEntityClassName %}{{ model.entities[relationship.destinationEntity].className|default:"NSManagedObject" }}{% endset %}
{% set collectionClassName %}{% if relationship.isOrdered %}NSOrderedSet{% else %}Set<{{ destinationEntityClassName }}>{% endif %}{% endset %}
{% set relationshipName %}{{ relationship.name | upperFirstLetter }}{% endset %}
// MARK: Relationship {{ relationshipName }}
extension {{ entityClassName }} {
{% if relationship.isOrdered %}
@objc(insertObject:in{{ relationshipName }}AtIndex:)
@NSManaged public func insertInto{{ relationshipName }}(_ value: {{ destinationEntityClassName }}, at idx: Int)
@objc(removeObjectFrom{{ relationshipName }}AtIndex:)
@NSManaged public func removeFrom{{ relationshipName }}(at idx: Int)
@objc(insert{{ relationshipName }}:atIndexes:)
@NSManaged public func insertInto{{ relationshipName }}(_ values: [{{ destinationEntityClassName }}], at indexes: NSIndexSet)
@objc(remove{{ relationshipName }}AtIndexes:)
@NSManaged public func removeFrom{{ relationshipName }}(at indexes: NSIndexSet)
@objc(replaceObjectIn{{ relationshipName }}AtIndex:withObject:)
@NSManaged public func replace{{ relationshipName }}(at idx: Int, with value: {{ destinationEntityClassName }})
@objc(replace{{ relationshipName }}AtIndexes:with{{ relationshipName }}:)
@NSManaged public func replace{{ relationshipName }}(at indexes: NSIndexSet, with values: [{{ destinationEntityClassName }}])
{% endif %}
@objc(add{{ relationshipName }}Object:)
@NSManaged public func addTo{{ relationshipName }}(_ value: {{ destinationEntityClassName }})
@objc(remove{{ relationshipName }}Object:)
@NSManaged public func removeFrom{{ relationshipName }}(_ value: {{ destinationEntityClassName }})
@objc(add{{ relationshipName }}:)
@NSManaged public func addTo{{ relationshipName }}(_ values: {{ collectionClassName }})
@objc(remove{{ relationshipName }}:)
@NSManaged public func removeFrom{{ relationshipName }}(_ values: {{ collectionClassName }})
}
{% endfor %}
{% if model.fetchRequests[entity.name].count > 0 %}
// MARK: Fetch Requests
extension {{ entityClassName }} {
{% for fetchRequest in model.fetchRequests[entity.name] %}
{% set resultTypeName %}{% filter removeNewlines:"leading" %}
{% if fetchRequest.resultType == "Object" %}
{{ entityClassName }}
{% elif fetchRequest.resultType == "Object ID" %}
NSManagedObjectID
{% elif fetchRequest.resultType == "Dictionary" %}
[String: Any]
{% endif %}
{% endfilter %}{% endset %}
class func fetch{{ fetchRequest.name | upperFirstLetter }}({% filter removeNewlines:"leading" %}
managedObjectContext: NSManagedObjectContext
{% for variableName, variableType in fetchRequest.substitutionVariables %}
, {{ variableName | lowerFirstWord }}: {{ variableType }}
{% endfor %}
{% endfilter %}) throws -> [{{ resultTypeName }}] {
guard let persistentStoreCoordinator = managedObjectContext.persistentStoreCoordinator else {
fatalError("Managed object context has no persistent store coordinator for getting fetch request templates")
}
let model = persistentStoreCoordinator.managedObjectModel
let substitutionVariables: [String: Any] = [
{% for variableName, variableType in fetchRequest.substitutionVariables %}
"{{ variableName }}": {{ variableName | lowerFirstWord }}{{ "," if not forloop.last }}
{% empty %}
:
{% endfor %}
]
guard let fetchRequest = model.fetchRequestFromTemplate(withName: "{{ fetchRequest.name }}", substitutionVariables: substitutionVariables) else {
fatalError("No fetch request template named '{{ fetchRequest.name }}' found.")
}
guard let result = try managedObjectContext.fetch(fetchRequest) as? [{{ resultTypeName }}] else {
fatalError("Unable to cast fetch result to correct result type.")
}
return result
}
{% endfor %}
}
{% endif %}
{% endif %}
{% endfor %}
{% endfor %}
// swiftlint:enable identifier_name line_length type_body_length

View file

@ -0,0 +1,103 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if groups.count > 0 %}
{% set enumName %}{{param.enumName|default:"Files"}}{% endset %}
{% set useExt %}{% if param.useExtension|default:"true" %}true{% endif %}{% endset %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
{% set resourceType %}{{param.resourceTypeName|default:"File"}}{% endset %}
import Foundation
// swiftlint:disable superfluous_disable_command file_length line_length implicit_return
// MARK: - Files
{% macro groupBlock group %}
{% for file in group.files %}
{% call fileBlock file %}
{% endfor %}
{% for dir in group.directories %}
{% call dirBlock dir %}
{% endfor %}
{% endmacro %}
{% macro fileBlock file %}
/// {% if file.path and param.preservePath %}{{file.path}}/{% endif %}{{file.name}}{% if file.ext %}.{{file.ext}}{% endif %}
{% set identifier %}{{ file.name }}{% if useExt %}.{{ file.ext }}{% endif %}{% endset %}
{{accessModifier}} static let {{identifier|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{resourceType}}(name: "{{file.name}}", ext: {% if file.ext %}"{{file.ext}}"{% else %}nil{% endif %}, relativePath: "{{file.path if param.preservePath}}", mimeType: "{{file.mimeType}}")
{% endmacro %}
{% macro dirBlock directory %}
{% for file in directory.files %}
{% call fileBlock file %}
{% endfor %}
{% for dir in directory.directories %}
{% call dirBlock dir %}
{% endfor %}
{% endmacro %}
// swiftlint:disable explicit_type_interface identifier_name
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
{{accessModifier}} enum {{enumName}} {
{% if groups.count > 1 or param.forceFileNameEnum %}
{% for group in groups %}
{{accessModifier}} enum {{group.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call groupBlock group %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call groupBlock groups.first %}
{% endif %}
}
// swiftlint:enable explicit_type_interface identifier_name
// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces
// MARK: - Implementation Details
{{accessModifier}} struct {{resourceType}} {
{{accessModifier}} let name: String
{{accessModifier}} let ext: String?
{{accessModifier}} let relativePath: String
{{accessModifier}} let mimeType: String
{{accessModifier}} var url: URL {
return url(locale: nil)
}
{{accessModifier}} func url(locale: Locale?) -> URL {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
let url = bundle.url(
forResource: name,
withExtension: ext,
subdirectory: relativePath,
localization: locale?.identifier
)
guard let result = url else {
let file = name + (ext.flatMap { ".\($0)" } ?? "")
fatalError("Could not locate file named \(file)")
}
return result
}
{{accessModifier}} var path: String {
return path(locale: nil)
}
{{accessModifier}} func path(locale: Locale?) -> String {
return url(locale: locale).path
}
}
{% if not param.bundle %}
// swiftlint:disable convenience_type explicit_type_interface
private final class BundleToken {
static let bundle: Bundle = {
#if SWIFT_PACKAGE
return Bundle.module
#else
return Bundle(for: BundleToken.self)
#endif
}()
}
// swiftlint:enable convenience_type explicit_type_interface
{% endif %}
{% else %}
// No files found
{% endif %}

View file

@ -0,0 +1,103 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if groups.count > 0 %}
{% set enumName %}{{param.enumName|default:"Files"}}{% endset %}
{% set useExt %}{% if param.useExtension|default:"true" %}true{% endif %}{% endset %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
{% set resourceType %}{{param.resourceTypeName|default:"File"}}{% endset %}
import Foundation
// swiftlint:disable superfluous_disable_command file_length line_length implicit_return
// MARK: - Files
{% macro groupBlock group %}
{% for file in group.files %}
{% call fileBlock file %}
{% endfor %}
{% for dir in group.directories %}
{% call dirBlock dir %}
{% endfor %}
{% endmacro %}
{% macro fileBlock file %}
/// {% if file.path and param.preservePath %}{{file.path}}/{% endif %}{{file.name}}{% if file.ext %}.{{file.ext}}{% endif %}
{% set identifier %}{{ file.name }}{% if useExt %}.{{ file.ext }}{% endif %}{% endset %}
{{accessModifier}} static let {{identifier|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{resourceType}}(name: "{{file.name}}", ext: {% if file.ext %}"{{file.ext}}"{% else %}nil{% endif %}, relativePath: "{{file.path if param.preservePath}}", mimeType: "{{file.mimeType}}")
{% endmacro %}
{% macro dirBlock directory %}
{% for file in directory.files %}
{% call fileBlock file %}
{% endfor %}
{% for dir in directory.directories %}
{% call dirBlock dir %}
{% endfor %}
{% endmacro %}
// swiftlint:disable explicit_type_interface identifier_name
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
{{accessModifier}} enum {{enumName}} {
{% if groups.count > 1 or param.forceFileNameEnum %}
{% for group in groups %}
{{accessModifier}} enum {{group.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call groupBlock group %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call groupBlock groups.first %}
{% endif %}
}
// swiftlint:enable explicit_type_interface identifier_name
// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces
// MARK: - Implementation Details
{{accessModifier}} struct {{resourceType}} {
{{accessModifier}} let name: String
{{accessModifier}} let ext: String?
{{accessModifier}} let relativePath: String
{{accessModifier}} let mimeType: String
{{accessModifier}} var url: URL {
return url(locale: nil)
}
{{accessModifier}} func url(locale: Locale?) -> URL {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
let url = bundle.url(
forResource: name,
withExtension: ext,
subdirectory: relativePath,
localization: locale?.identifier
)
guard let result = url else {
let file = name + (ext.flatMap { ".\($0)" } ?? "")
fatalError("Could not locate file named \(file)")
}
return result
}
{{accessModifier}} var path: String {
return path(locale: nil)
}
{{accessModifier}} func path(locale: Locale?) -> String {
return url(locale: locale).path
}
}
{% if not param.bundle %}
// swiftlint:disable convenience_type explicit_type_interface
private final class BundleToken {
static let bundle: Bundle = {
#if SWIFT_PACKAGE
return Bundle.module
#else
return Bundle(for: BundleToken.self)
#endif
}()
}
// swiftlint:enable convenience_type explicit_type_interface
{% endif %}
{% else %}
// No files found
{% endif %}

View file

@ -0,0 +1,107 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if groups.count > 0 %}
{% set enumName %}{{param.enumName|default:"Files"}}{% endset %}
{% set useExt %}{% if param.useExtension|default:"true" %}true{% endif %}{% endset %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
{% set resourceType %}{{param.resourceTypeName|default:"File"}}{% endset %}
import Foundation
// swiftlint:disable superfluous_disable_command file_length line_length implicit_return
// MARK: - Files
{% macro groupBlock group %}
{% for file in group.files %}
{% call fileBlock file %}
{% endfor %}
{% for dir in group.directories %}
{% call dirBlock dir "" %}
{% endfor %}
{% endmacro %}
{% macro fileBlock file %}
/// {% if file.path and param.preservePath %}{{file.path}}/{% endif %}{{file.name}}{% if file.ext %}.{{file.ext}}{% endif %}
{% set identifier %}{{ file.name }}{% if useExt %}.{{ file.ext }}{% endif %}{% endset %}
{{accessModifier}} static let {{identifier|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{resourceType}}(name: "{{file.name}}", ext: {% if file.ext %}"{{file.ext}}"{% else %}nil{% endif %}, relativePath: "{{file.path if param.preservePath}}", mimeType: "{{file.mimeType}}")
{% endmacro %}
{% macro dirBlock directory parent %}
{% set fullDir %}{{parent}}{{directory.name}}/{% endset %}
/// {{ fullDir }}
{{accessModifier}} enum {{directory.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% for file in directory.files %}
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
{% endfor %}
{% for dir in directory.directories %}
{% filter indent:2 %}{% call dirBlock dir fullDir %}{% endfilter %}
{% endfor %}
}
{% endmacro %}
// swiftlint:disable explicit_type_interface identifier_name
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
{{accessModifier}} enum {{enumName}} {
{% if groups.count > 1 or param.forceFileNameEnum %}
{% for group in groups %}
{{accessModifier}} enum {{group.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call groupBlock group %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call groupBlock groups.first %}
{% endif %}
}
// swiftlint:enable explicit_type_interface identifier_name
// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces
// MARK: - Implementation Details
{{accessModifier}} struct {{resourceType}} {
{{accessModifier}} let name: String
{{accessModifier}} let ext: String?
{{accessModifier}} let relativePath: String
{{accessModifier}} let mimeType: String
{{accessModifier}} var url: URL {
return url(locale: nil)
}
{{accessModifier}} func url(locale: Locale?) -> URL {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
let url = bundle.url(
forResource: name,
withExtension: ext,
subdirectory: relativePath,
localization: locale?.identifier
)
guard let result = url else {
let file = name + (ext.flatMap { ".\($0)" } ?? "")
fatalError("Could not locate file named \(file)")
}
return result
}
{{accessModifier}} var path: String {
return path(locale: nil)
}
{{accessModifier}} func path(locale: Locale?) -> String {
return url(locale: locale).path
}
}
{% if not param.bundle %}
// swiftlint:disable convenience_type explicit_type_interface
private final class BundleToken {
static let bundle: Bundle = {
#if SWIFT_PACKAGE
return Bundle.module
#else
return Bundle(for: BundleToken.self)
#endif
}()
}
// swiftlint:enable convenience_type explicit_type_interface
{% endif %}
{% else %}
// No files found
{% endif %}

View file

@ -0,0 +1,107 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if groups.count > 0 %}
{% set enumName %}{{param.enumName|default:"Files"}}{% endset %}
{% set useExt %}{% if param.useExtension|default:"true" %}true{% endif %}{% endset %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
{% set resourceType %}{{param.resourceTypeName|default:"File"}}{% endset %}
import Foundation
// swiftlint:disable superfluous_disable_command file_length line_length implicit_return
// MARK: - Files
{% macro groupBlock group %}
{% for file in group.files %}
{% call fileBlock file %}
{% endfor %}
{% for dir in group.directories %}
{% call dirBlock dir "" %}
{% endfor %}
{% endmacro %}
{% macro fileBlock file %}
/// {% if file.path and param.preservePath %}{{file.path}}/{% endif %}{{file.name}}{% if file.ext %}.{{file.ext}}{% endif %}
{% set identifier %}{{ file.name }}{% if useExt %}.{{ file.ext }}{% endif %}{% endset %}
{{accessModifier}} static let {{identifier|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{resourceType}}(name: "{{file.name}}", ext: {% if file.ext %}"{{file.ext}}"{% else %}nil{% endif %}, relativePath: "{{file.path if param.preservePath}}", mimeType: "{{file.mimeType}}")
{% endmacro %}
{% macro dirBlock directory parent %}
{% set fullDir %}{{parent}}{{directory.name}}/{% endset %}
/// {{ fullDir }}
{{accessModifier}} enum {{directory.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% for file in directory.files %}
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
{% endfor %}
{% for dir in directory.directories %}
{% filter indent:2 %}{% call dirBlock dir fullDir %}{% endfilter %}
{% endfor %}
}
{% endmacro %}
// swiftlint:disable explicit_type_interface identifier_name
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
{{accessModifier}} enum {{enumName}} {
{% if groups.count > 1 or param.forceFileNameEnum %}
{% for group in groups %}
{{accessModifier}} enum {{group.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call groupBlock group %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call groupBlock groups.first %}
{% endif %}
}
// swiftlint:enable explicit_type_interface identifier_name
// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces
// MARK: - Implementation Details
{{accessModifier}} struct {{resourceType}} {
{{accessModifier}} let name: String
{{accessModifier}} let ext: String?
{{accessModifier}} let relativePath: String
{{accessModifier}} let mimeType: String
{{accessModifier}} var url: URL {
return url(locale: nil)
}
{{accessModifier}} func url(locale: Locale?) -> URL {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
let url = bundle.url(
forResource: name,
withExtension: ext,
subdirectory: relativePath,
localization: locale?.identifier
)
guard let result = url else {
let file = name + (ext.flatMap { ".\($0)" } ?? "")
fatalError("Could not locate file named \(file)")
}
return result
}
{{accessModifier}} var path: String {
return path(locale: nil)
}
{{accessModifier}} func path(locale: Locale?) -> String {
return url(locale: locale).path
}
}
{% if not param.bundle %}
// swiftlint:disable convenience_type explicit_type_interface
private final class BundleToken {
static let bundle: Bundle = {
#if SWIFT_PACKAGE
return Bundle.module
#else
return Bundle(for: BundleToken.self)
#endif
}()
}
// swiftlint:enable convenience_type explicit_type_interface
{% endif %}
{% else %}
// No files found
{% endif %}

View file

@ -0,0 +1,110 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if families %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
{% set fontType %}{{param.fontTypeName|default:"FontConvertible"}}{% endset %}
#if os(macOS)
import AppKit.NSFont
#elseif os(iOS) || os(tvOS) || os(watchOS)
import UIKit.UIFont
#endif
// Deprecated typealiases
@available(*, deprecated, renamed: "{{fontType}}.Font", message: "This typealias will be removed in SwiftGen 7.0")
{{accessModifier}} typealias {{param.fontAliasName|default:"Font"}} = {{fontType}}.Font
// swiftlint:disable superfluous_disable_command
// swiftlint:disable file_length
// swiftlint:disable implicit_return
// MARK: - Fonts
// swiftlint:disable identifier_name line_length type_body_length
{% macro transformPath path %}{% filter removeNewlines %}
{% if param.preservePath %}
{{path}}
{% else %}
{{path|basename}}
{% endif %}
{% endfilter %}{% endmacro %}
{{accessModifier}} enum {{param.enumName|default:"FontFamily"}} {
{% for family in families %}
{{accessModifier}} enum {{family.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% for font in family.fonts %}
{{accessModifier}} static let {{font.style|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{fontType}}(name: "{{font.name}}", family: "{{family.name}}", path: "{% call transformPath font.path %}")
{% endfor %}
{{accessModifier}} static let all: [{{fontType}}] = [{% for font in family.fonts %}{{font.style|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{{ ", " if not forloop.last }}{% endfor %}]
}
{% endfor %}
{{accessModifier}} static let allCustomFonts: [{{fontType}}] = [{% for family in families %}{{family.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}.all{{ ", " if not forloop.last }}{% endfor %}].flatMap { $0 }
{{accessModifier}} static func registerAllCustomFonts() {
allCustomFonts.forEach { $0.register() }
}
}
// swiftlint:enable identifier_name line_length type_body_length
// MARK: - Implementation Details
{{accessModifier}} struct {{fontType}} {
{{accessModifier}} let name: String
{{accessModifier}} let family: String
{{accessModifier}} let path: String
#if os(macOS)
{{accessModifier}} typealias Font = NSFont
#elseif os(iOS) || os(tvOS) || os(watchOS)
{{accessModifier}} typealias Font = UIFont
#endif
{{accessModifier}} func font(size: CGFloat) -> Font! {
return Font(font: self, size: size)
}
{{accessModifier}} func register() {
// swiftlint:disable:next conditional_returns_on_newline
guard let url = url else { return }
CTFontManagerRegisterFontsForURL(url as CFURL, .process, nil)
}
fileprivate var url: URL? {
{% if param.lookupFunction %}
return {{param.lookupFunction}}(name, family, path)
{% else %}
return {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil)
{% endif %}
}
}
{{accessModifier}} extension {{fontType}}.Font {
convenience init?(font: {{fontType}}, size: CGFloat) {
#if os(iOS) || os(tvOS) || os(watchOS)
if !UIFont.fontNames(forFamilyName: font.family).contains(font.name) {
font.register()
}
#elseif os(macOS)
if let url = font.url, CTFontManagerGetScopeForURL(url as CFURL) == .none {
font.register()
}
#endif
self.init(name: font.name, size: size)
}
}
{% if not param.bundle and not param.lookupFunction %}
// swiftlint:disable convenience_type
private final class BundleToken {
static let bundle: Bundle = {
#if SWIFT_PACKAGE
return Bundle.module
#else
return Bundle(for: BundleToken.self)
#endif
}()
}
// swiftlint:enable convenience_type
{% endif %}
{% else %}
// No fonts found
{% endif %}

View file

@ -0,0 +1,113 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if families %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
{% set fontType %}{{param.fontTypeName|default:"FontConvertible"}}{% endset %}
#if os(macOS)
import AppKit.NSFont
#elseif os(iOS) || os(tvOS) || os(watchOS)
import UIKit.UIFont
#endif
// Deprecated typealiases
@available(*, deprecated, renamed: "{{fontType}}.Font", message: "This typealias will be removed in SwiftGen 7.0")
{{accessModifier}} typealias {{param.fontAliasName|default:"Font"}} = {{fontType}}.Font
// swiftlint:disable superfluous_disable_command
// swiftlint:disable file_length
// MARK: - Fonts
// swiftlint:disable identifier_name line_length type_body_length
{% macro transformPath path %}{% filter removeNewlines %}
{% if param.preservePath %}
{{path}}
{% else %}
{{path|basename}}
{% endif %}
{% endfilter %}{% endmacro %}
{{accessModifier}} enum {{param.enumName|default:"FontFamily"}} {
{% for family in families %}
{{accessModifier}} enum {{family.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% for font in family.fonts %}
{{accessModifier}} static let {{font.style|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{fontType}}(name: "{{font.name}}", family: "{{family.name}}", path: "{% call transformPath font.path %}")
{% endfor %}
{{accessModifier}} static let all: [{{fontType}}] = [{% for font in family.fonts %}{{font.style|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{{ ", " if not forloop.last }}{% endfor %}]
}
{% endfor %}
{{accessModifier}} static let allCustomFonts: [{{fontType}}] = [{% for family in families %}{{family.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}.all{{ ", " if not forloop.last }}{% endfor %}].flatMap { $0 }
{{accessModifier}} static func registerAllCustomFonts() {
allCustomFonts.forEach { $0.register() }
}
}
// swiftlint:enable identifier_name line_length type_body_length
// MARK: - Implementation Details
{{accessModifier}} struct {{fontType}} {
{{accessModifier}} let name: String
{{accessModifier}} let family: String
{{accessModifier}} let path: String
#if os(macOS)
{{accessModifier}} typealias Font = NSFont
#elseif os(iOS) || os(tvOS) || os(watchOS)
{{accessModifier}} typealias Font = UIFont
#endif
{{accessModifier}} func font(size: CGFloat) -> Font {
guard let font = Font(font: self, size: size) else {
fatalError("Unable to initialize font '\(name)' (\(family))")
}
return font
}
{{accessModifier}} func register() {
// swiftlint:disable:next conditional_returns_on_newline
guard let url = url else { return }
CTFontManagerRegisterFontsForURL(url as CFURL, .process, nil)
}
fileprivate var url: URL? {
// swiftlint:disable:next implicit_return
{% if param.lookupFunction %}
return {{param.lookupFunction}}(name, family, path)
{% else %}
return {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil)
{% endif %}
}
}
{{accessModifier}} extension {{fontType}}.Font {
convenience init?(font: {{fontType}}, size: CGFloat) {
#if os(iOS) || os(tvOS) || os(watchOS)
if !UIFont.fontNames(forFamilyName: font.family).contains(font.name) {
font.register()
}
#elseif os(macOS)
if let url = font.url, CTFontManagerGetScopeForURL(url as CFURL) == .none {
font.register()
}
#endif
self.init(name: font.name, size: size)
}
}
{% if not param.bundle and not param.lookupFunction %}
// swiftlint:disable convenience_type
private final class BundleToken {
static let bundle: Bundle = {
#if SWIFT_PACKAGE
return Bundle.module
#else
return Bundle(for: BundleToken.self)
#endif
}()
}
// swiftlint:enable convenience_type
{% endif %}
{% else %}
// No fonts found
{% endif %}

View file

@ -0,0 +1,157 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if platform and storyboards %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
{% set isAppKit %}{% if platform == "macOS" %}true{% endif %}{% endset %}
{% set prefix %}{% if isAppKit %}NS{% else %}UI{% endif %}{% endset %}
{% set controller %}{% if isAppKit %}Controller{% else %}ViewController{% endif %}{% endset %}
// swiftlint:disable sorted_imports
import Foundation
{% for module in modules where module != env.PRODUCT_MODULE_NAME and module != param.module %}
import {{module}}
{% endfor %}
// swiftlint:disable superfluous_disable_command
// swiftlint:disable file_length implicit_return
// MARK: - Storyboard Scenes
// swiftlint:disable explicit_type_interface identifier_name line_length type_body_length type_name
{% macro moduleName item %}{% filter removeNewlines %}
{% if item.moduleIsPlaceholder %}
{{ env.PRODUCT_MODULE_NAME|default:param.module }}
{% else %}
{{ item.module }}
{% endif %}
{% endfilter %}{% endmacro %}
{% macro className item %}{% filter removeNewlines %}
{% set module %}{% call moduleName item %}{% endset %}
{% if module and ( not param.ignoreTargetModule or module != env.PRODUCT_MODULE_NAME and module != param.module ) %}
{{module}}.
{% endif %}
{{item.type}}
{% endfilter %}{% endmacro %}
{{accessModifier}} enum {{param.enumName|default:"StoryboardScene"}} {
{% for storyboard in storyboards %}
{% set storyboardName %}{{storyboard.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}{% endset %}
{{accessModifier}} enum {{storyboardName}}: StoryboardType {
{{accessModifier}} static let storyboardName = "{{storyboard.name}}"
{% if storyboard.initialScene %}
{% set sceneClass %}{% call className storyboard.initialScene %}{% endset %}
{{accessModifier}} static let initialScene = InitialSceneType<{{sceneClass}}>(storyboard: {{storyboardName}}.self)
{% endif %}
{% for scene in storyboard.scenes %}
{% set sceneID %}{{scene.identifier|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
{% set sceneClass %}{% call className scene %}{% endset %}
{{accessModifier}} static let {{sceneID}} = SceneType<{{sceneClass}}>(storyboard: {{storyboardName}}.self, identifier: "{{scene.identifier}}")
{% endfor %}
}
{% endfor %}
}
// swiftlint:enable explicit_type_interface identifier_name line_length type_body_length type_name
// MARK: - Implementation Details
{{accessModifier}} protocol StoryboardType {
static var storyboardName: String { get }
}
{{accessModifier}} extension StoryboardType {
static var storyboard: {{prefix}}Storyboard {
let name = {% if isAppKit %}NSStoryboard.Name({% endif %}self.storyboardName{% if isAppKit %}){% endif %}
{% if param.lookupFunction %}
return {{param.lookupFunction}}(name)
{% else %}
return {{prefix}}Storyboard(name: name, bundle: {{param.bundle|default:"BundleToken.bundle"}})
{% endif %}
}
}
{{accessModifier}} struct SceneType<T{% if not isAppKit %}: UIViewController{% endif %}> {
{{accessModifier}} let storyboard: StoryboardType.Type
{{accessModifier}} let identifier: String
{{accessModifier}} func instantiate() -> T {
let identifier = {% if isAppKit %}NSStoryboard.SceneIdentifier({% endif %}self.identifier{% if isAppKit %}){% endif %}
guard let controller = storyboard.storyboard.instantiate{{controller}}(withIdentifier: identifier) as? T else {
fatalError("{{controller}} '\(identifier)' is not of the expected class \(T.self).")
}
return controller
}
{% if isAppKit %}
@available(macOS 10.15, *)
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSViewController {
return storyboard.storyboard.instantiate{{controller}}(identifier: identifier, creator: block)
}
@available(macOS 10.15, *)
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSWindowController {
return storyboard.storyboard.instantiate{{controller}}(identifier: identifier, creator: block)
}
{% else %}
@available(iOS 13.0, tvOS 13.0, *)
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T {
return storyboard.storyboard.instantiate{{controller}}(identifier: identifier, creator: block)
}
{% endif %}
}
{{accessModifier}} struct InitialSceneType<T{% if not isAppKit %}: UIViewController{% endif %}> {
{{accessModifier}} let storyboard: StoryboardType.Type
{{accessModifier}} func instantiate() -> T {
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}() as? T else {
fatalError("{{controller}} is not of the expected class \(T.self).")
}
return controller
}
{% if isAppKit %}
@available(macOS 10.15, *)
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSViewController {
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}(creator: block) else {
fatalError("Storyboard \(storyboard.storyboardName) does not have an initial scene.")
}
return controller
}
@available(macOS 10.15, *)
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSWindowController {
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}(creator: block) else {
fatalError("Storyboard \(storyboard.storyboardName) does not have an initial scene.")
}
return controller
}
{% else %}
@available(iOS 13.0, tvOS 13.0, *)
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T {
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}(creator: block) else {
fatalError("Storyboard \(storyboard.storyboardName) does not have an initial scene.")
}
return controller
}
{% endif %}
}
{% if not param.bundle and not param.lookupFunction %}
// swiftlint:disable convenience_type
private final class BundleToken {
static let bundle: Bundle = {
#if SWIFT_PACKAGE
return Bundle.module
#else
return Bundle(for: BundleToken.self)
#endif
}()
}
// swiftlint:enable convenience_type
{% endif %}
{% elif storyboards %}
// Mixed AppKit and UIKit storyboard files found, please invoke swiftgen with these separately
{% else %}
// No storyboard found
{% endif %}

View file

@ -0,0 +1,159 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if platform and storyboards %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
{% set isAppKit %}{% if platform == "macOS" %}true{% endif %}{% endset %}
{% set prefix %}{% if isAppKit %}NS{% else %}UI{% endif %}{% endset %}
{% set controller %}{% if isAppKit %}Controller{% else %}ViewController{% endif %}{% endset %}
// swiftlint:disable sorted_imports
import Foundation
{% for module in modules where module != env.PRODUCT_MODULE_NAME and module != param.module %}
import {{module}}
{% endfor %}
// swiftlint:disable superfluous_disable_command
// swiftlint:disable file_length implicit_return
// MARK: - Storyboard Scenes
// swiftlint:disable explicit_type_interface identifier_name line_length type_body_length type_name
{% macro moduleName item %}{% filter removeNewlines %}
{% if item.moduleIsPlaceholder %}
{{ env.PRODUCT_MODULE_NAME|default:param.module }}
{% else %}
{{ item.module }}
{% endif %}
{% endfilter %}{% endmacro %}
{% macro className item %}{% filter removeNewlines %}
{% set module %}{% call moduleName item %}{% endset %}
{% if module and ( not param.ignoreTargetModule or module != env.PRODUCT_MODULE_NAME and module != param.module ) %}
{{module}}.
{% endif %}
{{item.type}}
{% endfilter %}{% endmacro %}
{{accessModifier}} enum {{param.enumName|default:"StoryboardScene"}} {
{% for storyboard in storyboards %}
{% set storyboardName %}{{storyboard.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}{% endset %}
{{accessModifier}} enum {{storyboardName}}: StoryboardType {
{{accessModifier}} static let storyboardName = "{{storyboard.name}}"
{% if storyboard.initialScene %}
{% set sceneClass %}{% call className storyboard.initialScene %}{% endset %}
{{accessModifier}} static let initialScene = InitialSceneType<{{sceneClass}}>(storyboard: {{storyboardName}}.self)
{% endif %}
{% for scene in storyboard.scenes %}
{% set sceneID %}{{scene.identifier|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
{% set sceneClass %}{% call className scene %}{% endset %}
{{accessModifier}} static let {{sceneID}} = SceneType<{{sceneClass}}>(storyboard: {{storyboardName}}.self, identifier: "{{scene.identifier}}")
{% endfor %}
}
{% endfor %}
}
// swiftlint:enable explicit_type_interface identifier_name line_length type_body_length type_name
// MARK: - Implementation Details
{{accessModifier}} protocol StoryboardType {
static var storyboardName: String { get }
}
{{accessModifier}} extension StoryboardType {
static var storyboard: {{prefix}}Storyboard {
let name = {% if isAppKit %}NSStoryboard.Name({% endif %}self.storyboardName{% if isAppKit %}){% endif %}
{% if param.lookupFunction %}
return {{param.lookupFunction}}(name)
{% else %}
return {{prefix}}Storyboard(name: name, bundle: {{param.bundle|default:"BundleToken.bundle"}})
{% endif %}
}
}
{{accessModifier}} struct SceneType<T{% if not isAppKit %}: UIViewController{% endif %}> {
{{accessModifier}} let storyboard: StoryboardType.Type
{{accessModifier}} let identifier: String
{{accessModifier}} func instantiate() -> T {
let identifier = {% if isAppKit %}NSStoryboard.SceneIdentifier({% endif %}self.identifier{% if isAppKit %}){% endif %}
guard let controller = storyboard.storyboard.instantiate{{controller}}(withIdentifier: identifier) as? T else {
fatalError("{{controller}} '\(identifier)' is not of the expected class \(T.self).")
}
return controller
}
{% if isAppKit %}
@available(macOS 10.15, *)
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSViewController {
let identifier = NSStoryboard.SceneIdentifier(self.identifier)
return storyboard.storyboard.instantiate{{controller}}(identifier: identifier, creator: block)
}
@available(macOS 10.15, *)
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSWindowController {
let identifier = NSStoryboard.SceneIdentifier(self.identifier)
return storyboard.storyboard.instantiate{{controller}}(identifier: identifier, creator: block)
}
{% else %}
@available(iOS 13.0, tvOS 13.0, *)
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T {
return storyboard.storyboard.instantiate{{controller}}(identifier: identifier, creator: block)
}
{% endif %}
}
{{accessModifier}} struct InitialSceneType<T{% if not isAppKit %}: UIViewController{% endif %}> {
{{accessModifier}} let storyboard: StoryboardType.Type
{{accessModifier}} func instantiate() -> T {
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}() as? T else {
fatalError("{{controller}} is not of the expected class \(T.self).")
}
return controller
}
{% if isAppKit %}
@available(macOS 10.15, *)
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSViewController {
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}(creator: block) else {
fatalError("Storyboard \(storyboard.storyboardName) does not have an initial scene.")
}
return controller
}
@available(macOS 10.15, *)
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T where T: NSWindowController {
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}(creator: block) else {
fatalError("Storyboard \(storyboard.storyboardName) does not have an initial scene.")
}
return controller
}
{% else %}
@available(iOS 13.0, tvOS 13.0, *)
{{accessModifier}} func instantiate(creator block: @escaping (NSCoder) -> T?) -> T {
guard let controller = storyboard.storyboard.instantiateInitial{{controller}}(creator: block) else {
fatalError("Storyboard \(storyboard.storyboardName) does not have an initial scene.")
}
return controller
}
{% endif %}
}
{% if not param.bundle and not param.lookupFunction %}
// swiftlint:disable convenience_type
private final class BundleToken {
static let bundle: Bundle = {
#if SWIFT_PACKAGE
return Bundle.module
#else
return Bundle(for: BundleToken.self)
#endif
}()
}
// swiftlint:enable convenience_type
{% endif %}
{% elif storyboards %}
// Mixed AppKit and UIKit storyboard files found, please invoke swiftgen with these separately
{% else %}
// No storyboard found
{% endif %}

View file

@ -0,0 +1,60 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if platform and storyboards %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
{% set isAppKit %}{% if platform == "macOS" %}true{% endif %}{% endset %}
// swiftlint:disable sorted_imports
import Foundation
{% for module in modules where module != env.PRODUCT_MODULE_NAME and module != param.module %}
import {{module}}
{% endfor %}
// swiftlint:disable superfluous_disable_command
// swiftlint:disable file_length
// MARK: - Storyboard Segues
// swiftlint:disable explicit_type_interface identifier_name line_length type_body_length type_name
{{accessModifier}} enum {{param.enumName|default:"StoryboardSegue"}} {
{% for storyboard in storyboards where storyboard.segues %}
{{accessModifier}} enum {{storyboard.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}: String, SegueType {
{% for segue in storyboard.segues %}
{% set segueID %}{{segue.identifier|swiftIdentifier:"pretty"|lowerFirstWord}}{% endset %}
case {{segueID|escapeReservedKeywords}}{% if segueID != segue.identifier %} = "{{segue.identifier}}"{% endif %}
{% endfor %}
}
{% endfor %}
}
// swiftlint:enable explicit_type_interface identifier_name line_length type_body_length type_name
// MARK: - Implementation Details
{{accessModifier}} protocol SegueType: RawRepresentable {}
{{accessModifier}} extension {% if isAppKit %}NSSeguePerforming{% else %}UIViewController{% endif %} {
func perform<S: SegueType>(segue: S, sender: Any? = nil) where S.RawValue == String {
let identifier = {% if isAppKit %}NSStoryboardSegue.Identifier({% endif %}segue.rawValue{% if isAppKit %}){% endif %}
performSegue{% if isAppKit %}?{% endif %}(withIdentifier: identifier, sender: sender)
}
}
{{accessModifier}} extension SegueType where RawValue == String {
init?(_ segue: {% if isAppKit %}NS{% else %}UI{% endif %}StoryboardSegue) {
{% if isAppKit %}
#if swift(>=4.2)
guard let identifier = segue.identifier else { return nil }
#else
guard let identifier = segue.identifier?.rawValue else { return nil }
#endif
{% else %}
guard let identifier = segue.identifier else { return nil }
{% endif %}
self.init(rawValue: identifier)
}
}
{% elif storyboards %}
// Mixed AppKit and UIKit storyboard files found, please invoke swiftgen with these separately
{% else %}
// No storyboard found
{% endif %}

View file

@ -0,0 +1,60 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if platform and storyboards %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
{% set isAppKit %}{% if platform == "macOS" %}true{% endif %}{% endset %}
// swiftlint:disable sorted_imports
import Foundation
{% for module in modules where module != env.PRODUCT_MODULE_NAME and module != param.module %}
import {{module}}
{% endfor %}
// swiftlint:disable superfluous_disable_command
// swiftlint:disable file_length
// MARK: - Storyboard Segues
// swiftlint:disable explicit_type_interface identifier_name line_length type_body_length type_name
{{accessModifier}} enum {{param.enumName|default:"StoryboardSegue"}} {
{% for storyboard in storyboards where storyboard.segues %}
{{accessModifier}} enum {{storyboard.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}: String, SegueType {
{% for segue in storyboard.segues %}
{% set segueID %}{{segue.identifier|swiftIdentifier:"pretty"|lowerFirstWord}}{% endset %}
case {{segueID|escapeReservedKeywords}}{% if segueID != segue.identifier %} = "{{segue.identifier}}"{% endif %}
{% endfor %}
}
{% endfor %}
}
// swiftlint:enable explicit_type_interface identifier_name line_length type_body_length type_name
// MARK: - Implementation Details
{{accessModifier}} protocol SegueType: RawRepresentable {}
{{accessModifier}} extension {% if isAppKit %}NSSeguePerforming{% else %}UIViewController{% endif %} {
func perform<S: SegueType>(segue: S, sender: Any? = nil) where S.RawValue == String {
let identifier = {% if isAppKit %}NSStoryboardSegue.Identifier({% endif %}segue.rawValue{% if isAppKit %}){% endif %}
performSegue{% if isAppKit %}?{% endif %}(withIdentifier: identifier, sender: sender)
}
}
{{accessModifier}} extension SegueType where RawValue == String {
init?(_ segue: {% if isAppKit %}NS{% else %}UI{% endif %}StoryboardSegue) {
{% if isAppKit %}
#if swift(>=4.2)
guard let identifier = segue.identifier else { return nil }
#else
guard let identifier = segue.identifier?.rawValue else { return nil }
#endif
{% else %}
guard let identifier = segue.identifier else { return nil }
{% endif %}
self.init(rawValue: identifier)
}
}
{% elif storyboards %}
// Mixed AppKit and UIKit storyboard files found, please invoke swiftgen with these separately
{% else %}
// No storyboard found
{% endif %}

View file

@ -0,0 +1,82 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if files %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
import Foundation
// swiftlint:disable superfluous_disable_command
// swiftlint:disable file_length
// MARK: - JSON Files
{% macro fileBlock file %}
{% call documentBlock file file.document %}
{% endmacro %}
{% macro documentBlock file document %}
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
{% if document.metadata.type == "Array" %}
{{accessModifier}} static let items: {{rootType}} = {% call valueBlock document.data document.metadata %}
{% elif document.metadata.type == "Dictionary" %}
{% for key,value in document.metadata.properties %}
{{accessModifier}} {% call propertyBlock key value document.data %}
{% endfor %}
{% else %}
{{accessModifier}} static let value: {{rootType}} = {% call valueBlock document.data document.metadata %}
{% endif %}
{% endmacro %}
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
{% if metadata.type == "Array" %}
[{% call typeBlock metadata.element %}]
{% elif metadata.type == "Dictionary" %}
[String: Any]
{% elif metadata.type == "Optional" %}
Any?
{% else %}
{{metadata.type}}
{% endif %}
{% endfilter %}{% endmacro %}
{% macro propertyBlock key metadata data %}{% filter removeNewlines:"leading" %}
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
static let {{propertyName}}: {{propertyType}} = {% call valueBlock data[key] metadata %}
{% endfilter %}{% endmacro %}
{% macro valueBlock value metadata %}{% filter removeNewlines:"leading" %}
{% if metadata.type == "String" %}
"{{ value }}"
{% elif metadata.type == "Optional" %}
nil
{% elif metadata.type == "Array" and value %}
[{% for value in value %}
{% call valueBlock value metadata.element.items[forloop.counter0]|default:metadata.element %}
{{ ", " if not forloop.last }}
{% endfor %}]
{% elif metadata.type == "Dictionary" %}
[{% for key,value in value %}
"{{key}}": {% call valueBlock value metadata.properties[key] %}
{{ ", " if not forloop.last }}
{% empty %}
:
{% endfor %}]
{% elif metadata.type == "Bool" %}
{% if value %}true{% else %}false{% endif %}
{% else %}
{{ value }}
{% endif %}
{% endfilter %}{% endmacro %}
// swiftlint:disable identifier_name line_length number_separator type_body_length
{{accessModifier}} enum {{param.enumName|default:"JSONFiles"}} {
{% if files.count > 1 or param.forceFileNameEnum %}
{% for file in files %}
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call fileBlock files.first %}
{% endif %}
}
// swiftlint:enable identifier_name line_length number_separator type_body_length
{% else %}
// No files found
{% endif %}

View file

@ -0,0 +1,82 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if files %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
import Foundation
// swiftlint:disable superfluous_disable_command
// swiftlint:disable file_length
// MARK: - JSON Files
{% macro fileBlock file %}
{% call documentBlock file file.document %}
{% endmacro %}
{% macro documentBlock file document %}
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
{% if document.metadata.type == "Array" %}
{{accessModifier}} static let items: {{rootType}} = {% call valueBlock document.data document.metadata %}
{% elif document.metadata.type == "Dictionary" %}
{% for key,value in document.metadata.properties %}
{{accessModifier}} {% call propertyBlock key value document.data %}
{% endfor %}
{% else %}
{{accessModifier}} static let value: {{rootType}} = {% call valueBlock document.data document.metadata %}
{% endif %}
{% endmacro %}
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
{% if metadata.type == "Array" %}
[{% call typeBlock metadata.element %}]
{% elif metadata.type == "Dictionary" %}
[String: Any]
{% elif metadata.type == "Optional" %}
Any?
{% else %}
{{metadata.type}}
{% endif %}
{% endfilter %}{% endmacro %}
{% macro propertyBlock key metadata data %}{% filter removeNewlines:"leading" %}
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
static let {{propertyName}}: {{propertyType}} = {% call valueBlock data[key] metadata %}
{% endfilter %}{% endmacro %}
{% macro valueBlock value metadata %}{% filter removeNewlines:"leading" %}
{% if metadata.type == "String" %}
"{{ value }}"
{% elif metadata.type == "Optional" %}
nil
{% elif metadata.type == "Array" and value %}
[{% for value in value %}
{% call valueBlock value metadata.element.items[forloop.counter0]|default:metadata.element %}
{{ ", " if not forloop.last }}
{% endfor %}]
{% elif metadata.type == "Dictionary" %}
[{% for key,value in value %}
"{{key}}": {% call valueBlock value metadata.properties[key] %}
{{ ", " if not forloop.last }}
{% empty %}
:
{% endfor %}]
{% elif metadata.type == "Bool" %}
{% if value %}true{% else %}false{% endif %}
{% else %}
{{ value }}
{% endif %}
{% endfilter %}{% endmacro %}
// swiftlint:disable identifier_name line_length number_separator type_body_length
{{accessModifier}} enum {{param.enumName|default:"JSONFiles"}} {
{% if files.count > 1 or param.forceFileNameEnum %}
{% for file in files %}
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call fileBlock files.first %}
{% endif %}
}
// swiftlint:enable identifier_name line_length number_separator type_body_length
{% else %}
// No files found
{% endif %}

View file

@ -0,0 +1,112 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if files %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
import Foundation
// swiftlint:disable superfluous_disable_command
// swiftlint:disable file_length
// MARK: - JSON Files
{% macro fileBlock file %}
{% call documentBlock file file.document %}
{% endmacro %}
{% macro documentBlock file document %}
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
{% if document.metadata.type == "Array" %}
{{accessModifier}} static let items: {{rootType}} = objectFromJSON(at: "{% call transformPath file.path %}")
{% elif document.metadata.type == "Dictionary" %}
private static let _document = JSONDocument(path: "{% call transformPath file.path %}")
{% for key,value in document.metadata.properties %}
{{accessModifier}} {% call propertyBlock key value %}
{% endfor %}
{% else %}
{{accessModifier}} static let value: {{rootType}} = objectFromJSON(at: "{% call transformPath file.path %}")
{% endif %}
{% endmacro %}
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
{% if metadata.type == "Array" %}
[{% call typeBlock metadata.element %}]
{% elif metadata.type == "Dictionary" %}
[String: Any]
{% elif metadata.type == "Optional" %}
Any?
{% else %}
{{metadata.type}}
{% endif %}
{% endfilter %}{% endmacro %}
{% macro propertyBlock key metadata %}{% filter removeNewlines:"leading" %}
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
static let {{propertyName}}: {{propertyType}} = _document["{{key}}"]
{% endfilter %}{% endmacro %}
{% macro transformPath path %}{% filter removeNewlines %}
{% if param.preservePath %}
{{path}}
{% else %}
{{path|basename}}
{% endif %}
{% endfilter %}{% endmacro %}
// swiftlint:disable identifier_name line_length type_body_length
{{accessModifier}} enum {{param.enumName|default:"JSONFiles"}} {
{% if files.count > 1 or param.forceFileNameEnum %}
{% for file in files %}
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call fileBlock files.first %}
{% endif %}
}
// swiftlint:enable identifier_name line_length type_body_length
// MARK: - Implementation Details
private func objectFromJSON<T>(at path: String) -> T {
{% if param.lookupFunction %}
guard let url = {{param.lookupFunction}}(path),
{% else %}
guard let url = {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil),
{% endif %}
let json = try? JSONSerialization.jsonObject(with: Data(contentsOf: url), options: []),
let result = json as? T else {
fatalError("Unable to load JSON at path: \(path)")
}
return result
}
private struct JSONDocument {
let data: [String: Any]
init(path: String) {
self.data = objectFromJSON(at: path)
}
subscript<T>(key: String) -> T {
guard let result = data[key] as? T else {
fatalError("Property '\(key)' is not of type \(T.self)")
}
return result
}
}
{% if not param.bundle and not param.lookupFunction %}
// swiftlint:disable convenience_type
private final class BundleToken {
static let bundle: Bundle = {
#if SWIFT_PACKAGE
return Bundle.module
#else
return Bundle(for: BundleToken.self)
#endif
}()
}
// swiftlint:enable convenience_type
{% endif %}
{% else %}
// No files found
{% endif %}

View file

@ -0,0 +1,112 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if files %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
import Foundation
// swiftlint:disable superfluous_disable_command
// swiftlint:disable file_length
// MARK: - JSON Files
{% macro fileBlock file %}
{% call documentBlock file file.document %}
{% endmacro %}
{% macro documentBlock file document %}
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
{% if document.metadata.type == "Array" %}
{{accessModifier}} static let items: {{rootType}} = objectFromJSON(at: "{% call transformPath file.path %}")
{% elif document.metadata.type == "Dictionary" %}
private static let _document = JSONDocument(path: "{% call transformPath file.path %}")
{% for key,value in document.metadata.properties %}
{{accessModifier}} {% call propertyBlock key value %}
{% endfor %}
{% else %}
{{accessModifier}} static let value: {{rootType}} = objectFromJSON(at: "{% call transformPath file.path %}")
{% endif %}
{% endmacro %}
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
{% if metadata.type == "Array" %}
[{% call typeBlock metadata.element %}]
{% elif metadata.type == "Dictionary" %}
[String: Any]
{% elif metadata.type == "Optional" %}
Any?
{% else %}
{{metadata.type}}
{% endif %}
{% endfilter %}{% endmacro %}
{% macro propertyBlock key metadata %}{% filter removeNewlines:"leading" %}
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
static let {{propertyName}}: {{propertyType}} = _document["{{key}}"]
{% endfilter %}{% endmacro %}
{% macro transformPath path %}{% filter removeNewlines %}
{% if param.preservePath %}
{{path}}
{% else %}
{{path|basename}}
{% endif %}
{% endfilter %}{% endmacro %}
// swiftlint:disable identifier_name line_length type_body_length
{{accessModifier}} enum {{param.enumName|default:"JSONFiles"}} {
{% if files.count > 1 or param.forceFileNameEnum %}
{% for file in files %}
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call fileBlock files.first %}
{% endif %}
}
// swiftlint:enable identifier_name line_length type_body_length
// MARK: - Implementation Details
private func objectFromJSON<T>(at path: String) -> T {
{% if param.lookupFunction %}
guard let url = {{param.lookupFunction}}(path),
{% else %}
guard let url = {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil),
{% endif %}
let json = try? JSONSerialization.jsonObject(with: Data(contentsOf: url), options: []),
let result = json as? T else {
fatalError("Unable to load JSON at path: \(path)")
}
return result
}
private struct JSONDocument {
let data: [String: Any]
init(path: String) {
self.data = objectFromJSON(at: path)
}
subscript<T>(key: String) -> T {
guard let result = data[key] as? T else {
fatalError("Property '\(key)' is not of type \(T.self)")
}
return result
}
}
{% if not param.bundle and not param.lookupFunction %}
// swiftlint:disable convenience_type
private final class BundleToken {
static let bundle: Bundle = {
#if SWIFT_PACKAGE
return Bundle.module
#else
return Bundle(for: BundleToken.self)
#endif
}()
}
// swiftlint:enable convenience_type
{% endif %}
{% else %}
// No files found
{% endif %}

View file

@ -0,0 +1,82 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if files %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
import Foundation
// swiftlint:disable superfluous_disable_command
// swiftlint:disable file_length
// MARK: - Plist Files
{% macro fileBlock file %}
{% call documentBlock file file.document %}
{% endmacro %}
{% macro documentBlock file document %}
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
{% if document.metadata.type == "Array" %}
{{accessModifier}} static let items: {{rootType}} = {% call valueBlock document.data document.metadata %}
{% elif document.metadata.type == "Dictionary" %}
{% for key,value in document.metadata.properties %}
{{accessModifier}} {% call propertyBlock key value document.data %}
{% endfor %}
{% else %}
{{accessModifier}} static let value: {{rootType}} = {% call valueBlock document.data document.metadata %}
{% endif %}
{% endmacro %}
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
{% if metadata.type == "Array" %}
[{% call typeBlock metadata.element %}]
{% elif metadata.type == "Dictionary" %}
[String: Any]
{% else %}
{{metadata.type}}
{% endif %}
{% endfilter %}{% endmacro %}
{% macro propertyBlock key metadata data %}{% filter removeNewlines:"leading" %}
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
static let {{propertyName}}: {{propertyType}} = {% call valueBlock data[key] metadata %}
{% endfilter %}{% endmacro %}
{% macro valueBlock value metadata %}{% filter removeNewlines:"leading" %}
{% if metadata.type == "String" %}
"{{ value }}"
{% elif metadata.type == "Date" %}
Date(timeIntervalSinceReferenceDate: {{ value.timeIntervalSinceReferenceDate }})
{% elif metadata.type == "Optional" %}
nil
{% elif metadata.type == "Array" and value %}
[{% for value in value %}
{% call valueBlock value metadata.element.items[forloop.counter0]|default:metadata.element %}
{{ ", " if not forloop.last }}
{% endfor %}]
{% elif metadata.type == "Dictionary" %}
[{% for key,value in value %}
"{{key}}": {% call valueBlock value metadata.properties[key] %}
{{ ", " if not forloop.last }}
{% empty %}
:
{% endfor %}]
{% elif metadata.type == "Bool" %}
{% if value %}true{% else %}false{% endif %}
{% else %}
{{ value }}
{% endif %}
{% endfilter %}{% endmacro %}
// swiftlint:disable identifier_name line_length number_separator type_body_length
{{accessModifier}} enum {{param.enumName|default:"PlistFiles"}} {
{% if files.count > 1 or param.forceFileNameEnum %}
{% for file in files %}
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call fileBlock files.first %}
{% endif %}
}
// swiftlint:enable identifier_name line_length number_separator type_body_length
{% else %}
// No files found
{% endif %}

View file

@ -0,0 +1,82 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if files %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
import Foundation
// swiftlint:disable superfluous_disable_command
// swiftlint:disable file_length
// MARK: - Plist Files
{% macro fileBlock file %}
{% call documentBlock file file.document %}
{% endmacro %}
{% macro documentBlock file document %}
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
{% if document.metadata.type == "Array" %}
{{accessModifier}} static let items: {{rootType}} = {% call valueBlock document.data document.metadata %}
{% elif document.metadata.type == "Dictionary" %}
{% for key,value in document.metadata.properties %}
{{accessModifier}} {% call propertyBlock key value document.data %}
{% endfor %}
{% else %}
{{accessModifier}} static let value: {{rootType}} = {% call valueBlock document.data document.metadata %}
{% endif %}
{% endmacro %}
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
{% if metadata.type == "Array" %}
[{% call typeBlock metadata.element %}]
{% elif metadata.type == "Dictionary" %}
[String: Any]
{% else %}
{{metadata.type}}
{% endif %}
{% endfilter %}{% endmacro %}
{% macro propertyBlock key metadata data %}{% filter removeNewlines:"leading" %}
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
static let {{propertyName}}: {{propertyType}} = {% call valueBlock data[key] metadata %}
{% endfilter %}{% endmacro %}
{% macro valueBlock value metadata %}{% filter removeNewlines:"leading" %}
{% if metadata.type == "String" %}
"{{ value }}"
{% elif metadata.type == "Date" %}
Date(timeIntervalSinceReferenceDate: {{ value.timeIntervalSinceReferenceDate }})
{% elif metadata.type == "Optional" %}
nil
{% elif metadata.type == "Array" and value %}
[{% for value in value %}
{% call valueBlock value metadata.element.items[forloop.counter0]|default:metadata.element %}
{{ ", " if not forloop.last }}
{% endfor %}]
{% elif metadata.type == "Dictionary" %}
[{% for key,value in value %}
"{{key}}": {% call valueBlock value metadata.properties[key] %}
{{ ", " if not forloop.last }}
{% empty %}
:
{% endfor %}]
{% elif metadata.type == "Bool" %}
{% if value %}true{% else %}false{% endif %}
{% else %}
{{ value }}
{% endif %}
{% endfilter %}{% endmacro %}
// swiftlint:disable identifier_name line_length number_separator type_body_length
{{accessModifier}} enum {{param.enumName|default:"PlistFiles"}} {
{% if files.count > 1 or param.forceFileNameEnum %}
{% for file in files %}
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call fileBlock files.first %}
{% endif %}
}
// swiftlint:enable identifier_name line_length number_separator type_body_length
{% else %}
// No files found
{% endif %}

View file

@ -0,0 +1,117 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if files %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
import Foundation
// swiftlint:disable superfluous_disable_command
// swiftlint:disable file_length
// MARK: - Plist Files
{% macro fileBlock file %}
{% call documentBlock file file.document %}
{% endmacro %}
{% macro documentBlock file document %}
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
{% if document.metadata.type == "Array" %}
{{accessModifier}} static let items: {{rootType}} = arrayFromPlist(at: "{% call transformPath file.path %}")
{% elif document.metadata.type == "Dictionary" %}
private static let _document = PlistDocument(path: "{% call transformPath file.path %}")
{% for key,value in document.metadata.properties %}
{{accessModifier}} {% call propertyBlock key value %}
{% endfor %}
{% else %}
// Unsupported root type `{{rootType}}`
{% endif %}
{% endmacro %}
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
{% if metadata.type == "Array" %}
[{% call typeBlock metadata.element %}]
{% elif metadata.type == "Dictionary" %}
[String: Any]
{% else %}
{{metadata.type}}
{% endif %}
{% endfilter %}{% endmacro %}
{% macro propertyBlock key metadata %}{% filter removeNewlines:"leading" %}
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
static let {{propertyName}}: {{propertyType}} = _document["{{key}}"]
{% endfilter %}{% endmacro %}
{% macro transformPath path %}{% filter removeNewlines %}
{% if param.preservePath %}
{{path}}
{% else %}
{{path|basename}}
{% endif %}
{% endfilter %}{% endmacro %}
// swiftlint:disable identifier_name line_length type_body_length
{{accessModifier}} enum {{param.enumName|default:"PlistFiles"}} {
{% if files.count > 1 or param.forceFileNameEnum %}
{% for file in files %}
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call fileBlock files.first %}
{% endif %}
}
// swiftlint:enable identifier_name line_length type_body_length
// MARK: - Implementation Details
private func arrayFromPlist<T>(at path: String) -> [T] {
{% if param.lookupFunction %}
guard let url = {{param.lookupFunction}}(path),
{% else %}
guard let url = {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil),
{% endif %}
let data = NSArray(contentsOf: url) as? [T] else {
fatalError("Unable to load PLIST at path: \(path)")
}
return data
}
private struct PlistDocument {
let data: [String: Any]
init(path: String) {
{% if param.lookupFunction %}
guard let url = {{param.lookupFunction}}(path),
{% else %}
guard let url = {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil),
{% endif %}
let data = NSDictionary(contentsOf: url) as? [String: Any] else {
fatalError("Unable to load PLIST at path: \(path)")
}
self.data = data
}
subscript<T>(key: String) -> T {
guard let result = data[key] as? T else {
fatalError("Property '\(key)' is not of type \(T.self)")
}
return result
}
}
{% if not param.bundle and not param.lookupFunction %}
// swiftlint:disable convenience_type
private final class BundleToken {
static let bundle: Bundle = {
#if SWIFT_PACKAGE
return Bundle.module
#else
return Bundle(for: BundleToken.self)
#endif
}()
}
// swiftlint:enable convenience_type
{% endif %}
{% else %}
// No files found
{% endif %}

View file

@ -0,0 +1,117 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if files %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
import Foundation
// swiftlint:disable superfluous_disable_command
// swiftlint:disable file_length
// MARK: - Plist Files
{% macro fileBlock file %}
{% call documentBlock file file.document %}
{% endmacro %}
{% macro documentBlock file document %}
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
{% if document.metadata.type == "Array" %}
{{accessModifier}} static let items: {{rootType}} = arrayFromPlist(at: "{% call transformPath file.path %}")
{% elif document.metadata.type == "Dictionary" %}
private static let _document = PlistDocument(path: "{% call transformPath file.path %}")
{% for key,value in document.metadata.properties %}
{{accessModifier}} {% call propertyBlock key value %}
{% endfor %}
{% else %}
// Unsupported root type `{{rootType}}`
{% endif %}
{% endmacro %}
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
{% if metadata.type == "Array" %}
[{% call typeBlock metadata.element %}]
{% elif metadata.type == "Dictionary" %}
[String: Any]
{% else %}
{{metadata.type}}
{% endif %}
{% endfilter %}{% endmacro %}
{% macro propertyBlock key metadata %}{% filter removeNewlines:"leading" %}
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
static let {{propertyName}}: {{propertyType}} = _document["{{key}}"]
{% endfilter %}{% endmacro %}
{% macro transformPath path %}{% filter removeNewlines %}
{% if param.preservePath %}
{{path}}
{% else %}
{{path|basename}}
{% endif %}
{% endfilter %}{% endmacro %}
// swiftlint:disable identifier_name line_length type_body_length
{{accessModifier}} enum {{param.enumName|default:"PlistFiles"}} {
{% if files.count > 1 or param.forceFileNameEnum %}
{% for file in files %}
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call fileBlock files.first %}
{% endif %}
}
// swiftlint:enable identifier_name line_length type_body_length
// MARK: - Implementation Details
private func arrayFromPlist<T>(at path: String) -> [T] {
{% if param.lookupFunction %}
guard let url = {{param.lookupFunction}}(path),
{% else %}
guard let url = {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil),
{% endif %}
let data = NSArray(contentsOf: url) as? [T] else {
fatalError("Unable to load PLIST at path: \(path)")
}
return data
}
private struct PlistDocument {
let data: [String: Any]
init(path: String) {
{% if param.lookupFunction %}
guard let url = {{param.lookupFunction}}(path),
{% else %}
guard let url = {{param.bundle|default:"BundleToken.bundle"}}.url(forResource: path, withExtension: nil),
{% endif %}
let data = NSDictionary(contentsOf: url) as? [String: Any] else {
fatalError("Unable to load PLIST at path: \(path)")
}
self.data = data
}
subscript<T>(key: String) -> T {
guard let result = data[key] as? T else {
fatalError("Property '\(key)' is not of type \(T.self)")
}
return result
}
}
{% if not param.bundle and not param.lookupFunction %}
// swiftlint:disable convenience_type
private final class BundleToken {
static let bundle: Bundle = {
#if SWIFT_PACKAGE
return Bundle.module
#else
return Bundle(for: BundleToken.self)
#endif
}()
}
// swiftlint:enable convenience_type
{% endif %}
{% else %}
// No files found
{% endif %}

View file

@ -0,0 +1,99 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if tables.count > 0 %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
import Foundation
// swiftlint:disable superfluous_disable_command file_length implicit_return
// MARK: - Strings
{% macro parametersBlock types %}{% filter removeNewlines:"leading" %}
{% for type in types %}
{% if type == "String" %}
_ p{{forloop.counter}}: Any
{% else %}
_ p{{forloop.counter}}: {{type}}
{% endif %}
{{ ", " if not forloop.last }}
{% endfor %}
{% endfilter %}{% endmacro %}
{% macro argumentsBlock types %}{% filter removeNewlines:"leading" %}
{% for type in types %}
{% if type == "String" %}
String(describing: p{{forloop.counter}})
{% elif type == "UnsafeRawPointer" %}
Int(bitPattern: p{{forloop.counter}})
{% else %}
p{{forloop.counter}}
{% endif %}
{{ ", " if not forloop.last }}
{% endfor %}
{% endfilter %}{% endmacro %}
{% macro recursiveBlock table item %}
{% for string in item.strings %}
{% if not param.noComments %}
{% for line in string.translation|split:"\n" %}
/// {{line}}
{% endfor %}
{% endif %}
{% if string.types %}
{{accessModifier}} static func {{string.key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}({% call parametersBlock string.types %}) -> String {
return {{enumName}}.tr("{{table}}", "{{string.key}}", {% call argumentsBlock string.types %})
}
{% elif param.lookupFunction %}
{# custom localization function is mostly used for in-app lang selection, so we want the loc to be recomputed at each call for those (hence the computed var) #}
{{accessModifier}} static var {{string.key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}: String { return {{enumName}}.tr("{{table}}", "{{string.key}}") }
{% else %}
{{accessModifier}} static let {{string.key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{enumName}}.tr("{{table}}", "{{string.key}}")
{% endif %}
{% endfor %}
{% for child in item.children %}
{% call recursiveBlock table child %}
{% endfor %}
{% endmacro %}
// swiftlint:disable function_parameter_count identifier_name line_length type_body_length
{% set enumName %}{{param.enumName|default:"L10n"}}{% endset %}
{{accessModifier}} enum {{enumName}} {
{% if tables.count > 1 or param.forceFileNameEnum %}
{% for table in tables %}
{{accessModifier}} enum {{table.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call recursiveBlock table.name table.levels %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call recursiveBlock tables.first.name tables.first.levels %}
{% endif %}
}
// swiftlint:enable function_parameter_count identifier_name line_length type_body_length
// MARK: - Implementation Details
extension {{enumName}} {
private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
{% if param.lookupFunction %}
let format = {{ param.lookupFunction }}(key, table)
{% else %}
let format = {{param.bundle|default:"BundleToken.bundle"}}.localizedString(forKey: key, value: nil, table: table)
{% endif %}
return String(format: format, locale: Locale.current, arguments: args)
}
}
{% if not param.bundle and not param.lookupFunction %}
// swiftlint:disable convenience_type
private final class BundleToken {
static let bundle: Bundle = {
#if SWIFT_PACKAGE
return Bundle.module
#else
return Bundle(for: BundleToken.self)
#endif
}()
}
// swiftlint:enable convenience_type
{% endif %}
{% else %}
// No string found
{% endif %}

View file

@ -0,0 +1,99 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if tables.count > 0 %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
import Foundation
// swiftlint:disable superfluous_disable_command file_length implicit_return
// MARK: - Strings
{% macro parametersBlock types %}{% filter removeNewlines:"leading" %}
{% for type in types %}
{% if type == "String" %}
_ p{{forloop.counter}}: Any
{% else %}
_ p{{forloop.counter}}: {{type}}
{% endif %}
{{ ", " if not forloop.last }}
{% endfor %}
{% endfilter %}{% endmacro %}
{% macro argumentsBlock types %}{% filter removeNewlines:"leading" %}
{% for type in types %}
{% if type == "String" %}
String(describing: p{{forloop.counter}})
{% elif type == "UnsafeRawPointer" %}
Int(bitPattern: p{{forloop.counter}})
{% else %}
p{{forloop.counter}}
{% endif %}
{{ ", " if not forloop.last }}
{% endfor %}
{% endfilter %}{% endmacro %}
{% macro recursiveBlock table item %}
{% for string in item.strings %}
{% if not param.noComments %}
{% for line in string.translation|split:"\n" %}
/// {{line}}
{% endfor %}
{% endif %}
{% if string.types %}
{{accessModifier}} static func {{string.key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}({% call parametersBlock string.types %}) -> String {
return {{enumName}}.tr("{{table}}", "{{string.key}}", {% call argumentsBlock string.types %})
}
{% elif param.lookupFunction %}
{# custom localization function is mostly used for in-app lang selection, so we want the loc to be recomputed at each call for those (hence the computed var) #}
{{accessModifier}} static var {{string.key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}: String { return {{enumName}}.tr("{{table}}", "{{string.key}}") }
{% else %}
{{accessModifier}} static let {{string.key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{enumName}}.tr("{{table}}", "{{string.key}}")
{% endif %}
{% endfor %}
{% for child in item.children %}
{% call recursiveBlock table child %}
{% endfor %}
{% endmacro %}
// swiftlint:disable function_parameter_count identifier_name line_length type_body_length
{% set enumName %}{{param.enumName|default:"L10n"}}{% endset %}
{{accessModifier}} enum {{enumName}} {
{% if tables.count > 1 or param.forceFileNameEnum %}
{% for table in tables %}
{{accessModifier}} enum {{table.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call recursiveBlock table.name table.levels %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call recursiveBlock tables.first.name tables.first.levels %}
{% endif %}
}
// swiftlint:enable function_parameter_count identifier_name line_length type_body_length
// MARK: - Implementation Details
extension {{enumName}} {
private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
{% if param.lookupFunction %}
let format = {{ param.lookupFunction }}(key, table)
{% else %}
let format = {{param.bundle|default:"BundleToken.bundle"}}.localizedString(forKey: key, value: nil, table: table)
{% endif %}
return String(format: format, locale: Locale.current, arguments: args)
}
}
{% if not param.bundle and not param.lookupFunction %}
// swiftlint:disable convenience_type
private final class BundleToken {
static let bundle: Bundle = {
#if SWIFT_PACKAGE
return Bundle.module
#else
return Bundle(for: BundleToken.self)
#endif
}()
}
// swiftlint:enable convenience_type
{% endif %}
{% else %}
// No string found
{% endif %}

View file

@ -0,0 +1,68 @@
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if tables.count > 0 %}
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
{% macro parametersBlock types %}{% filter removeNewlines:"leading" %}
{% for type in types %}
({% call paramTranslate type %})p{{ forloop.counter }}{{ " :" if not forloop.last }}
{% endfor %}
{% endfilter %}{% endmacro %}
{% macro argumentsBlock types %}{% filter removeNewlines:"leading" %}
{% for type in types %}
p{{forloop.counter}}{{ ", " if not forloop.last }}
{% endfor %}
{% endfilter %}{% endmacro %}
{% macro paramTranslate swiftType %}
{% if swiftType == "Any" %}
id
{% elif swiftType == "CChar" %}
char
{% elif swiftType == "Float" %}
float
{% elif swiftType == "Int" %}
NSInteger
{% elif swiftType == "String" %}
id
{% elif swiftType == "UnsafePointer<CChar>" %}
char*
{% elif swiftType == "UnsafeRawPointer" %}
void*
{% else %}
objc-h.stencil is missing '{{swiftType}}'
{% endif %}
{% endmacro %}
{% macro emitOneMethod table item %}
{% for string in item.strings %}
{% if not param.noComments %}
{% for line in string.translation|split:"\n" %}
/// {{line}}
{% endfor %}
{% endif %}
{% if string.types %}
{% if string.types.count == 1 %}
+ (NSString*){{string.key|swiftIdentifier:"pretty"|lowerFirstWord}}WithValue:{% call parametersBlock string.types %};
{% else %}
+ (NSString*){{string.key|swiftIdentifier:"pretty"|lowerFirstWord}}WithValues:{% call parametersBlock string.types %};
{% endif %}
{% else %}
+ (NSString*){{string.key|swiftIdentifier:"pretty"|lowerFirstWord}};
{% endif %}
{% endfor %}
{% for child in item.children %}
{% call emitOneMethod table child %}
{% endfor %}
{% endmacro %}
{% for table in tables %}
@interface {{ table.name }} : NSObject
{% call emitOneMethod table.name table.levels %}
@end
{% endfor %}
NS_ASSUME_NONNULL_END
{% else %}
// No strings found
{% endif %}

View file

@ -0,0 +1,90 @@
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if tables.count > 0 %}
#import "{{ param.headerName|default:"Localizable.h" }}"
{% if not param.bundle %}
@interface BundleToken : NSObject
@end
@implementation BundleToken
@end
{% endif %}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-security"
static NSString* tr(NSString *tableName, NSString *key, ...) {
NSBundle *bundle = {{param.bundle|default:"[NSBundle bundleForClass:BundleToken.class]"}};
NSString *format = [bundle localizedStringForKey:key value:nil table:tableName];
NSLocale *locale = [NSLocale currentLocale];
va_list args;
va_start(args, key);
NSString *result = [[NSString alloc] initWithFormat:format locale:locale arguments:args];
va_end(args);
return result;
};
#pragma clang diagnostic pop
{% macro parametersBlock types %}{% filter removeNewlines:"leading" %}
{% for type in types %}
({% call paramTranslate type %})p{{ forloop.counter }}{{ " :" if not forloop.last }}
{% endfor %}
{% endfilter %}{% endmacro %}
{% macro argumentsBlock types %}{% filter removeNewlines:"leading" %}
{% for type in types %}
p{{forloop.counter}}{{ ", " if not forloop.last }}
{% endfor %}
{% endfilter %}{% endmacro %}
{% macro paramTranslate swiftType %}
{% if swiftType == "Any" %}
id
{% elif swiftType == "CChar" %}
char
{% elif swiftType == "Float" %}
float
{% elif swiftType == "Int" %}
NSInteger
{% elif swiftType == "String" %}
id
{% elif swiftType == "UnsafePointer<CChar>" %}
char*
{% elif swiftType == "UnsafeRawPointer" %}
void*
{% else %}
objc-m.stencil is missing '{{swiftType}}'
{% endif %}
{% endmacro %}
{% macro tableContents table item %}
{% for string in item.strings %}
{% if string.types %}
{% if string.types.count == 1 %}
+ (NSString*){{string.key|swiftIdentifier:"pretty"|lowerFirstWord}}WithValue:{% call parametersBlock string.types %}
{% else %}
+ (NSString*){{string.key|swiftIdentifier:"pretty"|lowerFirstWord}}WithValues:{% call parametersBlock string.types %}
{% endif %}
{
return tr(@"{{table}}", @"{{string.key}}", {% call argumentsBlock string.types %});
}
{% else %}
+ (NSString*){{string.key|swiftIdentifier:"pretty"|lowerFirstWord}} {
return tr(@"{{table}}", @"{{string.key}}");
}
{% endif %}
{% endfor %}
{% for child in item.children %}
{% call tableContents table child %}
{% endfor %}
{% endmacro %}
{% for table in tables %}
{% set tableName %}{{table.name|default:"Localized"}}{% endset %}
@implementation {{ tableName }} : NSObject
{% call tableContents table.name table.levels %}
@end
{% endfor %}
{% else %}
// No strings found
{% endif %}

View file

@ -0,0 +1,104 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if tables.count > 0 %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
import Foundation
// swiftlint:disable superfluous_disable_command file_length implicit_return
// MARK: - Strings
{% macro parametersBlock types %}{% filter removeNewlines:"leading" %}
{% for type in types %}
{% if type == "String" %}
_ p{{forloop.counter}}: Any
{% else %}
_ p{{forloop.counter}}: {{type}}
{% endif %}
{{ ", " if not forloop.last }}
{% endfor %}
{% endfilter %}{% endmacro %}
{% macro argumentsBlock types %}{% filter removeNewlines:"leading" %}
{% for type in types %}
{% if type == "String" %}
String(describing: p{{forloop.counter}})
{% elif type == "UnsafeRawPointer" %}
Int(bitPattern: p{{forloop.counter}})
{% else %}
p{{forloop.counter}}
{% endif %}
{{ ", " if not forloop.last }}
{% endfor %}
{% endfilter %}{% endmacro %}
{% macro recursiveBlock table item %}
{% for string in item.strings %}
{% if not param.noComments %}
{% for line in string.translation|split:"\n" %}
/// {{line}}
{% endfor %}
{% endif %}
{% if string.types %}
{{accessModifier}} static func {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}({% call parametersBlock string.types %}) -> String {
return {{enumName}}.tr("{{table}}", "{{string.key}}", {% call argumentsBlock string.types %})
}
{% elif param.lookupFunction %}
{# custom localization function is mostly used for in-app lang selection, so we want the loc to be recomputed at each call for those (hence the computed var) #}
{{accessModifier}} static var {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}: String { return {{enumName}}.tr("{{table}}", "{{string.key}}") }
{% else %}
{{accessModifier}} static let {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{enumName}}.tr("{{table}}", "{{string.key}}")
{% endif %}
{% endfor %}
{% for child in item.children %}
{{accessModifier}} enum {{child.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call recursiveBlock table child %}{% endfilter %}
}
{% endfor %}
{% endmacro %}
// swiftlint:disable explicit_type_interface function_parameter_count identifier_name line_length
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
{% set enumName %}{{param.enumName|default:"L10n"}}{% endset %}
{{accessModifier}} enum {{enumName}} {
{% if tables.count > 1 or param.forceFileNameEnum %}
{% for table in tables %}
{{accessModifier}} enum {{table.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call recursiveBlock table.name table.levels %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call recursiveBlock tables.first.name tables.first.levels %}
{% endif %}
}
// swiftlint:enable explicit_type_interface function_parameter_count identifier_name line_length
// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces
// MARK: - Implementation Details
extension {{enumName}} {
private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
{% if param.lookupFunction %}
let format = {{ param.lookupFunction }}(key, table)
{% else %}
let format = {{param.bundle|default:"BundleToken.bundle"}}.localizedString(forKey: key, value: nil, table: table)
{% endif %}
return String(format: format, locale: Locale.current, arguments: args)
}
}
{% if not param.bundle and not param.lookupFunction %}
// swiftlint:disable convenience_type
private final class BundleToken {
static let bundle: Bundle = {
#if SWIFT_PACKAGE
return Bundle.module
#else
return Bundle(for: BundleToken.self)
#endif
}()
}
// swiftlint:enable convenience_type
{% endif %}
{% else %}
// No string found
{% endif %}

View file

@ -0,0 +1,104 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if tables.count > 0 %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
import Foundation
// swiftlint:disable superfluous_disable_command file_length implicit_return
// MARK: - Strings
{% macro parametersBlock types %}{% filter removeNewlines:"leading" %}
{% for type in types %}
{% if type == "String" %}
_ p{{forloop.counter}}: Any
{% else %}
_ p{{forloop.counter}}: {{type}}
{% endif %}
{{ ", " if not forloop.last }}
{% endfor %}
{% endfilter %}{% endmacro %}
{% macro argumentsBlock types %}{% filter removeNewlines:"leading" %}
{% for type in types %}
{% if type == "String" %}
String(describing: p{{forloop.counter}})
{% elif type == "UnsafeRawPointer" %}
Int(bitPattern: p{{forloop.counter}})
{% else %}
p{{forloop.counter}}
{% endif %}
{{ ", " if not forloop.last }}
{% endfor %}
{% endfilter %}{% endmacro %}
{% macro recursiveBlock table item %}
{% for string in item.strings %}
{% if not param.noComments %}
{% for line in string.translation|split:"\n" %}
/// {{line}}
{% endfor %}
{% endif %}
{% if string.types %}
{{accessModifier}} static func {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}({% call parametersBlock string.types %}) -> String {
return {{enumName}}.tr("{{table}}", "{{string.key}}", {% call argumentsBlock string.types %})
}
{% elif param.lookupFunction %}
{# custom localization function is mostly used for in-app lang selection, so we want the loc to be recomputed at each call for those (hence the computed var) #}
{{accessModifier}} static var {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}: String { return {{enumName}}.tr("{{table}}", "{{string.key}}") }
{% else %}
{{accessModifier}} static let {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{enumName}}.tr("{{table}}", "{{string.key}}")
{% endif %}
{% endfor %}
{% for child in item.children %}
{{accessModifier}} enum {{child.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call recursiveBlock table child %}{% endfilter %}
}
{% endfor %}
{% endmacro %}
// swiftlint:disable explicit_type_interface function_parameter_count identifier_name line_length
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
{% set enumName %}{{param.enumName|default:"L10n"}}{% endset %}
{{accessModifier}} enum {{enumName}} {
{% if tables.count > 1 or param.forceFileNameEnum %}
{% for table in tables %}
{{accessModifier}} enum {{table.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call recursiveBlock table.name table.levels %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call recursiveBlock tables.first.name tables.first.levels %}
{% endif %}
}
// swiftlint:enable explicit_type_interface function_parameter_count identifier_name line_length
// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces
// MARK: - Implementation Details
extension {{enumName}} {
private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
{% if param.lookupFunction %}
let format = {{ param.lookupFunction }}(key, table)
{% else %}
let format = {{param.bundle|default:"BundleToken.bundle"}}.localizedString(forKey: key, value: nil, table: table)
{% endif %}
return String(format: format, locale: Locale.current, arguments: args)
}
}
{% if not param.bundle and not param.lookupFunction %}
// swiftlint:disable convenience_type
private final class BundleToken {
static let bundle: Bundle = {
#if SWIFT_PACKAGE
return Bundle.module
#else
return Bundle(for: BundleToken.self)
#endif
}()
}
// swiftlint:enable convenience_type
{% endif %}
{% else %}
// No string found
{% endif %}

View file

@ -0,0 +1,329 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if catalogs %}
{% set enumName %}{{param.enumName|default:"Asset"}}{% endset %}
{% set arResourceGroupType %}{{param.arResourceGroupTypeName|default:"ARResourceGroupAsset"}}{% endset %}
{% set colorType %}{{param.colorTypeName|default:"ColorAsset"}}{% endset %}
{% set dataType %}{{param.dataTypeName|default:"DataAsset"}}{% endset %}
{% set imageType %}{{param.imageTypeName|default:"ImageAsset"}}{% endset %}
{% set symbolType %}{{param.symbolTypeName|default:"SymbolAsset"}}{% endset %}
{% set forceNamespaces %}{{param.forceProvidesNamespaces|default:"false"}}{% endset %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
#if os(macOS)
import AppKit
#elseif os(iOS)
{% if resourceCount.arresourcegroup > 0 %}
import ARKit
{% endif %}
import UIKit
#elseif os(tvOS) || os(watchOS)
import UIKit
#endif
// Deprecated typealiases
{% if resourceCount.color > 0 %}
@available(*, deprecated, renamed: "{{colorType}}.Color", message: "This typealias will be removed in SwiftGen 7.0")
{{accessModifier}} typealias {{param.colorAliasName|default:"AssetColorTypeAlias"}} = {{colorType}}.Color
{% endif %}
{% if resourceCount.image > 0 %}
@available(*, deprecated, renamed: "{{imageType}}.Image", message: "This typealias will be removed in SwiftGen 7.0")
{{accessModifier}} typealias {{param.imageAliasName|default:"AssetImageTypeAlias"}} = {{imageType}}.Image
{% endif %}
// swiftlint:disable superfluous_disable_command file_length implicit_return
// MARK: - Asset Catalogs
{% macro enumBlock assets %}
{% call casesBlock assets %}
{% if param.allValues %}
// swiftlint:disable trailing_comma
{% if resourceCount.arresourcegroup > 0 %}
{{accessModifier}} static let allResourceGroups: [{{arResourceGroupType}}] = [
{% filter indent:2 %}{% call allValuesBlock assets "arresourcegroup" "" %}{% endfilter %}
]
{% endif %}
{% if resourceCount.color > 0 %}
{{accessModifier}} static let allColors: [{{colorType}}] = [
{% filter indent:2 %}{% call allValuesBlock assets "color" "" %}{% endfilter %}
]
{% endif %}
{% if resourceCount.data > 0 %}
{{accessModifier}} static let allDataAssets: [{{dataType}}] = [
{% filter indent:2 %}{% call allValuesBlock assets "data" "" %}{% endfilter %}
]
{% endif %}
{% if resourceCount.image > 0 %}
{{accessModifier}} static let allImages: [{{imageType}}] = [
{% filter indent:2 %}{% call allValuesBlock assets "image" "" %}{% endfilter %}
]
{% endif %}
{% if resourceCount.symbol > 0 %}
{{accessModifier}} static let allSymbols: [{{symbolType}}] = [
{% filter indent:2 %}{% call allValuesBlock assets "symbol" "" %}{% endfilter %}
]
{% endif %}
// swiftlint:enable trailing_comma
{% endif %}
{% endmacro %}
{% macro casesBlock assets %}
{% for asset in assets %}
{% if asset.type == "arresourcegroup" %}
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{arResourceGroupType}}(name: "{{asset.value}}")
{% elif asset.type == "color" %}
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{colorType}}(name: "{{asset.value}}")
{% elif asset.type == "data" %}
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{dataType}}(name: "{{asset.value}}")
{% elif asset.type == "image" %}
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{imageType}}(name: "{{asset.value}}")
{% elif asset.type == "symbol" %}
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{symbolType}}(name: "{{asset.value}}")
{% elif asset.items and ( forceNamespaces == "true" or asset.isNamespaced == "true" ) %}
{{accessModifier}} enum {{asset.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call casesBlock asset.items %}{% endfilter %}
}
{% elif asset.items %}
{% call casesBlock asset.items %}
{% endif %}
{% endfor %}
{% endmacro %}
{% macro allValuesBlock assets filter prefix %}
{% for asset in assets %}
{% if asset.type == filter %}
{{prefix}}{{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}},
{% elif asset.items and ( forceNamespaces == "true" or asset.isNamespaced == "true" ) %}
{% set prefix2 %}{{prefix}}{{asset.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}.{% endset %}
{% call allValuesBlock asset.items filter prefix2 %}
{% elif asset.items %}
{% call allValuesBlock asset.items filter prefix %}
{% endif %}
{% endfor %}
{% endmacro %}
// swiftlint:disable identifier_name line_length nesting type_body_length type_name
{{accessModifier}} enum {{enumName}} {
{% if catalogs.count > 1 or param.forceFileNameEnum %}
{% for catalog in catalogs %}
{{accessModifier}} enum {{catalog.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call enumBlock catalog.assets %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call enumBlock catalogs.first.assets %}
{% endif %}
}
// swiftlint:enable identifier_name line_length nesting type_body_length type_name
// MARK: - Implementation Details
{% if resourceCount.arresourcegroup > 0 %}
{{accessModifier}} struct {{arResourceGroupType}} {
{{accessModifier}} fileprivate(set) var name: String
#if os(iOS)
@available(iOS 11.3, *)
{{accessModifier}} var referenceImages: Set<ARReferenceImage> {
return ARReferenceImage.referenceImages(in: self)
}
@available(iOS 12.0, *)
{{accessModifier}} var referenceObjects: Set<ARReferenceObject> {
return ARReferenceObject.referenceObjects(in: self)
}
#endif
}
#if os(iOS)
@available(iOS 11.3, *)
{{accessModifier}} extension ARReferenceImage {
static func referenceImages(in asset: {{arResourceGroupType}}) -> Set<ARReferenceImage> {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
return referenceImages(inGroupNamed: asset.name, bundle: bundle) ?? Set()
}
}
@available(iOS 12.0, *)
{{accessModifier}} extension ARReferenceObject {
static func referenceObjects(in asset: {{arResourceGroupType}}) -> Set<ARReferenceObject> {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
return referenceObjects(inGroupNamed: asset.name, bundle: bundle) ?? Set()
}
}
#endif
{% endif %}
{% if resourceCount.color > 0 %}
{{accessModifier}} final class {{colorType}} {
{{accessModifier}} fileprivate(set) var name: String
#if os(macOS)
{{accessModifier}} typealias Color = NSColor
#elseif os(iOS) || os(tvOS) || os(watchOS)
{{accessModifier}} typealias Color = UIColor
#endif
@available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, *)
{{accessModifier}} private(set) lazy var color: Color = Color(asset: self)
#if os(iOS) || os(tvOS)
@available(iOS 11.0, tvOS 11.0, *)
{{accessModifier}} func color(compatibleWith traitCollection: UITraitCollection) -> Color {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
guard let color = Color(named: name, in: bundle, compatibleWith: traitCollection) else {
fatalError("Unable to load color asset named \(name).")
}
return color
}
#endif
fileprivate init(name: String) {
self.name = name
}
}
{{accessModifier}} extension {{colorType}}.Color {
@available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, *)
convenience init!(asset: {{colorType}}) {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
#if os(iOS) || os(tvOS)
self.init(named: asset.name, in: bundle, compatibleWith: nil)
#elseif os(macOS)
self.init(named: NSColor.Name(asset.name), bundle: bundle)
#elseif os(watchOS)
self.init(named: asset.name)
#endif
}
}
{% endif %}
{% if resourceCount.data > 0 %}
{{accessModifier}} struct {{dataType}} {
{{accessModifier}} fileprivate(set) var name: String
@available(iOS 9.0, tvOS 9.0, watchOS 6.0, macOS 10.11, *)
{{accessModifier}} var data: NSDataAsset {
return NSDataAsset(asset: self)
}
}
@available(iOS 9.0, tvOS 9.0, watchOS 6.0, macOS 10.11, *)
{{accessModifier}} extension NSDataAsset {
convenience init!(asset: {{dataType}}) {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
#if os(iOS) || os(tvOS) || os(watchOS)
self.init(name: asset.name, bundle: bundle)
#elseif os(macOS)
self.init(name: NSDataAsset.Name(asset.name), bundle: bundle)
#endif
}
}
{% endif %}
{% if resourceCount.image > 0 %}
{{accessModifier}} struct {{imageType}} {
{{accessModifier}} fileprivate(set) var name: String
#if os(macOS)
{{accessModifier}} typealias Image = NSImage
#elseif os(iOS) || os(tvOS) || os(watchOS)
{{accessModifier}} typealias Image = UIImage
#endif
@available(iOS 8.0, tvOS 9.0, watchOS 2.0, macOS 10.7, *)
{{accessModifier}} var image: Image {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
#if os(iOS) || os(tvOS)
let image = Image(named: name, in: bundle, compatibleWith: nil)
#elseif os(macOS)
let name = NSImage.Name(self.name)
let image = (bundle == .main) ? NSImage(named: name) : bundle.image(forResource: name)
#elseif os(watchOS)
let image = Image(named: name)
#endif
guard let result = image else {
fatalError("Unable to load image asset named \(name).")
}
return result
}
#if os(iOS) || os(tvOS)
@available(iOS 8.0, tvOS 9.0, *)
{{accessModifier}} func image(compatibleWith traitCollection: UITraitCollection) -> Image {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
guard let result = Image(named: name, in: bundle, compatibleWith: traitCollection) else {
fatalError("Unable to load image asset named \(name).")
}
return result
}
#endif
}
{{accessModifier}} extension {{imageType}}.Image {
@available(iOS 8.0, tvOS 9.0, watchOS 2.0, *)
@available(macOS, deprecated,
message: "This initializer is unsafe on macOS, please use the {{imageType}}.image property")
convenience init!(asset: {{imageType}}) {
#if os(iOS) || os(tvOS)
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
self.init(named: asset.name, in: bundle, compatibleWith: nil)
#elseif os(macOS)
self.init(named: NSImage.Name(asset.name))
#elseif os(watchOS)
self.init(named: asset.name)
#endif
}
}
{% endif %}
{% if resourceCount.symbol > 0 %}
{{accessModifier}} struct {{symbolType}} {
{{accessModifier}} fileprivate(set) var name: String
#if os(iOS) || os(tvOS) || os(watchOS)
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)
{{accessModifier}} typealias Configuration = UIImage.SymbolConfiguration
{{accessModifier}} typealias Image = UIImage
@available(iOS 12.0, tvOS 12.0, watchOS 5.0, *)
{{accessModifier}} var image: Image {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
#if os(iOS) || os(tvOS)
let image = Image(named: name, in: bundle, compatibleWith: nil)
#elseif os(watchOS)
let image = Image(named: name)
#endif
guard let result = image else {
fatalError("Unable to load symbol asset named \(name).")
}
return result
}
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)
{{accessModifier}} func image(with configuration: Configuration) -> Image {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
guard let result = Image(named: name, in: bundle, with: configuration) else {
fatalError("Unable to load symbol asset named \(name).")
}
return result
}
#endif
}
{% endif %}
{% if not param.bundle %}
// swiftlint:disable convenience_type
private final class BundleToken {
static let bundle: Bundle = {
#if SWIFT_PACKAGE
return Bundle.module
#else
return Bundle(for: BundleToken.self)
#endif
}()
}
// swiftlint:enable convenience_type
{% endif %}
{% else %}
// No assets found
{% endif %}

View file

@ -0,0 +1,337 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if catalogs %}
{% set enumName %}{{param.enumName|default:"Asset"}}{% endset %}
{% set arResourceGroupType %}{{param.arResourceGroupTypeName|default:"ARResourceGroupAsset"}}{% endset %}
{% set colorType %}{{param.colorTypeName|default:"ColorAsset"}}{% endset %}
{% set dataType %}{{param.dataTypeName|default:"DataAsset"}}{% endset %}
{% set imageType %}{{param.imageTypeName|default:"ImageAsset"}}{% endset %}
{% set symbolType %}{{param.symbolTypeName|default:"SymbolAsset"}}{% endset %}
{% set forceNamespaces %}{{param.forceProvidesNamespaces|default:"false"}}{% endset %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
#if os(macOS)
import AppKit
#elseif os(iOS)
{% if resourceCount.arresourcegroup > 0 %}
import ARKit
{% endif %}
import UIKit
#elseif os(tvOS) || os(watchOS)
import UIKit
#endif
// Deprecated typealiases
{% if resourceCount.color > 0 %}
@available(*, deprecated, renamed: "{{colorType}}.Color", message: "This typealias will be removed in SwiftGen 7.0")
{{accessModifier}} typealias {{param.colorAliasName|default:"AssetColorTypeAlias"}} = {{colorType}}.Color
{% endif %}
{% if resourceCount.image > 0 %}
@available(*, deprecated, renamed: "{{imageType}}.Image", message: "This typealias will be removed in SwiftGen 7.0")
{{accessModifier}} typealias {{param.imageAliasName|default:"AssetImageTypeAlias"}} = {{imageType}}.Image
{% endif %}
// swiftlint:disable superfluous_disable_command file_length implicit_return
// MARK: - Asset Catalogs
{% macro enumBlock assets %}
{% call casesBlock assets %}
{% if param.allValues %}
// swiftlint:disable trailing_comma
{% if resourceCount.arresourcegroup > 0 %}
{{accessModifier}} static let allResourceGroups: [{{arResourceGroupType}}] = [
{% filter indent:2 %}{% call allValuesBlock assets "arresourcegroup" "" %}{% endfilter %}
]
{% endif %}
{% if resourceCount.color > 0 %}
{{accessModifier}} static let allColors: [{{colorType}}] = [
{% filter indent:2 %}{% call allValuesBlock assets "color" "" %}{% endfilter %}
]
{% endif %}
{% if resourceCount.data > 0 %}
{{accessModifier}} static let allDataAssets: [{{dataType}}] = [
{% filter indent:2 %}{% call allValuesBlock assets "data" "" %}{% endfilter %}
]
{% endif %}
{% if resourceCount.image > 0 %}
{{accessModifier}} static let allImages: [{{imageType}}] = [
{% filter indent:2 %}{% call allValuesBlock assets "image" "" %}{% endfilter %}
]
{% endif %}
{% if resourceCount.symbol > 0 %}
{{accessModifier}} static let allSymbols: [{{symbolType}}] = [
{% filter indent:2 %}{% call allValuesBlock assets "symbol" "" %}{% endfilter %}
]
{% endif %}
// swiftlint:enable trailing_comma
{% endif %}
{% endmacro %}
{% macro casesBlock assets %}
{% for asset in assets %}
{% if asset.type == "arresourcegroup" %}
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{arResourceGroupType}}(name: "{{asset.value}}")
{% elif asset.type == "color" %}
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{colorType}}(name: "{{asset.value}}")
{% elif asset.type == "data" %}
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{dataType}}(name: "{{asset.value}}")
{% elif asset.type == "image" %}
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{imageType}}(name: "{{asset.value}}")
{% elif asset.type == "symbol" %}
{{accessModifier}} static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = {{symbolType}}(name: "{{asset.value}}")
{% elif asset.items and ( forceNamespaces == "true" or asset.isNamespaced == "true" ) %}
{{accessModifier}} enum {{asset.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call casesBlock asset.items %}{% endfilter %}
}
{% elif asset.items %}
{% call casesBlock asset.items %}
{% endif %}
{% endfor %}
{% endmacro %}
{% macro allValuesBlock assets filter prefix %}
{% for asset in assets %}
{% if asset.type == filter %}
{{prefix}}{{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}},
{% elif asset.items and ( forceNamespaces == "true" or asset.isNamespaced == "true" ) %}
{% set prefix2 %}{{prefix}}{{asset.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}.{% endset %}
{% call allValuesBlock asset.items filter prefix2 %}
{% elif asset.items %}
{% call allValuesBlock asset.items filter prefix %}
{% endif %}
{% endfor %}
{% endmacro %}
// swiftlint:disable identifier_name line_length nesting type_body_length type_name
{{accessModifier}} enum {{enumName}} {
{% if catalogs.count > 1 or param.forceFileNameEnum %}
{% for catalog in catalogs %}
{{accessModifier}} enum {{catalog.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call enumBlock catalog.assets %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call enumBlock catalogs.first.assets %}
{% endif %}
}
// swiftlint:enable identifier_name line_length nesting type_body_length type_name
// MARK: - Implementation Details
{% if resourceCount.arresourcegroup > 0 %}
{{accessModifier}} struct {{arResourceGroupType}} {
{{accessModifier}} fileprivate(set) var name: String
#if os(iOS)
@available(iOS 11.3, *)
{{accessModifier}} var referenceImages: Set<ARReferenceImage> {
return ARReferenceImage.referenceImages(in: self)
}
@available(iOS 12.0, *)
{{accessModifier}} var referenceObjects: Set<ARReferenceObject> {
return ARReferenceObject.referenceObjects(in: self)
}
#endif
}
#if os(iOS)
@available(iOS 11.3, *)
{{accessModifier}} extension ARReferenceImage {
static func referenceImages(in asset: {{arResourceGroupType}}) -> Set<ARReferenceImage> {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
return referenceImages(inGroupNamed: asset.name, bundle: bundle) ?? Set()
}
}
@available(iOS 12.0, *)
{{accessModifier}} extension ARReferenceObject {
static func referenceObjects(in asset: {{arResourceGroupType}}) -> Set<ARReferenceObject> {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
return referenceObjects(inGroupNamed: asset.name, bundle: bundle) ?? Set()
}
}
#endif
{% endif %}
{% if resourceCount.color > 0 %}
{{accessModifier}} final class {{colorType}} {
{{accessModifier}} fileprivate(set) var name: String
#if os(macOS)
{{accessModifier}} typealias Color = NSColor
#elseif os(iOS) || os(tvOS) || os(watchOS)
{{accessModifier}} typealias Color = UIColor
#endif
@available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, *)
{{accessModifier}} private(set) lazy var color: Color = {
guard let color = Color(asset: self) else {
fatalError("Unable to load color asset named \(name).")
}
return color
}()
#if os(iOS) || os(tvOS)
@available(iOS 11.0, tvOS 11.0, *)
{{accessModifier}} func color(compatibleWith traitCollection: UITraitCollection) -> Color {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
guard let color = Color(named: name, in: bundle, compatibleWith: traitCollection) else {
fatalError("Unable to load color asset named \(name).")
}
return color
}
#endif
fileprivate init(name: String) {
self.name = name
}
}
{{accessModifier}} extension {{colorType}}.Color {
@available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, *)
convenience init?(asset: {{colorType}}) {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
#if os(iOS) || os(tvOS)
self.init(named: asset.name, in: bundle, compatibleWith: nil)
#elseif os(macOS)
self.init(named: NSColor.Name(asset.name), bundle: bundle)
#elseif os(watchOS)
self.init(named: asset.name)
#endif
}
}
{% endif %}
{% if resourceCount.data > 0 %}
{{accessModifier}} struct {{dataType}} {
{{accessModifier}} fileprivate(set) var name: String
@available(iOS 9.0, tvOS 9.0, watchOS 6.0, macOS 10.11, *)
{{accessModifier}} var data: NSDataAsset {
guard let data = NSDataAsset(asset: self) else {
fatalError("Unable to load data asset named \(name).")
}
return data
}
}
@available(iOS 9.0, tvOS 9.0, watchOS 6.0, macOS 10.11, *)
{{accessModifier}} extension NSDataAsset {
convenience init?(asset: {{dataType}}) {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
#if os(iOS) || os(tvOS) || os(watchOS)
self.init(name: asset.name, bundle: bundle)
#elseif os(macOS)
self.init(name: NSDataAsset.Name(asset.name), bundle: bundle)
#endif
}
}
{% endif %}
{% if resourceCount.image > 0 %}
{{accessModifier}} struct {{imageType}} {
{{accessModifier}} fileprivate(set) var name: String
#if os(macOS)
{{accessModifier}} typealias Image = NSImage
#elseif os(iOS) || os(tvOS) || os(watchOS)
{{accessModifier}} typealias Image = UIImage
#endif
@available(iOS 8.0, tvOS 9.0, watchOS 2.0, macOS 10.7, *)
{{accessModifier}} var image: Image {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
#if os(iOS) || os(tvOS)
let image = Image(named: name, in: bundle, compatibleWith: nil)
#elseif os(macOS)
let name = NSImage.Name(self.name)
let image = (bundle == .main) ? NSImage(named: name) : bundle.image(forResource: name)
#elseif os(watchOS)
let image = Image(named: name)
#endif
guard let result = image else {
fatalError("Unable to load image asset named \(name).")
}
return result
}
#if os(iOS) || os(tvOS)
@available(iOS 8.0, tvOS 9.0, *)
{{accessModifier}} func image(compatibleWith traitCollection: UITraitCollection) -> Image {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
guard let result = Image(named: name, in: bundle, compatibleWith: traitCollection) else {
fatalError("Unable to load image asset named \(name).")
}
return result
}
#endif
}
{{accessModifier}} extension {{imageType}}.Image {
@available(iOS 8.0, tvOS 9.0, watchOS 2.0, *)
@available(macOS, deprecated,
message: "This initializer is unsafe on macOS, please use the {{imageType}}.image property")
convenience init?(asset: {{imageType}}) {
#if os(iOS) || os(tvOS)
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
self.init(named: asset.name, in: bundle, compatibleWith: nil)
#elseif os(macOS)
self.init(named: NSImage.Name(asset.name))
#elseif os(watchOS)
self.init(named: asset.name)
#endif
}
}
{% endif %}
{% if resourceCount.symbol > 0 %}
{{accessModifier}} struct {{symbolType}} {
{{accessModifier}} fileprivate(set) var name: String
#if os(iOS) || os(tvOS) || os(watchOS)
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)
{{accessModifier}} typealias Configuration = UIImage.SymbolConfiguration
{{accessModifier}} typealias Image = UIImage
@available(iOS 12.0, tvOS 12.0, watchOS 5.0, *)
{{accessModifier}} var image: Image {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
#if os(iOS) || os(tvOS)
let image = Image(named: name, in: bundle, compatibleWith: nil)
#elseif os(watchOS)
let image = Image(named: name)
#endif
guard let result = image else {
fatalError("Unable to load symbol asset named \(name).")
}
return result
}
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)
{{accessModifier}} func image(with configuration: Configuration) -> Image {
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
guard let result = Image(named: name, in: bundle, with: configuration) else {
fatalError("Unable to load symbol asset named \(name).")
}
return result
}
#endif
}
{% endif %}
{% if not param.bundle %}
// swiftlint:disable convenience_type
private final class BundleToken {
static let bundle: Bundle = {
#if SWIFT_PACKAGE
return Bundle.module
#else
return Bundle(for: BundleToken.self)
#endif
}()
}
// swiftlint:enable convenience_type
{% endif %}
{% else %}
// No assets found
{% endif %}

View file

@ -0,0 +1,92 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if files %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
{% set documentPrefix %}{{param.documentName|default:"Document"}}{% endset %}
import Foundation
// swiftlint:disable superfluous_disable_command
// swiftlint:disable file_length
// MARK: - YAML Files
{% macro fileBlock file %}
{% if file.documents.count > 1 %}
{% for document in file.documents %}
{% set documentName %}{{documentPrefix}}{{forloop.counter}}{% endset %}
{{accessModifier}} enum {{documentName|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call documentBlock file document %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call documentBlock file file.documents.first %}
{% endif %}
{% endmacro %}
{% macro documentBlock file document %}
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
{% if document.metadata.type == "Array" %}
{{accessModifier}} static let items: {{rootType}} = {% call valueBlock document.data document.metadata %}
{% elif document.metadata.type == "Dictionary" %}
{% for key,value in document.metadata.properties %}
{{accessModifier}} {% call propertyBlock key value document.data %}
{% endfor %}
{% else %}
{{accessModifier}} static let value: {{rootType}} = {% call valueBlock document.data document.metadata %}
{% endif %}
{% endmacro %}
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
{% if metadata.type == "Array" %}
[{% call typeBlock metadata.element %}]
{% elif metadata.type == "Dictionary" %}
[String: Any]
{% elif metadata.type == "Optional" %}
Any?
{% else %}
{{metadata.type}}
{% endif %}
{% endfilter %}{% endmacro %}
{% macro propertyBlock key metadata data %}{% filter removeNewlines:"leading" %}
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
static let {{propertyName}}: {{propertyType}} = {% call valueBlock data[key] metadata %}
{% endfilter %}{% endmacro %}
{% macro valueBlock value metadata %}{% filter removeNewlines:"leading" %}
{% if metadata.type == "String" %}
"{{ value }}"
{% elif metadata.type == "Optional" %}
nil
{% elif metadata.type == "Array" and value %}
[{% for value in value %}
{% call valueBlock value metadata.element.items[forloop.counter0]|default:metadata.element %}
{{ ", " if not forloop.last }}
{% endfor %}]
{% elif metadata.type == "Dictionary" %}
[{% for key,value in value %}
"{{key}}": {% call valueBlock value metadata.properties[key] %}
{{ ", " if not forloop.last }}
{% empty %}
:
{% endfor %}]
{% elif metadata.type == "Bool" %}
{% if value %}true{% else %}false{% endif %}
{% else %}
{{ value }}
{% endif %}
{% endfilter %}{% endmacro %}
// swiftlint:disable identifier_name line_length number_separator type_body_length
{{accessModifier}} enum {{param.enumName|default:"YAMLFiles"}} {
{% if files.count > 1 or param.forceFileNameEnum %}
{% for file in files %}
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call fileBlock files.first %}
{% endif %}
}
// swiftlint:enable identifier_name line_length number_separator type_body_length
{% else %}
// No files found
{% endif %}

View file

@ -0,0 +1,92 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if files %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
{% set documentPrefix %}{{param.documentName|default:"Document"}}{% endset %}
import Foundation
// swiftlint:disable superfluous_disable_command
// swiftlint:disable file_length
// MARK: - YAML Files
{% macro fileBlock file %}
{% if file.documents.count > 1 %}
{% for document in file.documents %}
{% set documentName %}{{documentPrefix}}{{forloop.counter}}{% endset %}
{{accessModifier}} enum {{documentName|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call documentBlock file document %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call documentBlock file file.documents.first %}
{% endif %}
{% endmacro %}
{% macro documentBlock file document %}
{% set rootType %}{% call typeBlock document.metadata %}{% endset %}
{% if document.metadata.type == "Array" %}
{{accessModifier}} static let items: {{rootType}} = {% call valueBlock document.data document.metadata %}
{% elif document.metadata.type == "Dictionary" %}
{% for key,value in document.metadata.properties %}
{{accessModifier}} {% call propertyBlock key value document.data %}
{% endfor %}
{% else %}
{{accessModifier}} static let value: {{rootType}} = {% call valueBlock document.data document.metadata %}
{% endif %}
{% endmacro %}
{% macro typeBlock metadata %}{% filter removeNewlines:"leading" %}
{% if metadata.type == "Array" %}
[{% call typeBlock metadata.element %}]
{% elif metadata.type == "Dictionary" %}
[String: Any]
{% elif metadata.type == "Optional" %}
Any?
{% else %}
{{metadata.type}}
{% endif %}
{% endfilter %}{% endmacro %}
{% macro propertyBlock key metadata data %}{% filter removeNewlines:"leading" %}
{% set propertyName %}{{key|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
{% set propertyType %}{% call typeBlock metadata %}{% endset %}
static let {{propertyName}}: {{propertyType}} = {% call valueBlock data[key] metadata %}
{% endfilter %}{% endmacro %}
{% macro valueBlock value metadata %}{% filter removeNewlines:"leading" %}
{% if metadata.type == "String" %}
"{{ value }}"
{% elif metadata.type == "Optional" %}
nil
{% elif metadata.type == "Array" and value %}
[{% for value in value %}
{% call valueBlock value metadata.element.items[forloop.counter0]|default:metadata.element %}
{{ ", " if not forloop.last }}
{% endfor %}]
{% elif metadata.type == "Dictionary" %}
[{% for key,value in value %}
"{{key}}": {% call valueBlock value metadata.properties[key] %}
{{ ", " if not forloop.last }}
{% empty %}
:
{% endfor %}]
{% elif metadata.type == "Bool" %}
{% if value %}true{% else %}false{% endif %}
{% else %}
{{ value }}
{% endif %}
{% endfilter %}{% endmacro %}
// swiftlint:disable identifier_name line_length number_separator type_body_length
{{accessModifier}} enum {{param.enumName|default:"YAMLFiles"}} {
{% if files.count > 1 or param.forceFileNameEnum %}
{% for file in files %}
{{accessModifier}} enum {{file.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call fileBlock files.first %}
{% endif %}
}
// swiftlint:enable identifier_name line_length number_separator type_body_length
{% else %}
// No files found
{% endif %}

BIN
.swiftgen/bin/swiftgen Executable file

Binary file not shown.

View file

@ -0,0 +1,29 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if families %}
import SwiftUI
{% for family in families %}
{% set identifierName %}{{family.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}{% endset %}
{% set styleTypeName %}{{family.name|swiftIdentifier:"pretty"|escapeReservedKeywords}}Style{% endset %}
extension Font {
public static func {{identifierName}}(_ style: {{styleTypeName}}, fixedSize: CGFloat) -> Font {
return Font.custom(style.rawValue, fixedSize: fixedSize)
}
public static func {{identifierName}}(_ style: {{styleTypeName}}, size: CGFloat, relativeTo textStyle: TextStyle = .body) -> Font {
return Font.custom(style.rawValue, size: size, relativeTo: textStyle)
}
public enum {{styleTypeName}}: String {
{% for font in family.fonts %}
case {{font.style|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = "{{font.name}}"
{% endfor %}
}
}
{% endfor %}
{% else %}
// No fonts found
{% endif %}

View file

@ -0,0 +1,84 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if tables.count > 0 %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
import Foundation
// swiftlint:disable superfluous_disable_command file_length implicit_return
// MARK: - Strings
{% macro parametersBlock types %}{% filter removeNewlines:"leading" %}
{% for type in types %}
{% if type == "String" %}
_ p{{forloop.counter}}: Any
{% else %}
_ p{{forloop.counter}}: {{type}}
{% endif %}
{{ ", " if not forloop.last }}
{% endfor %}
{% endfilter %}{% endmacro %}
{% macro argumentsBlock types %}{% filter removeNewlines:"leading" %}
{% for type in types %}
{% if type == "String" %}
String(describing: p{{forloop.counter}})
{% elif type == "UnsafeRawPointer" %}
Int(bitPattern: p{{forloop.counter}})
{% else %}
p{{forloop.counter}}
{% endif %}
{{ ", " if not forloop.last }}
{% endfor %}
{% endfilter %}{% endmacro %}
{% macro recursiveBlock table item %}
{% for string in item.strings %}
{% if not param.noComments %}
{% for line in string.translation|split:"\n" %}
/// {{line}}
{% endfor %}
{% endif %}
{% if string.types %}
{{accessModifier}} static func {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}({% call parametersBlock string.types %}) -> String {
{{enumName}}.tr("{{table}}", "{{string.key}}", {% call argumentsBlock string.types %})
}
{% else %}
{{accessModifier}} static var {{string.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}}: String { {{enumName}}.tr("{{table}}", "{{string.key}}") }
{% endif %}
{% endfor %}
{% for child in item.children %}
{{accessModifier}} enum {{child.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call recursiveBlock table child %}{% endfilter %}
}
{% endfor %}
{% endmacro %}
// swiftlint:disable explicit_type_interface function_parameter_count identifier_name line_length
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
{% set enumName %}{{param.enumName|default:"L10n"}}{% endset %}
{{accessModifier}} enum {{enumName}} {
{% if tables.count > 1 or param.forceFileNameEnum %}
{% for table in tables %}
{{accessModifier}} enum {{table.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call recursiveBlock table.name table.levels %}{% endfilter %}
}
{% endfor %}
{% else %}
{% call recursiveBlock tables.first.name tables.first.levels %}
{% endif %}
}
// swiftlint:enable explicit_type_interface function_parameter_count identifier_name line_length
// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces
// MARK: - Implementation Details
import Localize_Swift
extension {{enumName}} {
static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
let selectedLanguage = Localize.currentLanguage()
guard let path = Bundle.main.path(forResource: selectedLanguage, ofType: "lproj"),
let bundle = Bundle(path: path) else { return "Setup language error" }
return NSLocalizedString(key, tableName: table, bundle: bundle, comment: "")
}
}
{% endif %}

View file

@ -0,0 +1,47 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if catalogs %}
import SwiftUI
{% macro casesBlock assets %}
{% for asset in assets %}
{% if asset.items and asset.isNamespaced == "true" %}
public enum {{asset.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call casesBlock asset.items %}{% endfilter %}
}
{% elif asset.items %}
{% call casesBlock asset.items %}
{% elif asset.type == "color" %}
public static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = Color("{{asset.value}}")
{% elif asset.type == "image" %}
public static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = Image("{{asset.value}}")
{% endif %}
{% endfor %}
{% endmacro %}
{% for catalog in catalogs %}
{% if catalog.name == "Colors" %}
extension Color {
{% for catalog in catalogs %}
{% if catalog.name == "Colors" %}
{% call casesBlock catalog.assets %}
{% endif %}
{% endfor %}
}
{% endif %}
{% endfor %}
{% for catalog in catalogs %}
{% if catalog.name == "Images" %}
extension Image {
{% for catalog in catalogs %}
{% if catalog.name == "Images" %}
{% call casesBlock catalog.assets %}
{% endif %}
{% endfor %}
}
{% endif %}
{% endfor %}
{% else %}
// No assets found
{% endif %}

View file

@ -0,0 +1,35 @@
// swiftlint:disable all
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if catalogs %}
import Foundation
typealias AssetStrings = String
{% macro casesBlock assets %}
{% for asset in assets %}
{% if asset.items and asset.isNamespaced == "true" %}
public enum {{asset.name|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call casesBlock asset.items %}{% endfilter %}
}
{% elif asset.items %}
{% call casesBlock asset.items %}
{% elif asset.type == "image" %}
public static let {{asset.name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = String("{{asset.value}}")
{% endif %}
{% endfor %}
{% endmacro %}
{% for catalog in catalogs %}
{% if catalog.name == "Images" %}
extension String {
{% for catalog in catalogs %}
{% if catalog.name == "Images" %}
{% call casesBlock catalog.assets %}
{% endif %}
{% endfor %}
}
{% endif %}
{% endfor %}
{% else %}
// No assets found
{% endif %}

118
.swiftlint.yml Normal file
View file

@ -0,0 +1,118 @@
---
colon:
severity: error
line_length:
ignores_comments: true
warning: 260
error: 300
type_body_length:
warning: 300
error: 500
file_length:
warning: 800
error: 1000
function_parameter_count:
warning: 20
error: 30
function_body_length:
warning: 120
error: 150
cyclomatic_complexity:
warning: 40
error: 50
nesting:
type_level:
warning: 3
error: 6
function_level:
warning: 5
error: 10
vertical_parameter_alignment:
severity: warning
implicitly_unwrapped_optional:
severity: warning
force_unwrapping:
severity: error
vertical_whitespace:
severity: error
force_try:
severity: error
trailing_semicolon:
severity: error
type_name:
min_length: 3
max_length: 60
error: 80
identifier_name:
min_length: 3
max_length: 60
validates_start_with_lowercase: true
allowed_symbols: "_"
excluded:
- iv
- id
- ip
- on
- ui
- x
- y
- tz
- to
- db
# Disable rules from the default enabled set.
disabled_rules:
- trailing_whitespace
- implicit_getter
- redundant_string_enum_value
- switch_case_alignment
# Enable rules not from the default set.
opt_in_rules:
# - function_default_parameter_at_end
- empty_count
- indentation_width
# - index_at_zero
- legacy_constant
# - implicitly_unwrapped_optional
- force_unwrapping
# - no header
- file_header
# - for force unwrapping
- implicitly_unwrapped_optional
- vertical_parameter_alignment_on_call
- vertical_whitespace_between_cases
- vertical_whitespace_closing_braces
- vertical_whitespace_opening_braces
# Acts as a whitelist, only the rules specified in this list will be enabled. Can not be specified alongside disabled_rules or opt_in_rules.
only_rules:
# This is an entirely separate list of rules that are only run by the analyze command. All analyzer rules are opt-in, so this is the only configurable rule list (there is no disabled/whitelist equivalent).
analyzer_rules:
- unused_import
- unused_declaration
unused_declaration:
include_public_and_open: true
# paths to ignore during linting. Takes precedence over `included`.
excluded:
- Snikket/Generated
- old
- Packages/*/.build

674
COPYING
View file

@ -1,674 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

View file

@ -1 +0,0 @@

View file

@ -0,0 +1,68 @@
<?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>AvailableLibraries</key>
<array>
<dict>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>WebRTC.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
</dict>
<dict>
<key>LibraryIdentifier</key>
<string>ios-x86_64_arm64-simulator</string>
<key>LibraryPath</key>
<string>WebRTC.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
<dict>
<key>LibraryIdentifier</key>
<string>macos-x86_64_arm64</string>
<key>LibraryPath</key>
<string>WebRTC.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>x86_64</string>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>macos</string>
</dict>
<dict>
<key>LibraryIdentifier</key>
<string>ios-x86_64_arm64-maccatalyst</string>
<key>LibraryPath</key>
<string>WebRTC.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>x86_64</string>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>maccatalyst</string>
</dict>
</array>
<key>CFBundlePackageType</key>
<string>XFWK</string>
<key>XCFrameworkFormatVersion</key>
<string>1.0</string>
</dict>
</plist>

View file

@ -0,0 +1,29 @@
Copyright (c) 2011, The WebRTC project authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Google nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,308 @@
/*
* Copyright 2022 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <AudioUnit/AudioUnit.h>
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
typedef OSStatus (^RTC_OBJC_TYPE(RTCAudioDeviceGetPlayoutDataBlock))(
AudioUnitRenderActionFlags *_Nonnull actionFlags,
const AudioTimeStamp *_Nonnull timestamp,
NSInteger inputBusNumber,
UInt32 frameCount,
AudioBufferList *_Nonnull outputData);
typedef OSStatus (^RTC_OBJC_TYPE(RTCAudioDeviceRenderRecordedDataBlock))(
AudioUnitRenderActionFlags *_Nonnull actionFlags,
const AudioTimeStamp *_Nonnull timestamp,
NSInteger inputBusNumber,
UInt32 frameCount,
AudioBufferList *_Nonnull inputData,
void *_Nullable renderContext);
typedef OSStatus (^RTC_OBJC_TYPE(RTCAudioDeviceDeliverRecordedDataBlock))(
AudioUnitRenderActionFlags *_Nonnull actionFlags,
const AudioTimeStamp *_Nonnull timestamp,
NSInteger inputBusNumber,
UInt32 frameCount,
const AudioBufferList *_Nullable inputData,
void *_Nullable renderContext,
NS_NOESCAPE RTC_OBJC_TYPE(RTCAudioDeviceRenderRecordedDataBlock) _Nullable renderBlock);
/**
* Delegate object provided by native ADM during RTCAudioDevice initialization.
* Provides blocks to poll playback audio samples from native ADM and to feed
* recorded audio samples into native ADM.
*/
RTC_OBJC_EXPORT @protocol RTC_OBJC_TYPE
(RTCAudioDeviceDelegate)<NSObject>
/**
* Implementation of RTCAudioSource should call this block to feed recorded PCM (16-bit integer)
* into native ADM. Stereo data is expected to be interleaved starting with the left channel.
* Either `inputData` with pre-filled audio data must be provided during block
* call or `renderBlock` must be provided which must fill provided audio buffer with recorded
* samples.
*
* NOTE: Implementation of RTCAudioDevice is expected to call the block on the same thread until
* `notifyAudioInterrupted` is called. When `notifyAudioInterrupted` is called implementation
* can call the block on a different thread.
*/
@property(readonly, nonnull)
RTC_OBJC_TYPE(RTCAudioDeviceDeliverRecordedDataBlock) deliverRecordedData;
/**
* Provides input sample rate preference as it preferred by native ADM.
*/
@property(readonly) double preferredInputSampleRate;
/**
* Provides input IO buffer duration preference as it preferred by native ADM.
*/
@property(readonly) NSTimeInterval preferredInputIOBufferDuration;
/**
* Provides output sample rate preference as it preferred by native ADM.
*/
@property(readonly) double preferredOutputSampleRate;
/**
* Provides output IO buffer duration preference as it preferred by native ADM.
*/
@property(readonly) NSTimeInterval preferredOutputIOBufferDuration;
/**
* Implementation of RTCAudioDevice should call this block to request PCM (16-bit integer)
* from native ADM to play. Stereo data is interleaved starting with the left channel.
*
* NOTE: Implementation of RTCAudioDevice is expected to invoke of this block on the
* same thread until `notifyAudioInterrupted` is called. When `notifyAudioInterrupted` is called
* implementation can call the block from a different thread.
*/
@property(readonly, nonnull) RTC_OBJC_TYPE(RTCAudioDeviceGetPlayoutDataBlock) getPlayoutData;
/**
* Notifies native ADM that some of the audio input parameters of RTCAudioDevice like
* samle rate and/or IO buffer duration and/or IO latency had possibly changed.
* Native ADM will adjust its audio input buffer to match current parameters of audio device.
*
* NOTE: Must be called within block executed via `dispatchAsync` or `dispatchSync`.
*/
- (void)notifyAudioInputParametersChange;
/**
* Notifies native ADM that some of the audio output parameters of RTCAudioDevice like
* samle rate and/or IO buffer duration and/or IO latency had possibly changed.
* Native ADM will adjust its audio output buffer to match current parameters of audio device.
*
* NOTE: Must be called within block executed via `dispatchAsync` or `dispatchSync`.
*/
- (void)notifyAudioOutputParametersChange;
/**
* Notifies native ADM that audio input is interrupted and further audio playout
* and recording might happen on a different thread.
*
* NOTE: Must be called within block executed via `dispatchAsync` or `dispatchSync`.
*/
- (void)notifyAudioInputInterrupted;
/**
* Notifies native ADM that audio output is interrupted and further audio playout
* and recording might happen on a different thread.
*
* NOTE: Must be called within block executed via `dispatchAsync` or `dispatchSync`.
*/
- (void)notifyAudioOutputInterrupted;
/**
* Asynchronously execute block of code within the context of
* thread which owns native ADM.
*
* NOTE: Intended to be used to invoke `notifyAudioInputParametersChange`,
* `notifyAudioOutputParametersChange`, `notifyAudioInputInterrupted`,
* `notifyAudioOutputInterrupted` on native ADM thread.
* Also could be used by `RTCAudioDevice` implementation to tie
* mutations of underlying audio objects (AVAudioEngine, AudioUnit, etc)
* to the native ADM thread. Could be useful to handle events like audio route change, which
* could lead to audio parameters change.
*/
- (void)dispatchAsync:(dispatch_block_t)block;
/**
* Synchronously execute block of code within the context of
* thread which owns native ADM. Allows reentrancy.
*
* NOTE: Intended to be used to invoke `notifyAudioInputParametersChange`,
* `notifyAudioOutputParametersChange`, `notifyAudioInputInterrupted`,
* `notifyAudioOutputInterrupted` on native ADM thread and make sure
* aforementioned is completed before `dispatchSync` returns. Could be useful
* when implementation of `RTCAudioDevice` tie mutation to underlying audio objects (AVAudioEngine,
* AudioUnit, etc) to own thread to satisfy requirement that native ADM audio parameters
* must be kept in sync with current audio parameters before audio is actually played or recorded.
*/
- (void)dispatchSync:(dispatch_block_t)block;
@end
/**
* Protocol to abstract platform specific ways to implement playback and recording.
*
* NOTE: All the members of protocol are called by native ADM from the same thread
* between calls to `initializeWithDelegate` and `terminate`.
* NOTE: Implementation is fully responsible for configuring application's AVAudioSession.
* An example implementation of RTCAudioDevice: https://github.com/mstyura/RTCAudioDevice
* TODO(yura.yaroshevich): Implement custom RTCAudioDevice for AppRTCMobile demo app.
*/
RTC_OBJC_EXPORT @protocol RTC_OBJC_TYPE
(RTCAudioDevice)<NSObject>
/**
* Indicates current sample rate of audio recording. Changes to this property
* must be notified back to native ADM via `-[RTCAudioDeviceDelegate
* notifyAudioParametersChange]`.
*/
@property(readonly) double deviceInputSampleRate;
/**
* Indicates current size of record buffer. Changes to this property
* must be notified back to native ADM via `-[RTCAudioDeviceDelegate notifyAudioParametersChange]`.
*/
@property(readonly) NSTimeInterval inputIOBufferDuration;
/**
* Indicates current number of recorded audio channels. Changes to this property
* must be notified back to native ADM via `-[RTCAudioDeviceDelegate notifyAudioParametersChange]`.
*/
@property(readonly) NSInteger inputNumberOfChannels;
/**
* Indicates current input latency
*/
@property(readonly) NSTimeInterval inputLatency;
/**
* Indicates current sample rate of audio playback. Changes to this property
* must be notified back to native ADM via `-[RTCAudioDeviceDelegate notifyAudioParametersChange]`.
*/
@property(readonly) double deviceOutputSampleRate;
/**
* Indicates current size of playback buffer. Changes to this property
* must be notified back to native ADM via `-[RTCAudioDeviceDelegate notifyAudioParametersChange]`.
*/
@property(readonly) NSTimeInterval outputIOBufferDuration;
/**
* Indicates current number of playback audio channels. Changes to this property
* must be notified back to WebRTC via `[RTCAudioDeviceDelegate notifyAudioParametersChange]`.
*/
@property(readonly) NSInteger outputNumberOfChannels;
/**
* Indicates current output latency
*/
@property(readonly) NSTimeInterval outputLatency;
/**
* Indicates if invocation of `initializeWithDelegate` required before usage of RTCAudioDevice.
* YES indicates that `initializeWithDelegate` was called earlier without subsequent call to
* `terminate`. NO indicates that either `initializeWithDelegate` not called or `terminate` called.
*/
@property(readonly) BOOL isInitialized;
/**
* Initializes RTCAudioDevice with RTCAudioDeviceDelegate.
* Implementation must return YES if RTCAudioDevice initialized successfully and NO otherwise.
*/
- (BOOL)initializeWithDelegate:(id<RTC_OBJC_TYPE(RTCAudioDeviceDelegate)>)delegate;
/**
* De-initializes RTCAudioDevice. Implementation should forget about `delegate` provided in
* `initializeWithDelegate`.
*/
- (BOOL)terminateDevice;
/**
* Property to indicate if `initializePlayout` call required before invocation of `startPlayout`.
* YES indicates that `initializePlayout` was successfully invoked earlier or not necessary,
* NO indicates that `initializePlayout` invocation required.
*/
@property(readonly) BOOL isPlayoutInitialized;
/**
* Prepares RTCAudioDevice to play audio.
* Called by native ADM before invocation of `startPlayout`.
* Implementation is expected to return YES in case of successful playout initialization and NO
* otherwise.
*/
- (BOOL)initializePlayout;
/**
* Property to indicate if RTCAudioDevice should be playing according to
* earlier calls of `startPlayout` and `stopPlayout`.
*/
@property(readonly) BOOL isPlaying;
/**
* Method is called when native ADM wants to play audio.
* Implementation is expected to return YES if playback start request
* successfully handled and NO otherwise.
*/
- (BOOL)startPlayout;
/**
* Method is called when native ADM no longer needs to play audio.
* Implementation is expected to return YES if playback stop request
* successfully handled and NO otherwise.
*/
- (BOOL)stopPlayout;
/**
* Property to indicate if `initializeRecording` call required before usage of `startRecording`.
* YES indicates that `initializeRecording` was successfully invoked earlier or not necessary,
* NO indicates that `initializeRecording` invocation required.
*/
@property(readonly) BOOL isRecordingInitialized;
/**
* Prepares RTCAudioDevice to record audio.
* Called by native ADM before invocation of `startRecording`.
* Implementation may use this method to prepare resources required to record audio.
* Implementation is expected to return YES in case of successful record initialization and NO
* otherwise.
*/
- (BOOL)initializeRecording;
/**
* Property to indicate if RTCAudioDevice should record audio according to
* earlier calls to `startRecording` and `stopRecording`.
*/
@property(readonly) BOOL isRecording;
/**
* Method is called when native ADM wants to record audio.
* Implementation is expected to return YES if recording start request
* successfully handled and NO otherwise.
*/
- (BOOL)startRecording;
/**
* Method is called when native ADM no longer needs to record audio.
* Implementation is expected to return YES if recording stop request
* successfully handled and NO otherwise.
*/
- (BOOL)stopRecording;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,269 @@
/*
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <AVFoundation/AVFoundation.h>
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
extern NSString *const kRTCAudioSessionErrorDomain;
/** Method that requires lock was called without lock. */
extern NSInteger const kRTCAudioSessionErrorLockRequired;
/** Unknown configuration error occurred. */
extern NSInteger const kRTCAudioSessionErrorConfiguration;
@class RTC_OBJC_TYPE(RTCAudioSession);
@class RTC_OBJC_TYPE(RTCAudioSessionConfiguration);
// Surfaces AVAudioSession events. WebRTC will listen directly for notifications
// from AVAudioSession and handle them before calling these delegate methods,
// at which point applications can perform additional processing if required.
RTC_OBJC_EXPORT
@protocol RTC_OBJC_TYPE
(RTCAudioSessionDelegate)<NSObject>
@optional
/** Called on a system notification thread when AVAudioSession starts an
* interruption event.
*/
- (void)audioSessionDidBeginInterruption:(RTC_OBJC_TYPE(RTCAudioSession) *)session;
/** Called on a system notification thread when AVAudioSession ends an
* interruption event.
*/
- (void)audioSessionDidEndInterruption:(RTC_OBJC_TYPE(RTCAudioSession) *)session
shouldResumeSession:(BOOL)shouldResumeSession;
/** Called on a system notification thread when AVAudioSession changes the
* route.
*/
- (void)audioSessionDidChangeRoute:(RTC_OBJC_TYPE(RTCAudioSession) *)session
reason:(AVAudioSessionRouteChangeReason)reason
previousRoute:(AVAudioSessionRouteDescription *)previousRoute;
/** Called on a system notification thread when AVAudioSession media server
* terminates.
*/
- (void)audioSessionMediaServerTerminated:(RTC_OBJC_TYPE(RTCAudioSession) *)session;
/** Called on a system notification thread when AVAudioSession media server
* restarts.
*/
- (void)audioSessionMediaServerReset:(RTC_OBJC_TYPE(RTCAudioSession) *)session;
// TODO(tkchin): Maybe handle SilenceSecondaryAudioHintNotification.
- (void)audioSession:(RTC_OBJC_TYPE(RTCAudioSession) *)session
didChangeCanPlayOrRecord:(BOOL)canPlayOrRecord;
/** Called on a WebRTC thread when the audio device is notified to begin
* playback or recording.
*/
- (void)audioSessionDidStartPlayOrRecord:(RTC_OBJC_TYPE(RTCAudioSession) *)session;
/** Called on a WebRTC thread when the audio device is notified to stop
* playback or recording.
*/
- (void)audioSessionDidStopPlayOrRecord:(RTC_OBJC_TYPE(RTCAudioSession) *)session;
/** Called when the AVAudioSession output volume value changes. */
- (void)audioSession:(RTC_OBJC_TYPE(RTCAudioSession) *)audioSession
didChangeOutputVolume:(float)outputVolume;
/** Called when the audio device detects a playout glitch. The argument is the
* number of glitches detected so far in the current audio playout session.
*/
- (void)audioSession:(RTC_OBJC_TYPE(RTCAudioSession) *)audioSession
didDetectPlayoutGlitch:(int64_t)totalNumberOfGlitches;
/** Called when the audio session is about to change the active state.
*/
- (void)audioSession:(RTC_OBJC_TYPE(RTCAudioSession) *)audioSession willSetActive:(BOOL)active;
/** Called after the audio session sucessfully changed the active state.
*/
- (void)audioSession:(RTC_OBJC_TYPE(RTCAudioSession) *)audioSession didSetActive:(BOOL)active;
/** Called after the audio session failed to change the active state.
*/
- (void)audioSession:(RTC_OBJC_TYPE(RTCAudioSession) *)audioSession
failedToSetActive:(BOOL)active
error:(NSError *)error;
- (void)audioSession:(RTC_OBJC_TYPE(RTCAudioSession) *)audioSession
audioUnitStartFailedWithError:(NSError *)error;
@end
/** This is a protocol used to inform RTCAudioSession when the audio session
* activation state has changed outside of RTCAudioSession. The current known use
* case of this is when CallKit activates the audio session for the application
*/
RTC_OBJC_EXPORT
@protocol RTC_OBJC_TYPE
(RTCAudioSessionActivationDelegate)<NSObject>
/** Called when the audio session is activated outside of the app by iOS. */
- (void)audioSessionDidActivate : (AVAudioSession *)session;
/** Called when the audio session is deactivated outside of the app by iOS. */
- (void)audioSessionDidDeactivate:(AVAudioSession *)session;
@end
/** Proxy class for AVAudioSession that adds a locking mechanism similar to
* AVCaptureDevice. This is used to that interleaving configurations between
* WebRTC and the application layer are avoided.
*
* RTCAudioSession also coordinates activation so that the audio session is
* activated only once. See `setActive:error:`.
*/
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCAudioSession) : NSObject <RTC_OBJC_TYPE(RTCAudioSessionActivationDelegate)>
/** Convenience property to access the AVAudioSession singleton. Callers should
* not call setters on AVAudioSession directly, but other method invocations
* are fine.
*/
@property(nonatomic, readonly) AVAudioSession *session;
/** Our best guess at whether the session is active based on results of calls to
* AVAudioSession.
*/
@property(nonatomic, readonly) BOOL isActive;
/** If YES, WebRTC will not initialize the audio unit automatically when an
* audio track is ready for playout or recording. Instead, applications should
* call setIsAudioEnabled. If NO, WebRTC will initialize the audio unit
* as soon as an audio track is ready for playout or recording.
*/
@property(nonatomic, assign) BOOL useManualAudio;
/** This property is only effective if useManualAudio is YES.
* Represents permission for WebRTC to initialize the VoIP audio unit.
* When set to NO, if the VoIP audio unit used by WebRTC is active, it will be
* stopped and uninitialized. This will stop incoming and outgoing audio.
* When set to YES, WebRTC will initialize and start the audio unit when it is
* needed (e.g. due to establishing an audio connection).
* This property was introduced to work around an issue where if an AVPlayer is
* playing audio while the VoIP audio unit is initialized, its audio would be
* either cut off completely or played at a reduced volume. By preventing
* the audio unit from being initialized until after the audio has completed,
* we are able to prevent the abrupt cutoff.
*/
@property(nonatomic, assign) BOOL isAudioEnabled;
// Proxy properties.
@property(readonly) NSString *category;
@property(readonly) AVAudioSessionCategoryOptions categoryOptions;
@property(readonly) NSString *mode;
@property(readonly) BOOL secondaryAudioShouldBeSilencedHint;
@property(readonly) AVAudioSessionRouteDescription *currentRoute;
@property(readonly) NSInteger maximumInputNumberOfChannels;
@property(readonly) NSInteger maximumOutputNumberOfChannels;
@property(readonly) float inputGain;
@property(readonly) BOOL inputGainSettable;
@property(readonly) BOOL inputAvailable;
@property(readonly, nullable) NSArray<AVAudioSessionDataSourceDescription *> *inputDataSources;
@property(readonly, nullable) AVAudioSessionDataSourceDescription *inputDataSource;
@property(readonly, nullable) NSArray<AVAudioSessionDataSourceDescription *> *outputDataSources;
@property(readonly, nullable) AVAudioSessionDataSourceDescription *outputDataSource;
@property(readonly) double sampleRate;
@property(readonly) double preferredSampleRate;
@property(readonly) NSInteger inputNumberOfChannels;
@property(readonly) NSInteger outputNumberOfChannels;
@property(readonly) float outputVolume;
@property(readonly) NSTimeInterval inputLatency;
@property(readonly) NSTimeInterval outputLatency;
@property(readonly) NSTimeInterval IOBufferDuration;
@property(readonly) NSTimeInterval preferredIOBufferDuration;
/**
When YES, calls to -setConfiguration:error: and -setConfiguration:active:error: ignore errors in
configuring the audio session's "preferred" attributes (e.g. preferredInputNumberOfChannels).
Typically, configurations to preferred attributes are optimizations, and ignoring this type of
configuration error allows code flow to continue along the happy path when these optimization are
not available. The default value of this property is NO.
*/
@property(nonatomic) BOOL ignoresPreferredAttributeConfigurationErrors;
/** Default constructor. */
+ (instancetype)sharedInstance;
- (instancetype)init NS_UNAVAILABLE;
/** Adds a delegate, which is held weakly. */
- (void)addDelegate:(id<RTC_OBJC_TYPE(RTCAudioSessionDelegate)>)delegate;
/** Removes an added delegate. */
- (void)removeDelegate:(id<RTC_OBJC_TYPE(RTCAudioSessionDelegate)>)delegate;
/** Request exclusive access to the audio session for configuration. This call
* will block if the lock is held by another object.
*/
- (void)lockForConfiguration;
/** Relinquishes exclusive access to the audio session. */
- (void)unlockForConfiguration;
/** If `active`, activates the audio session if it isn't already active.
* Successful calls must be balanced with a setActive:NO when activation is no
* longer required. If not `active`, deactivates the audio session if one is
* active and this is the last balanced call. When deactivating, the
* AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation option is passed to
* AVAudioSession.
*/
- (BOOL)setActive:(BOOL)active error:(NSError **)outError;
// The following methods are proxies for the associated methods on
// AVAudioSession. `lockForConfiguration` must be called before using them
// otherwise they will fail with kRTCAudioSessionErrorLockRequired.
- (BOOL)setCategory:(AVAudioSessionCategory)category
mode:(AVAudioSessionMode)mode
options:(AVAudioSessionCategoryOptions)options
error:(NSError **)outError;
- (BOOL)setCategory:(AVAudioSessionCategory)category
withOptions:(AVAudioSessionCategoryOptions)options
error:(NSError **)outError;
- (BOOL)setMode:(AVAudioSessionMode)mode error:(NSError **)outError;
- (BOOL)setInputGain:(float)gain error:(NSError **)outError;
- (BOOL)setPreferredSampleRate:(double)sampleRate error:(NSError **)outError;
- (BOOL)setPreferredIOBufferDuration:(NSTimeInterval)duration error:(NSError **)outError;
- (BOOL)setPreferredInputNumberOfChannels:(NSInteger)count error:(NSError **)outError;
- (BOOL)setPreferredOutputNumberOfChannels:(NSInteger)count error:(NSError **)outError;
- (BOOL)overrideOutputAudioPort:(AVAudioSessionPortOverride)portOverride error:(NSError **)outError;
- (BOOL)setPreferredInput:(AVAudioSessionPortDescription *)inPort error:(NSError **)outError;
- (BOOL)setInputDataSource:(AVAudioSessionDataSourceDescription *)dataSource
error:(NSError **)outError;
- (BOOL)setOutputDataSource:(AVAudioSessionDataSourceDescription *)dataSource
error:(NSError **)outError;
@end
@interface RTC_OBJC_TYPE (RTCAudioSession)
(Configuration)
/** Applies the configuration to the current session. Attempts to set all
* properties even if previous ones fail. Only the last error will be
* returned.
* `lockForConfiguration` must be called first.
*/
- (BOOL)setConfiguration : (RTC_OBJC_TYPE(RTCAudioSessionConfiguration) *)configuration error
: (NSError **)outError;
/** Convenience method that calls both setConfiguration and setActive.
* `lockForConfiguration` must be called first.
*/
- (BOOL)setConfiguration:(RTC_OBJC_TYPE(RTCAudioSessionConfiguration) *)configuration
active:(BOOL)active
error:(NSError **)outError;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,46 @@
/*
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <AVFoundation/AVFoundation.h>
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
RTC_EXTERN const int kRTCAudioSessionPreferredNumberOfChannels;
RTC_EXTERN const double kRTCAudioSessionHighPerformanceSampleRate;
RTC_EXTERN const double kRTCAudioSessionHighPerformanceIOBufferDuration;
// Struct to hold configuration values.
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCAudioSessionConfiguration) : NSObject
@property(nonatomic, strong) NSString *category;
@property(nonatomic, assign) AVAudioSessionCategoryOptions categoryOptions;
@property(nonatomic, strong) NSString *mode;
@property(nonatomic, assign) double sampleRate;
@property(nonatomic, assign) NSTimeInterval ioBufferDuration;
@property(nonatomic, assign) NSInteger inputNumberOfChannels;
@property(nonatomic, assign) NSInteger outputNumberOfChannels;
/** Initializes configuration to defaults. */
- (instancetype)init NS_DESIGNATED_INITIALIZER;
/** Returns the current configuration of the audio session. */
+ (instancetype)currentConfiguration;
/** Returns the configuration that WebRTC needs. */
+ (instancetype)webRTCConfiguration;
/** Provide a way to override the default configuration. */
+ (void)setWebRTCConfiguration:(RTC_OBJC_TYPE(RTCAudioSessionConfiguration) *)configuration;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,32 @@
/*
* Copyright 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
#import <WebRTC/RTCMediaSource.h>
NS_ASSUME_NONNULL_BEGIN
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCAudioSource) : RTC_OBJC_TYPE(RTCMediaSource)
- (instancetype)init NS_UNAVAILABLE;
// Sets the volume for the RTCMediaSource. `volume` is a gain value in the range
// [0, 10].
// Temporary fix to be able to modify volume of remote audio tracks.
// TODO(kthelgason): Property stays here temporarily until a proper volume-api
// is available on the surface exposed by webrtc.
@property(nonatomic, assign) double volume;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,28 @@
/*
* Copyright 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <WebRTC/RTCMacros.h>
#import <WebRTC/RTCMediaStreamTrack.h>
NS_ASSUME_NONNULL_BEGIN
@class RTC_OBJC_TYPE(RTCAudioSource);
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCAudioTrack) : RTC_OBJC_TYPE(RTCMediaStreamTrack)
- (instancetype)init NS_UNAVAILABLE;
/** The audio source for this audio track. */
@property(nonatomic, readonly) RTC_OBJC_TYPE(RTCAudioSource) * source;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,52 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <AVFoundation/AVFoundation.h>
#import <WebRTC/RTCMacros.h>
#import <WebRTC/RTCVideoFrameBuffer.h>
NS_ASSUME_NONNULL_BEGIN
/** RTCVideoFrameBuffer containing a CVPixelBufferRef */
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCCVPixelBuffer) : NSObject <RTC_OBJC_TYPE(RTCVideoFrameBuffer)>
@property(nonatomic, readonly) CVPixelBufferRef pixelBuffer;
@property(nonatomic, readonly) int cropX;
@property(nonatomic, readonly) int cropY;
@property(nonatomic, readonly) int cropWidth;
@property(nonatomic, readonly) int cropHeight;
+ (NSSet<NSNumber *> *)supportedPixelFormats;
- (instancetype)initWithPixelBuffer:(CVPixelBufferRef)pixelBuffer;
- (instancetype)initWithPixelBuffer:(CVPixelBufferRef)pixelBuffer
adaptedWidth:(int)adaptedWidth
adaptedHeight:(int)adaptedHeight
cropWidth:(int)cropWidth
cropHeight:(int)cropHeight
cropX:(int)cropX
cropY:(int)cropY;
- (BOOL)requiresCropping;
- (BOOL)requiresScalingToWidth:(int)width height:(int)height;
- (int)bufferSizeForCroppingAndScalingToWidth:(int)width height:(int)height;
/** The minimum size of the `tmpBuffer` must be the number of bytes returned from the
* bufferSizeForCroppingAndScalingToWidth:height: method.
* If that size is 0, the `tmpBuffer` may be nil.
*/
- (BOOL)cropAndScaleTo:(CVPixelBufferRef)outputPixelBuffer
withTempBuffer:(nullable uint8_t *)tmpBuffer;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,41 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCLogging.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
typedef void (^RTCCallbackLoggerMessageHandler)(NSString *message);
typedef void (^RTCCallbackLoggerMessageAndSeverityHandler)(NSString *message,
RTCLoggingSeverity severity);
// This class intercepts WebRTC logs and forwards them to a registered block.
// This class is not threadsafe.
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCCallbackLogger) : NSObject
// The severity level to capture. The default is kRTCLoggingSeverityInfo.
@property(nonatomic, assign) RTCLoggingSeverity severity;
// The callback handler will be called on the same thread that does the
// logging, so if the logging callback can be slow it may be a good idea
// to implement dispatching to some other queue.
- (void)start:(nullable RTCCallbackLoggerMessageHandler)handler;
- (void)startWithMessageAndSeverityHandler:
(nullable RTCCallbackLoggerMessageAndSeverityHandler)handler;
- (void)stop;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,30 @@
/*
* Copyright 2015 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <WebRTC/RTCMacros.h>
@class AVCaptureSession;
/** RTCCameraPreviewView is a view that renders local video from an
* AVCaptureSession.
*/
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCCameraPreviewView) : UIView
/** The capture session being rendered in the view. Capture session
* is assigned to AVCaptureVideoPreviewLayer async in the same
* queue that the AVCaptureSession is started/stopped.
*/
@property(nonatomic, strong) AVCaptureSession* captureSession;
@end

View file

@ -0,0 +1,56 @@
/*
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <AVFoundation/AVFoundation.h>
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
#import <WebRTC/RTCVideoCapturer.h>
NS_ASSUME_NONNULL_BEGIN
RTC_OBJC_EXPORT
// Camera capture that implements RTCVideoCapturer. Delivers frames to a
// RTCVideoCapturerDelegate (usually RTCVideoSource).
NS_EXTENSION_UNAVAILABLE_IOS("Camera not available in app extensions.")
@interface RTC_OBJC_TYPE (RTCCameraVideoCapturer) : RTC_OBJC_TYPE(RTCVideoCapturer)
// Capture session that is used for capturing. Valid from initialization to dealloc.
@property(readonly, nonatomic) AVCaptureSession *captureSession;
// Returns list of available capture devices that support video capture.
+ (NSArray<AVCaptureDevice *> *)captureDevices;
// Returns list of formats that are supported by this class for this device.
+ (NSArray<AVCaptureDeviceFormat *> *)supportedFormatsForDevice:(AVCaptureDevice *)device;
// Returns the most efficient supported output pixel format for this capturer.
- (FourCharCode)preferredOutputPixelFormat;
// Starts the capture session asynchronously and notifies callback on completion.
// The device will capture video in the format given in the `format` parameter. If the pixel format
// in `format` is supported by the WebRTC pipeline, the same pixel format will be used for the
// output. Otherwise, the format returned by `preferredOutputPixelFormat` will be used.
- (void)startCaptureWithDevice:(AVCaptureDevice *)device
format:(AVCaptureDeviceFormat *)format
fps:(NSInteger)fps
completionHandler:(nullable void (^)(NSError *_Nullable))completionHandler;
// Stops the capture session asynchronously and notifies callback on completion.
- (void)stopCaptureWithCompletionHandler:(nullable void (^)(void))completionHandler;
// Starts the capture session asynchronously.
- (void)startCaptureWithDevice:(AVCaptureDevice *)device
format:(AVCaptureDeviceFormat *)format
fps:(NSInteger)fps;
// Stops the capture session asynchronously.
- (void)stopCapture;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,44 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCCertificate) : NSObject <NSCopying>
/** Private key in PEM. */
@property(nonatomic, readonly, copy) NSString *private_key;
/** Public key in an x509 cert encoded in PEM. */
@property(nonatomic, readonly, copy) NSString *certificate;
/**
* Initialize an RTCCertificate with PEM strings for private_key and certificate.
*/
- (instancetype)initWithPrivateKey:(NSString *)private_key
certificate:(NSString *)certificate NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
/** Generate a new certificate for 're' use.
*
* Optional dictionary of parameters. Defaults to KeyType ECDSA if none are
* provided.
* - name: "ECDSA" or "RSASSA-PKCS1-v1_5"
*/
+ (nullable RTC_OBJC_TYPE(RTCCertificate) *)generateCertificateWithParams:(NSDictionary *)params;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,24 @@
/*
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
/** Implement this protocol to pass codec specific info from the encoder.
* Corresponds to webrtc::CodecSpecificInfo.
*/
RTC_OBJC_EXPORT
@protocol RTC_OBJC_TYPE
(RTCCodecSpecificInfo)<NSObject> @end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,27 @@
/*
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCCodecSpecificInfo.h>
#import <WebRTC/RTCMacros.h>
/** Class for H264 specific config. */
typedef NS_ENUM(NSUInteger, RTCH264PacketizationMode) {
RTCH264PacketizationModeNonInterleaved = 0, // Mode 1 - STAP-A, FU-A is allowed
RTCH264PacketizationModeSingleNalUnit // Mode 0 - only single NALU allowed
};
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCCodecSpecificInfoH264) : NSObject <RTC_OBJC_TYPE(RTCCodecSpecificInfo)>
@property(nonatomic, assign) RTCH264PacketizationMode packetizationMode;
@end

View file

@ -0,0 +1,268 @@
/*
* Copyright 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCCertificate.h>
#import <WebRTC/RTCCryptoOptions.h>
#import <WebRTC/RTCMacros.h>
@class RTC_OBJC_TYPE(RTCIceServer);
/**
* Represents the ice transport policy. This exposes the same states in C++,
* which include one more state than what exists in the W3C spec.
*/
typedef NS_ENUM(NSInteger, RTCIceTransportPolicy) {
RTCIceTransportPolicyNone,
RTCIceTransportPolicyRelay,
RTCIceTransportPolicyNoHost,
RTCIceTransportPolicyAll
};
/** Represents the bundle policy. */
typedef NS_ENUM(NSInteger, RTCBundlePolicy) {
RTCBundlePolicyBalanced,
RTCBundlePolicyMaxCompat,
RTCBundlePolicyMaxBundle
};
/** Represents the rtcp mux policy. */
typedef NS_ENUM(NSInteger, RTCRtcpMuxPolicy) { RTCRtcpMuxPolicyNegotiate, RTCRtcpMuxPolicyRequire };
/** Represents the tcp candidate policy. */
typedef NS_ENUM(NSInteger, RTCTcpCandidatePolicy) {
RTCTcpCandidatePolicyEnabled,
RTCTcpCandidatePolicyDisabled
};
/** Represents the candidate network policy. */
typedef NS_ENUM(NSInteger, RTCCandidateNetworkPolicy) {
RTCCandidateNetworkPolicyAll,
RTCCandidateNetworkPolicyLowCost
};
/** Represents the continual gathering policy. */
typedef NS_ENUM(NSInteger, RTCContinualGatheringPolicy) {
RTCContinualGatheringPolicyGatherOnce,
RTCContinualGatheringPolicyGatherContinually
};
/** Represents the encryption key type. */
typedef NS_ENUM(NSInteger, RTCEncryptionKeyType) {
RTCEncryptionKeyTypeRSA,
RTCEncryptionKeyTypeECDSA,
};
/** Represents the chosen SDP semantics for the RTCPeerConnection. */
typedef NS_ENUM(NSInteger, RTCSdpSemantics) {
// TODO(https://crbug.com/webrtc/13528): Remove support for Plan B.
RTCSdpSemanticsPlanB,
RTCSdpSemanticsUnifiedPlan,
};
NS_ASSUME_NONNULL_BEGIN
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCConfiguration) : NSObject
/** If true, allows DSCP codes to be set on outgoing packets, configured using
* networkPriority field of RTCRtpEncodingParameters. Defaults to false.
*/
@property(nonatomic, assign) BOOL enableDscp;
/** An array of Ice Servers available to be used by ICE. */
@property(nonatomic, copy) NSArray<RTC_OBJC_TYPE(RTCIceServer) *> *iceServers;
/** An RTCCertificate for 're' use. */
@property(nonatomic, nullable) RTC_OBJC_TYPE(RTCCertificate) * certificate;
/** Which candidates the ICE agent is allowed to use. The W3C calls it
* `iceTransportPolicy`, while in C++ it is called `type`. */
@property(nonatomic, assign) RTCIceTransportPolicy iceTransportPolicy;
/** The media-bundling policy to use when gathering ICE candidates. */
@property(nonatomic, assign) RTCBundlePolicy bundlePolicy;
/** The rtcp-mux policy to use when gathering ICE candidates. */
@property(nonatomic, assign) RTCRtcpMuxPolicy rtcpMuxPolicy;
@property(nonatomic, assign) RTCTcpCandidatePolicy tcpCandidatePolicy;
@property(nonatomic, assign) RTCCandidateNetworkPolicy candidateNetworkPolicy;
@property(nonatomic, assign) RTCContinualGatheringPolicy continualGatheringPolicy;
/** If set to YES, don't gather IPv6 ICE candidates on Wi-Fi.
* Only intended to be used on specific devices. Certain phones disable IPv6
* when the screen is turned off and it would be better to just disable the
* IPv6 ICE candidates on Wi-Fi in those cases.
* Default is NO.
*/
@property(nonatomic, assign) BOOL disableIPV6OnWiFi;
/** By default, the PeerConnection will use a limited number of IPv6 network
* interfaces, in order to avoid too many ICE candidate pairs being created
* and delaying ICE completion.
*
* Can be set to INT_MAX to effectively disable the limit.
*/
@property(nonatomic, assign) int maxIPv6Networks;
/** Exclude link-local network interfaces
* from considertaion for gathering ICE candidates.
* Defaults to NO.
*/
@property(nonatomic, assign) BOOL disableLinkLocalNetworks;
@property(nonatomic, assign) int audioJitterBufferMaxPackets;
@property(nonatomic, assign) BOOL audioJitterBufferFastAccelerate;
@property(nonatomic, assign) int iceConnectionReceivingTimeout;
@property(nonatomic, assign) int iceBackupCandidatePairPingInterval;
/** Key type used to generate SSL identity. Default is ECDSA. */
@property(nonatomic, assign) RTCEncryptionKeyType keyType;
/** ICE candidate pool size as defined in JSEP. Default is 0. */
@property(nonatomic, assign) int iceCandidatePoolSize;
/** Prune turn ports on the same network to the same turn server.
* Default is NO.
*/
@property(nonatomic, assign) BOOL shouldPruneTurnPorts;
/** If set to YES, this means the ICE transport should presume TURN-to-TURN
* candidate pairs will succeed, even before a binding response is received.
*/
@property(nonatomic, assign) BOOL shouldPresumeWritableWhenFullyRelayed;
/* This flag is only effective when `continualGatheringPolicy` is
* RTCContinualGatheringPolicyGatherContinually.
*
* If YES, after the ICE transport type is changed such that new types of
* ICE candidates are allowed by the new transport type, e.g. from
* RTCIceTransportPolicyRelay to RTCIceTransportPolicyAll, candidates that
* have been gathered by the ICE transport but not matching the previous
* transport type and as a result not observed by PeerConnectionDelegateAdapter,
* will be surfaced to the delegate.
*/
@property(nonatomic, assign) BOOL shouldSurfaceIceCandidatesOnIceTransportTypeChanged;
/** If set to non-nil, controls the minimal interval between consecutive ICE
* check packets.
*/
@property(nonatomic, copy, nullable) NSNumber *iceCheckMinInterval;
/**
* Configure the SDP semantics used by this PeerConnection. By default, this
* is RTCSdpSemanticsUnifiedPlan which is compliant to the WebRTC 1.0
* specification. It is possible to overrwite this to the deprecated
* RTCSdpSemanticsPlanB SDP format, but note that RTCSdpSemanticsPlanB will be
* deleted at some future date, see https://crbug.com/webrtc/13528.
*
* RTCSdpSemanticsUnifiedPlan will cause RTCPeerConnection to create offers and
* answers with multiple m= sections where each m= section maps to one
* RTCRtpSender and one RTCRtpReceiver (an RTCRtpTransceiver), either both audio
* or both video. This will also cause RTCPeerConnection to ignore all but the
* first a=ssrc lines that form a Plan B stream.
*
* RTCSdpSemanticsPlanB will cause RTCPeerConnection to create offers and
* answers with at most one audio and one video m= section with multiple
* RTCRtpSenders and RTCRtpReceivers specified as multiple a=ssrc lines within
* the section. This will also cause RTCPeerConnection to ignore all but the
* first m= section of the same media type.
*/
@property(nonatomic, assign) RTCSdpSemantics sdpSemantics;
/** Actively reset the SRTP parameters when the DTLS transports underneath are
* changed after offer/answer negotiation. This is only intended to be a
* workaround for crbug.com/835958
*/
@property(nonatomic, assign) BOOL activeResetSrtpParams;
/** If the remote side support mid-stream codec switches then allow encoder
* switching to be performed.
*/
@property(nonatomic, assign) BOOL allowCodecSwitching;
/**
* Defines advanced optional cryptographic settings related to SRTP and
* frame encryption for native WebRTC. Setting this will overwrite any
* options set through the PeerConnectionFactory (which is deprecated).
*/
@property(nonatomic, nullable) RTC_OBJC_TYPE(RTCCryptoOptions) * cryptoOptions;
/**
* An optional string that will be attached to the TURN_ALLOCATE_REQUEST which
* which can be used to correlate client logs with backend logs.
*/
@property(nonatomic, nullable, copy) NSString *turnLoggingId;
/**
* Time interval between audio RTCP reports.
*/
@property(nonatomic, assign) int rtcpAudioReportIntervalMs;
/**
* Time interval between video RTCP reports.
*/
@property(nonatomic, assign) int rtcpVideoReportIntervalMs;
/**
* Allow implicit rollback of local description when remote description
* conflicts with local description.
* See: https://w3c.github.io/webrtc-pc/#dom-peerconnection-setremotedescription
*/
@property(nonatomic, assign) BOOL enableImplicitRollback;
/**
* Control if "a=extmap-allow-mixed" is included in the offer.
* See: https://www.chromestatus.com/feature/6269234631933952
*/
@property(nonatomic, assign) BOOL offerExtmapAllowMixed;
/**
* Defines the interval applied to ALL candidate pairs
* when ICE is strongly connected, and it overrides the
* default value of this interval in the ICE implementation;
*/
@property(nonatomic, copy, nullable) NSNumber *iceCheckIntervalStrongConnectivity;
/**
* Defines the counterpart for ALL pairs when ICE is
* weakly connected, and it overrides the default value of
* this interval in the ICE implementation
*/
@property(nonatomic, copy, nullable) NSNumber *iceCheckIntervalWeakConnectivity;
/**
* The min time period for which a candidate pair must wait for response to
* connectivity checks before it becomes unwritable. This parameter
* overrides the default value in the ICE implementation if set.
*/
@property(nonatomic, copy, nullable) NSNumber *iceUnwritableTimeout;
/**
* The min number of connectivity checks that a candidate pair must sent
* without receiving response before it becomes unwritable. This parameter
* overrides the default value in the ICE implementation if set.
*/
@property(nonatomic, copy, nullable) NSNumber *iceUnwritableMinChecks;
/**
* The min time period for which a candidate pair must wait for response to
* connectivity checks it becomes inactive. This parameter overrides the
* default value in the ICE implementation if set.
*/
@property(nonatomic, copy, nullable) NSNumber *iceInactiveTimeout;
- (instancetype)init;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,63 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Objective-C bindings for webrtc::CryptoOptions. This API had to be flattened
* as Objective-C doesn't support nested structures.
*/
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCCryptoOptions) : NSObject
/**
* Enable GCM crypto suites from RFC 7714 for SRTP. GCM will only be used
* if both sides enable it
*/
@property(nonatomic, assign) BOOL srtpEnableGcmCryptoSuites;
/**
* If set to true, the (potentially insecure) crypto cipher
* kSrtpAes128CmSha1_32 will be included in the list of supported ciphers
* during negotiation. It will only be used if both peers support it and no
* other ciphers get preferred.
*/
@property(nonatomic, assign) BOOL srtpEnableAes128Sha1_32CryptoCipher;
/**
* If set to true, encrypted RTP header extensions as defined in RFC 6904
* will be negotiated. They will only be used if both peers support them.
*/
@property(nonatomic, assign) BOOL srtpEnableEncryptedRtpHeaderExtensions;
/**
* If set all RtpSenders must have an FrameEncryptor attached to them before
* they are allowed to send packets. All RtpReceivers must have a
* FrameDecryptor attached to them before they are able to receive packets.
*/
@property(nonatomic, assign) BOOL sframeRequireFrameEncryption;
/**
* Initializes CryptoOptions with all possible options set explicitly. This
* is done when converting from a native RTCConfiguration.crypto_options.
*/
- (instancetype)initWithSrtpEnableGcmCryptoSuites:(BOOL)srtpEnableGcmCryptoSuites
srtpEnableAes128Sha1_32CryptoCipher:(BOOL)srtpEnableAes128Sha1_32CryptoCipher
srtpEnableEncryptedRtpHeaderExtensions:(BOOL)srtpEnableEncryptedRtpHeaderExtensions
sframeRequireFrameEncryption:(BOOL)sframeRequireFrameEncryption
NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,132 @@
/*
* Copyright 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <AvailabilityMacros.h>
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCDataBuffer) : NSObject
/** NSData representation of the underlying buffer. */
@property(nonatomic, readonly) NSData *data;
/** Indicates whether `data` contains UTF-8 or binary data. */
@property(nonatomic, readonly) BOOL isBinary;
- (instancetype)init NS_UNAVAILABLE;
/**
* Initialize an RTCDataBuffer from NSData. `isBinary` indicates whether `data`
* contains UTF-8 or binary data.
*/
- (instancetype)initWithData:(NSData *)data isBinary:(BOOL)isBinary;
@end
@class RTC_OBJC_TYPE(RTCDataChannel);
RTC_OBJC_EXPORT
@protocol RTC_OBJC_TYPE
(RTCDataChannelDelegate)<NSObject>
/** The data channel state changed. */
- (void)dataChannelDidChangeState : (RTC_OBJC_TYPE(RTCDataChannel) *)dataChannel;
/** The data channel successfully received a data buffer. */
- (void)dataChannel:(RTC_OBJC_TYPE(RTCDataChannel) *)dataChannel
didReceiveMessageWithBuffer:(RTC_OBJC_TYPE(RTCDataBuffer) *)buffer;
@optional
/** The data channel's `bufferedAmount` changed. */
- (void)dataChannel:(RTC_OBJC_TYPE(RTCDataChannel) *)dataChannel
didChangeBufferedAmount:(uint64_t)amount;
@end
/** Represents the state of the data channel. */
typedef NS_ENUM(NSInteger, RTCDataChannelState) {
RTCDataChannelStateConnecting,
RTCDataChannelStateOpen,
RTCDataChannelStateClosing,
RTCDataChannelStateClosed,
};
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCDataChannel) : NSObject
/**
* A label that can be used to distinguish this data channel from other data
* channel objects.
*/
@property(nonatomic, readonly) NSString *label;
/** Whether the data channel can send messages in unreliable mode. */
@property(nonatomic, readonly) BOOL isReliable DEPRECATED_ATTRIBUTE;
/** Returns whether this data channel is ordered or not. */
@property(nonatomic, readonly) BOOL isOrdered;
/** Deprecated. Use maxPacketLifeTime. */
@property(nonatomic, readonly) NSUInteger maxRetransmitTime DEPRECATED_ATTRIBUTE;
/**
* The length of the time window (in milliseconds) during which transmissions
* and retransmissions may occur in unreliable mode.
*/
@property(nonatomic, readonly) uint16_t maxPacketLifeTime;
/**
* The maximum number of retransmissions that are attempted in unreliable mode.
*/
@property(nonatomic, readonly) uint16_t maxRetransmits;
/**
* The name of the sub-protocol used with this data channel, if any. Otherwise
* this returns an empty string.
*/
@property(nonatomic, readonly) NSString *protocol;
/**
* Returns whether this data channel was negotiated by the application or not.
*/
@property(nonatomic, readonly) BOOL isNegotiated;
/** Deprecated. Use channelId. */
@property(nonatomic, readonly) NSInteger streamId DEPRECATED_ATTRIBUTE;
/** The identifier for this data channel. */
@property(nonatomic, readonly) int channelId;
/** The state of the data channel. */
@property(nonatomic, readonly) RTCDataChannelState readyState;
/**
* The number of bytes of application data that have been queued using
* `sendData:` but that have not yet been transmitted to the network.
*/
@property(nonatomic, readonly) uint64_t bufferedAmount;
/** The delegate for this data channel. */
@property(nonatomic, weak) id<RTC_OBJC_TYPE(RTCDataChannelDelegate)> delegate;
- (instancetype)init NS_UNAVAILABLE;
/** Closes the data channel. */
- (void)close;
/** Attempt to send `data` on this data channel's underlying data transport. */
- (BOOL)sendData:(RTC_OBJC_TYPE(RTCDataBuffer) *)data;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,52 @@
/*
* Copyright 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <AvailabilityMacros.h>
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCDataChannelConfiguration) : NSObject
/** Set to YES if ordered delivery is required. */
@property(nonatomic, assign) BOOL isOrdered;
/** Deprecated. Use maxPacketLifeTime. */
@property(nonatomic, assign) NSInteger maxRetransmitTimeMs DEPRECATED_ATTRIBUTE;
/**
* Max period in milliseconds in which retransmissions will be sent. After this
* time, no more retransmissions will be sent. -1 if unset.
*/
@property(nonatomic, assign) int maxPacketLifeTime;
/** The max number of retransmissions. -1 if unset. */
@property(nonatomic, assign) int maxRetransmits;
/** Set to YES if the channel has been externally negotiated and we do not send
* an in-band signalling in the form of an "open" message.
*/
@property(nonatomic, assign) BOOL isNegotiated;
/** Deprecated. Use channelId. */
@property(nonatomic, assign) int streamId DEPRECATED_ATTRIBUTE;
/** The id of the data channel. */
@property(nonatomic, assign) int channelId;
/** Set by the application and opaque to the WebRTC implementation. */
@property(nonatomic) NSString* protocol;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,26 @@
/*
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
#import <WebRTC/RTCVideoDecoderFactory.h>
NS_ASSUME_NONNULL_BEGIN
/** This decoder factory include support for all codecs bundled with WebRTC. If using custom
* codecs, create custom implementations of RTCVideoEncoderFactory and
* RTCVideoDecoderFactory.
*/
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCDefaultVideoDecoderFactory) : NSObject <RTC_OBJC_TYPE(RTCVideoDecoderFactory)>
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,31 @@
/*
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
#import <WebRTC/RTCVideoEncoderFactory.h>
NS_ASSUME_NONNULL_BEGIN
/** This encoder factory include support for all codecs bundled with WebRTC. If using custom
* codecs, create custom implementations of RTCVideoEncoderFactory and
* RTCVideoDecoderFactory.
*/
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCDefaultVideoEncoderFactory) : NSObject <RTC_OBJC_TYPE(RTCVideoEncoderFactory)>
@property(nonatomic, retain) RTC_OBJC_TYPE(RTCVideoCodecInfo) *preferredCodec;
+ (NSArray<RTC_OBJC_TYPE(RTCVideoCodecInfo) *> *)supportedCodecs;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,46 @@
/*
* Copyright 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
typedef NS_ENUM(NSInteger, RTCDispatcherQueueType) {
// Main dispatcher queue.
RTCDispatcherTypeMain,
// Used for starting/stopping AVCaptureSession, and assigning
// capture session to AVCaptureVideoPreviewLayer.
RTCDispatcherTypeCaptureSession,
// Used for operations on AVAudioSession.
RTCDispatcherTypeAudioSession,
// Used for operations on NWPathMonitor.
RTCDispatcherTypeNetworkMonitor,
};
/** Dispatcher that asynchronously dispatches blocks to a specific
* shared dispatch queue.
*/
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCDispatcher) : NSObject
- (instancetype)init NS_UNAVAILABLE;
/** Dispatch the block asynchronously on the queue for dispatchType.
* @param dispatchType The queue type to dispatch on.
* @param block The block to dispatch asynchronously.
*/
+ (void)dispatchAsyncOnType:(RTCDispatcherQueueType)dispatchType block:(dispatch_block_t)block;
/** Returns YES if run on queue for the dispatchType otherwise NO.
* Useful for asserting that a method is run on a correct queue.
*/
+ (BOOL)isOnQueueForType:(RTCDispatcherQueueType)dispatchType;
@end

View file

@ -0,0 +1,71 @@
/*
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
RTC_OBJC_EXPORT
@protocol RTC_OBJC_TYPE
(RTCDtmfSender)<NSObject>
/**
* Returns true if this RTCDtmfSender is capable of sending DTMF. Otherwise
* returns false. To be able to send DTMF, the associated RTCRtpSender must be
* able to send packets, and a "telephone-event" codec must be negotiated.
*/
@property(nonatomic, readonly) BOOL canInsertDtmf;
/**
* Queues a task that sends the DTMF tones. The tones parameter is treated
* as a series of characters. The characters 0 through 9, A through D, #, and *
* generate the associated DTMF tones. The characters a to d are equivalent
* to A to D. The character ',' indicates a delay of 2 seconds before
* processing the next character in the tones parameter.
*
* Unrecognized characters are ignored.
*
* @param duration The parameter indicates the duration to use for each
* character passed in the tones parameter. The duration cannot be more
* than 6000 or less than 70 ms.
*
* @param interToneGap The parameter indicates the gap between tones.
* This parameter must be at least 50 ms but should be as short as
* possible.
*
* If InsertDtmf is called on the same object while an existing task for this
* object to generate DTMF is still running, the previous task is canceled.
* Returns true on success and false on failure.
*/
- (BOOL)insertDtmf:(nonnull NSString *)tones
duration:(NSTimeInterval)duration
interToneGap:(NSTimeInterval)interToneGap;
/** The tones remaining to be played out */
- (nonnull NSString *)remainingTones;
/**
* The current tone duration value. This value will be the value last set via the
* insertDtmf method, or the default value of 100 ms if insertDtmf was never called.
*/
- (NSTimeInterval)duration;
/**
* The current value of the between-tone gap. This value will be the value last set
* via the insertDtmf() method, or the default value of 50 ms if insertDtmf() was never
* called.
*/
- (NSTimeInterval)interToneGap;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,45 @@
/*
* Copyright 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <WebRTC/RTCMacros.h>
#import <WebRTC/RTCVideoRenderer.h>
#import <WebRTC/RTCVideoViewShading.h>
NS_ASSUME_NONNULL_BEGIN
@class RTC_OBJC_TYPE(RTCEAGLVideoView);
/**
* RTCEAGLVideoView is an RTCVideoRenderer which renders video frames
* in its bounds using OpenGLES 2.0 or OpenGLES 3.0.
*/
RTC_OBJC_EXPORT
NS_EXTENSION_UNAVAILABLE_IOS("Rendering not available in app extensions.")
@interface RTC_OBJC_TYPE (RTCEAGLVideoView) : UIView <RTC_OBJC_TYPE(RTCVideoRenderer)>
@property(nonatomic, weak) id<RTC_OBJC_TYPE(RTCVideoViewDelegate)> delegate;
- (instancetype)initWithFrame:(CGRect)frame
shader:(id<RTC_OBJC_TYPE(RTCVideoViewShading)>)shader
NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithCoder:(NSCoder *)aDecoder
shader:(id<RTC_OBJC_TYPE(RTCVideoViewShading)>)shader
NS_DESIGNATED_INITIALIZER;
/** @abstract Wrapped RTCVideoRotation, or nil.
*/
@property(nonatomic, nullable) NSValue *rotationOverride;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,52 @@
/*
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
#import <WebRTC/RTCVideoFrame.h>
NS_ASSUME_NONNULL_BEGIN
/** Represents an encoded frame's type. */
typedef NS_ENUM(NSUInteger, RTCFrameType) {
RTCFrameTypeEmptyFrame = 0,
RTCFrameTypeAudioFrameSpeech = 1,
RTCFrameTypeAudioFrameCN = 2,
RTCFrameTypeVideoFrameKey = 3,
RTCFrameTypeVideoFrameDelta = 4,
};
typedef NS_ENUM(NSUInteger, RTCVideoContentType) {
RTCVideoContentTypeUnspecified,
RTCVideoContentTypeScreenshare,
};
/** Represents an encoded frame. Corresponds to webrtc::EncodedImage. */
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCEncodedImage) : NSObject
@property(nonatomic, strong) NSData *buffer;
@property(nonatomic, assign) int32_t encodedWidth;
@property(nonatomic, assign) int32_t encodedHeight;
@property(nonatomic, assign) uint32_t timeStamp;
@property(nonatomic, assign) int64_t captureTimeMs;
@property(nonatomic, assign) int64_t ntpTimeMs;
@property(nonatomic, assign) uint8_t flags;
@property(nonatomic, assign) int64_t encodeStartMs;
@property(nonatomic, assign) int64_t encodeFinishMs;
@property(nonatomic, assign) RTCFrameType frameType;
@property(nonatomic, assign) RTCVideoRotation rotation;
@property(nonatomic, strong) NSNumber *qp;
@property(nonatomic, assign) RTCVideoContentType contentType;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,30 @@
/*
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
/** The only valid value for the following if set is kRTCFieldTrialEnabledValue. */
RTC_EXTERN NSString *const kRTCFieldTrialAudioForceABWENoTWCCKey;
RTC_EXTERN NSString *const kRTCFieldTrialFlexFec03AdvertisedKey;
RTC_EXTERN NSString *const kRTCFieldTrialFlexFec03Key;
RTC_EXTERN NSString *const kRTCFieldTrialH264HighProfileKey;
RTC_EXTERN NSString *const kRTCFieldTrialMinimizeResamplingOnMobileKey;
RTC_EXTERN NSString *const kRTCFieldTrialUseNWPathMonitor;
/** The valid value for field trials above. */
RTC_EXTERN NSString *const kRTCFieldTrialEnabledValue;
/** Initialize field trials using a dictionary mapping field trial keys to their
* values. See above for valid keys and values. Must be called before any other
* call into WebRTC. See: webrtc/system_wrappers/include/field_trial.h
*/
RTC_EXTERN void RTCInitFieldTrialDictionary(NSDictionary<NSString *, NSString *> *fieldTrials);

View file

@ -0,0 +1,74 @@
/*
* Copyright 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
typedef NS_ENUM(NSUInteger, RTCFileLoggerSeverity) {
RTCFileLoggerSeverityVerbose,
RTCFileLoggerSeverityInfo,
RTCFileLoggerSeverityWarning,
RTCFileLoggerSeverityError
};
typedef NS_ENUM(NSUInteger, RTCFileLoggerRotationType) {
RTCFileLoggerTypeCall,
RTCFileLoggerTypeApp,
};
NS_ASSUME_NONNULL_BEGIN
// This class intercepts WebRTC logs and saves them to a file. The file size
// will not exceed the given maximum bytesize. When the maximum bytesize is
// reached, logs are rotated according to the rotationType specified.
// For kRTCFileLoggerTypeCall, logs from the beginning and the end
// are preserved while the middle section is overwritten instead.
// For kRTCFileLoggerTypeApp, the oldest log is overwritten.
// This class is not threadsafe.
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCFileLogger) : NSObject
// The severity level to capture. The default is kRTCFileLoggerSeverityInfo.
@property(nonatomic, assign) RTCFileLoggerSeverity severity;
// The rotation type for this file logger. The default is
// kRTCFileLoggerTypeCall.
@property(nonatomic, readonly) RTCFileLoggerRotationType rotationType;
// Disables buffering disk writes. Should be set before `start`. Buffering
// is enabled by default for performance.
@property(nonatomic, assign) BOOL shouldDisableBuffering;
// Default constructor provides default settings for dir path, file size and
// rotation type.
- (instancetype)init;
// Create file logger with default rotation type.
- (instancetype)initWithDirPath:(NSString *)dirPath maxFileSize:(NSUInteger)maxFileSize;
- (instancetype)initWithDirPath:(NSString *)dirPath
maxFileSize:(NSUInteger)maxFileSize
rotationType:(RTCFileLoggerRotationType)rotationType NS_DESIGNATED_INITIALIZER;
// Starts writing WebRTC logs to disk if not already started. Overwrites any
// existing file(s).
- (void)start;
// Stops writing WebRTC logs to disk. This method is also called on dealloc.
- (void)stop;
// Returns the current contents of the logs, or nil if start has been called
// without a stop.
- (nullable NSData *)logData;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,51 @@
/*
* Copyright 2017 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCVideoCapturer.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Error passing block.
*/
typedef void (^RTCFileVideoCapturerErrorBlock)(NSError *error);
/**
* Captures buffers from bundled video file.
*
* See @c RTCVideoCapturer for more info on capturers.
*/
RTC_OBJC_EXPORT
NS_CLASS_AVAILABLE_IOS(10)
@interface RTC_OBJC_TYPE (RTCFileVideoCapturer) : RTC_OBJC_TYPE(RTCVideoCapturer)
/**
* Starts asynchronous capture of frames from video file.
*
* Capturing is not started if error occurs. Underlying error will be
* relayed in the errorBlock if one is provided.
* Successfully captured video frames will be passed to the delegate.
*
* @param nameOfFile The name of the bundled video file to be read.
* @errorBlock block to be executed upon error.
*/
- (void)startCapturingFromFileNamed:(NSString *)nameOfFile
onError:(__nullable RTCFileVideoCapturerErrorBlock)errorBlock;
/**
* Immediately stops capture.
*/
- (void)stopCapture;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,60 @@
/*
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
RTC_OBJC_EXPORT extern NSString *const kRTCVideoCodecH264Name;
RTC_OBJC_EXPORT extern NSString *const kRTCLevel31ConstrainedHigh;
RTC_OBJC_EXPORT extern NSString *const kRTCLevel31ConstrainedBaseline;
RTC_OBJC_EXPORT extern NSString *const kRTCMaxSupportedH264ProfileLevelConstrainedHigh;
RTC_OBJC_EXPORT extern NSString *const kRTCMaxSupportedH264ProfileLevelConstrainedBaseline;
/** H264 Profiles and levels. */
typedef NS_ENUM(NSUInteger, RTCH264Profile) {
RTCH264ProfileConstrainedBaseline,
RTCH264ProfileBaseline,
RTCH264ProfileMain,
RTCH264ProfileConstrainedHigh,
RTCH264ProfileHigh,
};
typedef NS_ENUM(NSUInteger, RTCH264Level) {
RTCH264Level1_b = 0,
RTCH264Level1 = 10,
RTCH264Level1_1 = 11,
RTCH264Level1_2 = 12,
RTCH264Level1_3 = 13,
RTCH264Level2 = 20,
RTCH264Level2_1 = 21,
RTCH264Level2_2 = 22,
RTCH264Level3 = 30,
RTCH264Level3_1 = 31,
RTCH264Level3_2 = 32,
RTCH264Level4 = 40,
RTCH264Level4_1 = 41,
RTCH264Level4_2 = 42,
RTCH264Level5 = 50,
RTCH264Level5_1 = 51,
RTCH264Level5_2 = 52
};
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCH264ProfileLevelId) : NSObject
@property(nonatomic, readonly) RTCH264Profile profile;
@property(nonatomic, readonly) RTCH264Level level;
@property(nonatomic, readonly) NSString *hexString;
- (instancetype)initWithHexString:(NSString *)hexString;
- (instancetype)initWithProfile:(RTCH264Profile)profile level:(RTCH264Level)level;
@end

View file

@ -0,0 +1,22 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <AVFoundation/AVFoundation.h>
#import <WebRTC/RTCYUVPlanarBuffer.h>
NS_ASSUME_NONNULL_BEGIN
/** Protocol for RTCYUVPlanarBuffers containing I420 data */
RTC_OBJC_EXPORT
@protocol RTC_OBJC_TYPE
(RTCI420Buffer)<RTC_OBJC_TYPE(RTCYUVPlanarBuffer)> @end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,49 @@
/*
* Copyright 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCIceCandidate) : NSObject
/**
* If present, the identifier of the "media stream identification" for the media
* component this candidate is associated with.
*/
@property(nonatomic, readonly, nullable) NSString *sdpMid;
/**
* The index (starting at zero) of the media description this candidate is
* associated with in the SDP.
*/
@property(nonatomic, readonly) int sdpMLineIndex;
/** The SDP string for this candidate. */
@property(nonatomic, readonly) NSString *sdp;
/** The URL of the ICE server which this candidate is gathered from. */
@property(nonatomic, readonly, nullable) NSString *serverUrl;
- (instancetype)init NS_UNAVAILABLE;
/**
* Initialize an RTCIceCandidate from SDP.
*/
- (instancetype)initWithSdp:(NSString *)sdp
sdpMLineIndex:(int)sdpMLineIndex
sdpMid:(nullable NSString *)sdpMid NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCIceCandidateErrorEvent) : NSObject
/** The local IP address used to communicate with the STUN or TURN server. */
@property(nonatomic, readonly) NSString *address;
/** The port used to communicate with the STUN or TURN server. */
@property(nonatomic, readonly) int port;
/** The STUN or TURN URL that identifies the STUN or TURN server for which the failure occurred. */
@property(nonatomic, readonly) NSString *url;
/** The numeric STUN error code returned by the STUN or TURN server. If no host candidate can reach
* the server, errorCode will be set to the value 701 which is outside the STUN error code range.
* This error is only fired once per server URL while in the RTCIceGatheringState of "gathering". */
@property(nonatomic, readonly) int errorCode;
/** The STUN reason text returned by the STUN or TURN server. If the server could not be reached,
* errorText will be set to an implementation-specific value providing details about the error. */
@property(nonatomic, readonly) NSString *errorText;
- (instancetype)init NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,114 @@
/*
* Copyright 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
typedef NS_ENUM(NSUInteger, RTCTlsCertPolicy) {
RTCTlsCertPolicySecure,
RTCTlsCertPolicyInsecureNoCheck
};
NS_ASSUME_NONNULL_BEGIN
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCIceServer) : NSObject
/** URI(s) for this server represented as NSStrings. */
@property(nonatomic, readonly) NSArray<NSString *> *urlStrings;
/** Username to use if this RTCIceServer object is a TURN server. */
@property(nonatomic, readonly, nullable) NSString *username;
/** Credential to use if this RTCIceServer object is a TURN server. */
@property(nonatomic, readonly, nullable) NSString *credential;
/**
* TLS certificate policy to use if this RTCIceServer object is a TURN server.
*/
@property(nonatomic, readonly) RTCTlsCertPolicy tlsCertPolicy;
/**
If the URIs in `urls` only contain IP addresses, this field can be used
to indicate the hostname, which may be necessary for TLS (using the SNI
extension). If `urls` itself contains the hostname, this isn't necessary.
*/
@property(nonatomic, readonly, nullable) NSString *hostname;
/** List of protocols to be used in the TLS ALPN extension. */
@property(nonatomic, readonly) NSArray<NSString *> *tlsAlpnProtocols;
/**
List elliptic curves to be used in the TLS elliptic curves extension.
Only curve names supported by OpenSSL should be used (eg. "P-256","X25519").
*/
@property(nonatomic, readonly) NSArray<NSString *> *tlsEllipticCurves;
- (nonnull instancetype)init NS_UNAVAILABLE;
/** Convenience initializer for a server with no authentication (e.g. STUN). */
- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings;
/**
* Initialize an RTCIceServer with its associated URLs, optional username,
* optional credential, and credentialType.
*/
- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings
username:(nullable NSString *)username
credential:(nullable NSString *)credential;
/**
* Initialize an RTCIceServer with its associated URLs, optional username,
* optional credential, and TLS cert policy.
*/
- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings
username:(nullable NSString *)username
credential:(nullable NSString *)credential
tlsCertPolicy:(RTCTlsCertPolicy)tlsCertPolicy;
/**
* Initialize an RTCIceServer with its associated URLs, optional username,
* optional credential, TLS cert policy and hostname.
*/
- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings
username:(nullable NSString *)username
credential:(nullable NSString *)credential
tlsCertPolicy:(RTCTlsCertPolicy)tlsCertPolicy
hostname:(nullable NSString *)hostname;
/**
* Initialize an RTCIceServer with its associated URLs, optional username,
* optional credential, TLS cert policy, hostname and ALPN protocols.
*/
- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings
username:(nullable NSString *)username
credential:(nullable NSString *)credential
tlsCertPolicy:(RTCTlsCertPolicy)tlsCertPolicy
hostname:(nullable NSString *)hostname
tlsAlpnProtocols:(NSArray<NSString *> *)tlsAlpnProtocols;
/**
* Initialize an RTCIceServer with its associated URLs, optional username,
* optional credential, TLS cert policy, hostname, ALPN protocols and
* elliptic curves.
*/
- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings
username:(nullable NSString *)username
credential:(nullable NSString *)credential
tlsCertPolicy:(RTCTlsCertPolicy)tlsCertPolicy
hostname:(nullable NSString *)hostname
tlsAlpnProtocols:(nullable NSArray<NSString *> *)tlsAlpnProtocols
tlsEllipticCurves:(nullable NSArray<NSString *> *)tlsEllipticCurves
NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,37 @@
/*
* Copyright 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
/** This does not currently conform to the spec. */
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCLegacyStatsReport) : NSObject
/** Time since 1970-01-01T00:00:00Z in milliseconds. */
@property(nonatomic, readonly) CFTimeInterval timestamp;
/** The type of stats held by this object. */
@property(nonatomic, readonly) NSString *type;
/** The identifier for this object. */
@property(nonatomic, readonly) NSString *reportId;
/** A dictionary holding the actual stats. */
@property(nonatomic, readonly) NSDictionary<NSString *, NSString *> *values;
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,66 @@
/*
* Copyright 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
// Subset of rtc::LoggingSeverity.
typedef NS_ENUM(NSInteger, RTCLoggingSeverity) {
RTCLoggingSeverityVerbose,
RTCLoggingSeverityInfo,
RTCLoggingSeverityWarning,
RTCLoggingSeverityError,
RTCLoggingSeverityNone,
};
// Wrapper for C++ RTC_LOG(sev) macros.
// Logs the log string to the webrtc logstream for the given severity.
RTC_EXTERN void RTCLogEx(RTCLoggingSeverity severity, NSString* log_string);
// Wrapper for rtc::LogMessage::LogToDebug.
// Sets the minimum severity to be logged to console.
RTC_EXTERN void RTCSetMinDebugLogLevel(RTCLoggingSeverity severity);
// Returns the filename with the path prefix removed.
RTC_EXTERN NSString* RTCFileName(const char* filePath);
// Some convenience macros.
#define RTCLogString(format, ...) \
[NSString stringWithFormat:@"(%@:%d %s): " format, \
RTCFileName(__FILE__), \
__LINE__, \
__FUNCTION__, \
##__VA_ARGS__]
#define RTCLogFormat(severity, format, ...) \
do { \
NSString* log_string = RTCLogString(format, ##__VA_ARGS__); \
RTCLogEx(severity, log_string); \
} while (false)
#define RTCLogVerbose(format, ...) RTCLogFormat(RTCLoggingSeverityVerbose, format, ##__VA_ARGS__)
#define RTCLogInfo(format, ...) RTCLogFormat(RTCLoggingSeverityInfo, format, ##__VA_ARGS__)
#define RTCLogWarning(format, ...) RTCLogFormat(RTCLoggingSeverityWarning, format, ##__VA_ARGS__)
#define RTCLogError(format, ...) RTCLogFormat(RTCLoggingSeverityError, format, ##__VA_ARGS__)
#if !defined(NDEBUG)
#define RTCLogDebug(format, ...) RTCLogInfo(format, ##__VA_ARGS__)
#else
#define RTCLogDebug(format, ...) \
do { \
} while (false)
#endif
#define RTCLog(format, ...) RTCLogInfo(format, ##__VA_ARGS__)

View file

@ -0,0 +1,44 @@
/*
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
#import <WebRTC/RTCVideoFrame.h>
#import <WebRTC/RTCVideoRenderer.h>
NS_ASSUME_NONNULL_BEGIN
/**
* RTCMTLVideoView is thin wrapper around MTKView.
*
* It has id<RTCVideoRenderer> property that renders video frames in the view's
* bounds using Metal.
*/
NS_CLASS_AVAILABLE_IOS(9)
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCMTLVideoView) : UIView<RTC_OBJC_TYPE(RTCVideoRenderer)>
@property(nonatomic, weak) id<RTC_OBJC_TYPE(RTCVideoViewDelegate)> delegate;
@property(nonatomic) UIViewContentMode videoContentMode;
/** @abstract Enables/disables rendering.
*/
@property(nonatomic, getter=isEnabled) BOOL enabled;
/** @abstract Wrapped RTCVideoRotation, or nil.
*/
@property(nonatomic, nullable) NSValue* rotationOverride;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,63 @@
/*
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef SDK_OBJC_BASE_RTCMACROS_H_
#define SDK_OBJC_BASE_RTCMACROS_H_
#ifdef WEBRTC_ENABLE_OBJC_SYMBOL_EXPORT
#if defined(WEBRTC_LIBRARY_IMPL)
#define RTC_OBJC_EXPORT __attribute__((visibility("default")))
#endif
#endif // WEBRTC_ENABLE_OBJC_SYMBOL_EXPORT
#ifndef RTC_OBJC_EXPORT
#define RTC_OBJC_EXPORT
#endif
// Internal macros used to correctly concatenate symbols.
#define RTC_SYMBOL_CONCAT_HELPER(a, b) a##b
#define RTC_SYMBOL_CONCAT(a, b) RTC_SYMBOL_CONCAT_HELPER(a, b)
// RTC_OBJC_TYPE_PREFIX
//
// Macro used to prepend a prefix to the API types that are exported with
// RTC_OBJC_EXPORT.
//
// Clients can patch the definition of this macro locally and build
// WebRTC.framework with their own prefix in case symbol clashing is a
// problem.
//
// This macro must be defined uniformily across all the translation units.
#ifndef RTC_OBJC_TYPE_PREFIX
#define RTC_OBJC_TYPE_PREFIX
#endif
// RCT_OBJC_TYPE
//
// Macro used internally to declare API types. Declaring an API type without
// using this macro will not include the declared type in the set of types
// that will be affected by the configurable RTC_OBJC_TYPE_PREFIX.
#define RTC_OBJC_TYPE(type_name) RTC_SYMBOL_CONCAT(RTC_OBJC_TYPE_PREFIX, type_name)
#if defined(__cplusplus)
#define RTC_EXTERN extern "C" RTC_OBJC_EXPORT
#else
#define RTC_EXTERN extern RTC_OBJC_EXPORT
#endif
#ifdef __OBJC__
#define RTC_FWD_DECL_OBJC_CLASS(classname) @class classname
#else
#define RTC_FWD_DECL_OBJC_CLASS(classname) typedef struct objc_object classname
#endif
#endif // SDK_OBJC_BASE_RTCMACROS_H_

View file

@ -0,0 +1,46 @@
/*
* Copyright 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
/** Constraint keys for media sources. */
/** The value for this key should be a base64 encoded string containing
* the data from the serialized configuration proto.
*/
RTC_EXTERN NSString *const kRTCMediaConstraintsAudioNetworkAdaptorConfig;
/** Constraint keys for generating offers and answers. */
RTC_EXTERN NSString *const kRTCMediaConstraintsIceRestart;
RTC_EXTERN NSString *const kRTCMediaConstraintsOfferToReceiveAudio;
RTC_EXTERN NSString *const kRTCMediaConstraintsOfferToReceiveVideo;
RTC_EXTERN NSString *const kRTCMediaConstraintsVoiceActivityDetection;
/** Constraint values for Boolean parameters. */
RTC_EXTERN NSString *const kRTCMediaConstraintsValueTrue;
RTC_EXTERN NSString *const kRTCMediaConstraintsValueFalse;
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCMediaConstraints) : NSObject
- (instancetype)init NS_UNAVAILABLE;
/** Initialize with mandatory and/or optional constraints. */
- (instancetype)
initWithMandatoryConstraints:(nullable NSDictionary<NSString *, NSString *> *)mandatory
optionalConstraints:(nullable NSDictionary<NSString *, NSString *> *)optional
NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,34 @@
/*
* Copyright 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
typedef NS_ENUM(NSInteger, RTCSourceState) {
RTCSourceStateInitializing,
RTCSourceStateLive,
RTCSourceStateEnded,
RTCSourceStateMuted,
};
NS_ASSUME_NONNULL_BEGIN
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCMediaSource) : NSObject
/** The current state of the RTCMediaSource. */
@property(nonatomic, readonly) RTCSourceState state;
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,49 @@
/*
* Copyright 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
@class RTC_OBJC_TYPE(RTCAudioTrack);
@class RTC_OBJC_TYPE(RTCPeerConnectionFactory);
@class RTC_OBJC_TYPE(RTCVideoTrack);
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCMediaStream) : NSObject
/** The audio tracks in this stream. */
@property(nonatomic, strong, readonly) NSArray<RTC_OBJC_TYPE(RTCAudioTrack) *> *audioTracks;
/** The video tracks in this stream. */
@property(nonatomic, strong, readonly) NSArray<RTC_OBJC_TYPE(RTCVideoTrack) *> *videoTracks;
/** An identifier for this media stream. */
@property(nonatomic, readonly) NSString *streamId;
- (instancetype)init NS_UNAVAILABLE;
/** Adds the given audio track to this media stream. */
- (void)addAudioTrack:(RTC_OBJC_TYPE(RTCAudioTrack) *)audioTrack;
/** Adds the given video track to this media stream. */
- (void)addVideoTrack:(RTC_OBJC_TYPE(RTCVideoTrack) *)videoTrack;
/** Removes the given audio track to this media stream. */
- (void)removeAudioTrack:(RTC_OBJC_TYPE(RTCAudioTrack) *)audioTrack;
/** Removes the given video track to this media stream. */
- (void)removeVideoTrack:(RTC_OBJC_TYPE(RTCVideoTrack) *)videoTrack;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,50 @@
/*
* Copyright 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
/**
* Represents the state of the track. This exposes the same states in C++.
*/
typedef NS_ENUM(NSInteger, RTCMediaStreamTrackState) {
RTCMediaStreamTrackStateLive,
RTCMediaStreamTrackStateEnded
};
NS_ASSUME_NONNULL_BEGIN
RTC_EXTERN NSString *const kRTCMediaStreamTrackKindAudio;
RTC_EXTERN NSString *const kRTCMediaStreamTrackKindVideo;
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCMediaStreamTrack) : NSObject
/**
* The kind of track. For example, "audio" if this track represents an audio
* track and "video" if this track represents a video track.
*/
@property(nonatomic, readonly) NSString *kind;
/** An identifier string. */
@property(nonatomic, readonly) NSString *trackId;
/** The enabled state of the track. */
@property(nonatomic, assign) BOOL isEnabled;
/** The state of the track. */
@property(nonatomic, readonly) RTCMediaStreamTrackState readyState;
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,23 @@
/*
* Copyright 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
#import <WebRTC/RTCMetricsSampleInfo.h>
/**
* Enables gathering of metrics (which can be fetched with
* RTCGetAndResetMetrics). Must be called before any other call into WebRTC.
*/
RTC_EXTERN void RTCEnableMetrics(void);
/** Gets and clears native histograms. */
RTC_EXTERN NSArray<RTC_OBJC_TYPE(RTCMetricsSampleInfo) *>* RTCGetAndResetMetrics(void);

View file

@ -0,0 +1,48 @@
/*
* Copyright 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCMetricsSampleInfo) : NSObject
/**
* Example of RTCMetricsSampleInfo:
* name: "WebRTC.Video.InputFramesPerSecond"
* min: 1
* max: 100
* bucketCount: 50
* samples: [29]:2 [30]:1
*/
/** The name of the histogram. */
@property(nonatomic, readonly) NSString *name;
/** The minimum bucket value. */
@property(nonatomic, readonly) int min;
/** The maximum bucket value. */
@property(nonatomic, readonly) int max;
/** The number of buckets. */
@property(nonatomic, readonly) int bucketCount;
/** A dictionary holding the samples <value, # of events>. */
@property(nonatomic, readonly) NSDictionary<NSNumber *, NSNumber *> *samples;
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,23 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <AVFoundation/AVFoundation.h>
#import <WebRTC/RTCI420Buffer.h>
#import <WebRTC/RTCMutableYUVPlanarBuffer.h>
NS_ASSUME_NONNULL_BEGIN
/** Extension of the I420 buffer with mutable data access */
RTC_OBJC_EXPORT
@protocol RTC_OBJC_TYPE
(RTCMutableI420Buffer)<RTC_OBJC_TYPE(RTCI420Buffer), RTC_OBJC_TYPE(RTCMutableYUVPlanarBuffer)> @end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,28 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <AVFoundation/AVFoundation.h>
#import <WebRTC/RTCYUVPlanarBuffer.h>
NS_ASSUME_NONNULL_BEGIN
/** Extension of the YUV planar data buffer with mutable data access */
RTC_OBJC_EXPORT
@protocol RTC_OBJC_TYPE
(RTCMutableYUVPlanarBuffer)<RTC_OBJC_TYPE(RTCYUVPlanarBuffer)>
@property(nonatomic, readonly) uint8_t *mutableDataY;
@property(nonatomic, readonly) uint8_t *mutableDataU;
@property(nonatomic, readonly) uint8_t *mutableDataV;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,23 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <AVFoundation/AVFoundation.h>
#import <WebRTC/RTCI420Buffer.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
/** RTCI420Buffer implements the RTCI420Buffer protocol */
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCI420Buffer) : NSObject<RTC_OBJC_TYPE(RTCI420Buffer)>
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,24 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <AVFoundation/AVFoundation.h>
#import <WebRTC/RTCMacros.h>
#import <WebRTC/RTCMutableI420Buffer.h>
#import <WebRTC/RTCNativeI420Buffer.h>
NS_ASSUME_NONNULL_BEGIN
/** Mutable version of RTCI420Buffer */
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCMutableI420Buffer) : RTC_OBJC_TYPE(RTCI420Buffer)<RTC_OBJC_TYPE(RTCMutableI420Buffer)>
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,24 @@
/*
* Copyright 2020 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/** Listens for NWPathMonitor updates and forwards the results to a C++
* observer.
*/
@interface RTCNetworkMonitor : NSObject
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,397 @@
/*
* Copyright 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
@class RTC_OBJC_TYPE(RTCConfiguration);
@class RTC_OBJC_TYPE(RTCDataChannel);
@class RTC_OBJC_TYPE(RTCDataChannelConfiguration);
@class RTC_OBJC_TYPE(RTCIceCandidate);
@class RTC_OBJC_TYPE(RTCIceCandidateErrorEvent);
@class RTC_OBJC_TYPE(RTCMediaConstraints);
@class RTC_OBJC_TYPE(RTCMediaStream);
@class RTC_OBJC_TYPE(RTCMediaStreamTrack);
@class RTC_OBJC_TYPE(RTCPeerConnectionFactory);
@class RTC_OBJC_TYPE(RTCRtpReceiver);
@class RTC_OBJC_TYPE(RTCRtpSender);
@class RTC_OBJC_TYPE(RTCRtpTransceiver);
@class RTC_OBJC_TYPE(RTCRtpTransceiverInit);
@class RTC_OBJC_TYPE(RTCSessionDescription);
@class RTC_OBJC_TYPE(RTCStatisticsReport);
@class RTC_OBJC_TYPE(RTCLegacyStatsReport);
typedef NS_ENUM(NSInteger, RTCRtpMediaType);
NS_ASSUME_NONNULL_BEGIN
extern NSString *const kRTCPeerConnectionErrorDomain;
extern int const kRTCSessionDescriptionErrorCode;
/** Represents the signaling state of the peer connection. */
typedef NS_ENUM(NSInteger, RTCSignalingState) {
RTCSignalingStateStable,
RTCSignalingStateHaveLocalOffer,
RTCSignalingStateHaveLocalPrAnswer,
RTCSignalingStateHaveRemoteOffer,
RTCSignalingStateHaveRemotePrAnswer,
// Not an actual state, represents the total number of states.
RTCSignalingStateClosed,
};
/** Represents the ice connection state of the peer connection. */
typedef NS_ENUM(NSInteger, RTCIceConnectionState) {
RTCIceConnectionStateNew,
RTCIceConnectionStateChecking,
RTCIceConnectionStateConnected,
RTCIceConnectionStateCompleted,
RTCIceConnectionStateFailed,
RTCIceConnectionStateDisconnected,
RTCIceConnectionStateClosed,
RTCIceConnectionStateCount,
};
/** Represents the combined ice+dtls connection state of the peer connection. */
typedef NS_ENUM(NSInteger, RTCPeerConnectionState) {
RTCPeerConnectionStateNew,
RTCPeerConnectionStateConnecting,
RTCPeerConnectionStateConnected,
RTCPeerConnectionStateDisconnected,
RTCPeerConnectionStateFailed,
RTCPeerConnectionStateClosed,
};
/** Represents the ice gathering state of the peer connection. */
typedef NS_ENUM(NSInteger, RTCIceGatheringState) {
RTCIceGatheringStateNew,
RTCIceGatheringStateGathering,
RTCIceGatheringStateComplete,
};
/** Represents the stats output level. */
typedef NS_ENUM(NSInteger, RTCStatsOutputLevel) {
RTCStatsOutputLevelStandard,
RTCStatsOutputLevelDebug,
};
typedef void (^RTCCreateSessionDescriptionCompletionHandler)(
RTC_OBJC_TYPE(RTCSessionDescription) *_Nullable sdp, NSError *_Nullable error);
typedef void (^RTCSetSessionDescriptionCompletionHandler)(NSError *_Nullable error);
@class RTC_OBJC_TYPE(RTCPeerConnection);
RTC_OBJC_EXPORT
@protocol RTC_OBJC_TYPE
(RTCPeerConnectionDelegate)<NSObject>
/** Called when the SignalingState changed. */
- (void)peerConnection
: (RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection didChangeSignalingState
: (RTCSignalingState)stateChanged;
/** Called when media is received on a new stream from remote peer. */
- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection
didAddStream:(RTC_OBJC_TYPE(RTCMediaStream) *)stream;
/** Called when a remote peer closes a stream.
* This is not called when RTCSdpSemanticsUnifiedPlan is specified.
*/
- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection
didRemoveStream:(RTC_OBJC_TYPE(RTCMediaStream) *)stream;
/** Called when negotiation is needed, for example ICE has restarted. */
- (void)peerConnectionShouldNegotiate:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection;
/** Called any time the IceConnectionState changes. */
- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection
didChangeIceConnectionState:(RTCIceConnectionState)newState;
/** Called any time the IceGatheringState changes. */
- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection
didChangeIceGatheringState:(RTCIceGatheringState)newState;
/** New ice candidate has been found. */
- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection
didGenerateIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)candidate;
/** Called when a group of local Ice candidates have been removed. */
- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection
didRemoveIceCandidates:(NSArray<RTC_OBJC_TYPE(RTCIceCandidate) *> *)candidates;
/** New data channel has been opened. */
- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection
didOpenDataChannel:(RTC_OBJC_TYPE(RTCDataChannel) *)dataChannel;
/** Called when signaling indicates a transceiver will be receiving media from
* the remote endpoint.
* This is only called with RTCSdpSemanticsUnifiedPlan specified.
*/
@optional
/** Called any time the IceConnectionState changes following standardized
* transition. */
- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection
didChangeStandardizedIceConnectionState:(RTCIceConnectionState)newState;
/** Called any time the PeerConnectionState changes. */
- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection
didChangeConnectionState:(RTCPeerConnectionState)newState;
- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection
didStartReceivingOnTransceiver:(RTC_OBJC_TYPE(RTCRtpTransceiver) *)transceiver;
/** Called when a receiver and its track are created. */
- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection
didAddReceiver:(RTC_OBJC_TYPE(RTCRtpReceiver) *)rtpReceiver
streams:(NSArray<RTC_OBJC_TYPE(RTCMediaStream) *> *)mediaStreams;
/** Called when the receiver and its track are removed. */
- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection
didRemoveReceiver:(RTC_OBJC_TYPE(RTCRtpReceiver) *)rtpReceiver;
/** Called when the selected ICE candidate pair is changed. */
- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection
didChangeLocalCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)local
remoteCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)remote
lastReceivedMs:(int)lastDataReceivedMs
changeReason:(NSString *)reason;
/** Called when gathering of an ICE candidate failed. */
- (void)peerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)peerConnection
didFailToGatherIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidateErrorEvent) *)event;
@end
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCPeerConnection) : NSObject
/** The object that will be notifed about events such as state changes and
* streams being added or removed.
*/
@property(nonatomic, weak, nullable) id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)> delegate;
/** This property is not available with RTCSdpSemanticsUnifiedPlan. Please use
* `senders` instead.
*/
@property(nonatomic, readonly) NSArray<RTC_OBJC_TYPE(RTCMediaStream) *> *localStreams;
@property(nonatomic, readonly, nullable) RTC_OBJC_TYPE(RTCSessionDescription) * localDescription;
@property(nonatomic, readonly, nullable) RTC_OBJC_TYPE(RTCSessionDescription) * remoteDescription;
@property(nonatomic, readonly) RTCSignalingState signalingState;
@property(nonatomic, readonly) RTCIceConnectionState iceConnectionState;
@property(nonatomic, readonly) RTCPeerConnectionState connectionState;
@property(nonatomic, readonly) RTCIceGatheringState iceGatheringState;
@property(nonatomic, readonly, copy) RTC_OBJC_TYPE(RTCConfiguration) * configuration;
/** Gets all RTCRtpSenders associated with this peer connection.
* Note: reading this property returns different instances of RTCRtpSender.
* Use isEqual: instead of == to compare RTCRtpSender instances.
*/
@property(nonatomic, readonly) NSArray<RTC_OBJC_TYPE(RTCRtpSender) *> *senders;
/** Gets all RTCRtpReceivers associated with this peer connection.
* Note: reading this property returns different instances of RTCRtpReceiver.
* Use isEqual: instead of == to compare RTCRtpReceiver instances.
*/
@property(nonatomic, readonly) NSArray<RTC_OBJC_TYPE(RTCRtpReceiver) *> *receivers;
/** Gets all RTCRtpTransceivers associated with this peer connection.
* Note: reading this property returns different instances of
* RTCRtpTransceiver. Use isEqual: instead of == to compare
* RTCRtpTransceiver instances. This is only available with
* RTCSdpSemanticsUnifiedPlan specified.
*/
@property(nonatomic, readonly) NSArray<RTC_OBJC_TYPE(RTCRtpTransceiver) *> *transceivers;
- (instancetype)init NS_UNAVAILABLE;
/** Sets the PeerConnection's global configuration to `configuration`.
* Any changes to STUN/TURN servers or ICE candidate policy will affect the
* next gathering phase, and cause the next call to createOffer to generate
* new ICE credentials. Note that the BUNDLE and RTCP-multiplexing policies
* cannot be changed with this method.
*/
- (BOOL)setConfiguration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration;
/** Terminate all media and close the transport. */
- (void)close;
/** Provide a remote candidate to the ICE Agent. */
- (void)addIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)candidate
DEPRECATED_MSG_ATTRIBUTE("Please use addIceCandidate:completionHandler: instead");
/** Provide a remote candidate to the ICE Agent. */
- (void)addIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)candidate
completionHandler:(void (^)(NSError *_Nullable error))completionHandler;
/** Remove a group of remote candidates from the ICE Agent. */
- (void)removeIceCandidates:(NSArray<RTC_OBJC_TYPE(RTCIceCandidate) *> *)candidates;
/** Add a new media stream to be sent on this peer connection.
* This method is not supported with RTCSdpSemanticsUnifiedPlan. Please use
* addTrack instead.
*/
- (void)addStream:(RTC_OBJC_TYPE(RTCMediaStream) *)stream;
/** Remove the given media stream from this peer connection.
* This method is not supported with RTCSdpSemanticsUnifiedPlan. Please use
* removeTrack instead.
*/
- (void)removeStream:(RTC_OBJC_TYPE(RTCMediaStream) *)stream;
/** Add a new media stream track to be sent on this peer connection, and return
* the newly created RTCRtpSender. The RTCRtpSender will be
* associated with the streams specified in the `streamIds` list.
*
* Errors: If an error occurs, returns nil. An error can occur if:
* - A sender already exists for the track.
* - The peer connection is closed.
*/
- (nullable RTC_OBJC_TYPE(RTCRtpSender) *)addTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track
streamIds:(NSArray<NSString *> *)streamIds;
/** With PlanB semantics, removes an RTCRtpSender from this peer connection.
*
* With UnifiedPlan semantics, sets sender's track to null and removes the
* send component from the associated RTCRtpTransceiver's direction.
*
* Returns YES on success.
*/
- (BOOL)removeTrack:(RTC_OBJC_TYPE(RTCRtpSender) *)sender;
/** addTransceiver creates a new RTCRtpTransceiver and adds it to the set of
* transceivers. Adding a transceiver will cause future calls to CreateOffer
* to add a media description for the corresponding transceiver.
*
* The initial value of `mid` in the returned transceiver is nil. Setting a
* new session description may change it to a non-nil value.
*
* https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addtransceiver
*
* Optionally, an RtpTransceiverInit structure can be specified to configure
* the transceiver from construction. If not specified, the transceiver will
* default to having a direction of kSendRecv and not be part of any streams.
*
* These methods are only available when Unified Plan is enabled (see
* RTCConfiguration).
*/
/** Adds a transceiver with a sender set to transmit the given track. The kind
* of the transceiver (and sender/receiver) will be derived from the kind of
* the track.
*/
- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)addTransceiverWithTrack:
(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track;
- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)
addTransceiverWithTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track
init:(RTC_OBJC_TYPE(RTCRtpTransceiverInit) *)init;
/** Adds a transceiver with the given kind. Can either be RTCRtpMediaTypeAudio
* or RTCRtpMediaTypeVideo.
*/
- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)addTransceiverOfType:(RTCRtpMediaType)mediaType;
- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)
addTransceiverOfType:(RTCRtpMediaType)mediaType
init:(RTC_OBJC_TYPE(RTCRtpTransceiverInit) *)init;
/** Tells the PeerConnection that ICE should be restarted. This triggers a need
* for negotiation and subsequent offerForConstraints:completionHandler call will act as if
* RTCOfferAnswerOptions::ice_restart is true.
*/
- (void)restartIce;
/** Generate an SDP offer. */
- (void)offerForConstraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
completionHandler:(RTCCreateSessionDescriptionCompletionHandler)completionHandler;
/** Generate an SDP answer. */
- (void)answerForConstraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
completionHandler:(RTCCreateSessionDescriptionCompletionHandler)completionHandler;
/** Apply the supplied RTCSessionDescription as the local description. */
- (void)setLocalDescription:(RTC_OBJC_TYPE(RTCSessionDescription) *)sdp
completionHandler:(RTCSetSessionDescriptionCompletionHandler)completionHandler;
/** Creates an offer or answer (depending on current signaling state) and sets
* it as the local session description. */
- (void)setLocalDescriptionWithCompletionHandler:
(RTCSetSessionDescriptionCompletionHandler)completionHandler;
/** Apply the supplied RTCSessionDescription as the remote description. */
- (void)setRemoteDescription:(RTC_OBJC_TYPE(RTCSessionDescription) *)sdp
completionHandler:(RTCSetSessionDescriptionCompletionHandler)completionHandler;
/** Limits the bandwidth allocated for all RTP streams sent by this
* PeerConnection. Nil parameters will be unchanged. Setting
* `currentBitrateBps` will force the available bitrate estimate to the given
* value. Returns YES if the parameters were successfully updated.
*/
- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps
currentBitrateBps:(nullable NSNumber *)currentBitrateBps
maxBitrateBps:(nullable NSNumber *)maxBitrateBps;
/** Start or stop recording an Rtc EventLog. */
- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath maxSizeInBytes:(int64_t)maxSizeInBytes;
- (void)stopRtcEventLog;
@end
@interface RTC_OBJC_TYPE (RTCPeerConnection)
(Media)
/** Create an RTCRtpSender with the specified kind and media stream ID.
* See RTCMediaStreamTrack.h for available kinds.
* This method is not supported with RTCSdpSemanticsUnifiedPlan. Please use
* addTransceiver instead.
*/
- (RTC_OBJC_TYPE(RTCRtpSender) *)senderWithKind : (NSString *)kind streamId
: (NSString *)streamId;
@end
@interface RTC_OBJC_TYPE (RTCPeerConnection)
(DataChannel)
/** Create a new data channel with the given label and configuration. */
- (nullable RTC_OBJC_TYPE(RTCDataChannel) *)dataChannelForLabel
: (NSString *)label configuration : (RTC_OBJC_TYPE(RTCDataChannelConfiguration) *)configuration;
@end
typedef void (^RTCStatisticsCompletionHandler)(RTC_OBJC_TYPE(RTCStatisticsReport) *);
@interface RTC_OBJC_TYPE (RTCPeerConnection)
(Stats)
/** Gather stats for the given RTCMediaStreamTrack. If `mediaStreamTrack` is nil
* statistics are gathered for all tracks.
*/
- (void)statsForTrack
: (nullable RTC_OBJC_TYPE(RTCMediaStreamTrack) *)mediaStreamTrack statsOutputLevel
: (RTCStatsOutputLevel)statsOutputLevel completionHandler
: (nullable void (^)(NSArray<RTC_OBJC_TYPE(RTCLegacyStatsReport) *> *stats))completionHandler;
/** Gather statistic through the v2 statistics API. */
- (void)statisticsWithCompletionHandler:(RTCStatisticsCompletionHandler)completionHandler;
/** Spec-compliant getStats() performing the stats selection algorithm with the
* sender.
*/
- (void)statisticsForSender:(RTC_OBJC_TYPE(RTCRtpSender) *)sender
completionHandler:(RTCStatisticsCompletionHandler)completionHandler;
/** Spec-compliant getStats() performing the stats selection algorithm with the
* receiver.
*/
- (void)statisticsForReceiver:(RTC_OBJC_TYPE(RTCRtpReceiver) *)receiver
completionHandler:(RTCStatisticsCompletionHandler)completionHandler;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,113 @@
/*
* Copyright 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
@class RTC_OBJC_TYPE(RTCAudioSource);
@class RTC_OBJC_TYPE(RTCAudioTrack);
@class RTC_OBJC_TYPE(RTCConfiguration);
@class RTC_OBJC_TYPE(RTCMediaConstraints);
@class RTC_OBJC_TYPE(RTCMediaStream);
@class RTC_OBJC_TYPE(RTCPeerConnection);
@class RTC_OBJC_TYPE(RTCVideoSource);
@class RTC_OBJC_TYPE(RTCVideoTrack);
@class RTC_OBJC_TYPE(RTCPeerConnectionFactoryOptions);
@protocol RTC_OBJC_TYPE
(RTCPeerConnectionDelegate);
@protocol RTC_OBJC_TYPE
(RTCVideoDecoderFactory);
@protocol RTC_OBJC_TYPE
(RTCVideoEncoderFactory);
@protocol RTC_OBJC_TYPE
(RTCSSLCertificateVerifier);
@protocol RTC_OBJC_TYPE
(RTCAudioDevice);
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCPeerConnectionFactory) : NSObject
/* Initialize object with default H264 video encoder/decoder factories and default ADM */
- (instancetype)init;
/* Initialize object with injectable video encoder/decoder factories and default ADM */
- (instancetype)
initWithEncoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoEncoderFactory)>)encoderFactory
decoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoDecoderFactory)>)decoderFactory;
/* Initialize object with injectable video encoder/decoder factories and injectable ADM */
- (instancetype)
initWithEncoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoEncoderFactory)>)encoderFactory
decoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoDecoderFactory)>)decoderFactory
audioDevice:(nullable id<RTC_OBJC_TYPE(RTCAudioDevice)>)audioDevice;
/** Initialize an RTCAudioSource with constraints. */
- (RTC_OBJC_TYPE(RTCAudioSource) *)audioSourceWithConstraints:
(nullable RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints;
/** Initialize an RTCAudioTrack with an id. Convenience ctor to use an audio source
* with no constraints.
*/
- (RTC_OBJC_TYPE(RTCAudioTrack) *)audioTrackWithTrackId:(NSString *)trackId;
/** Initialize an RTCAudioTrack with a source and an id. */
- (RTC_OBJC_TYPE(RTCAudioTrack) *)audioTrackWithSource:(RTC_OBJC_TYPE(RTCAudioSource) *)source
trackId:(NSString *)trackId;
/** Initialize a generic RTCVideoSource. The RTCVideoSource should be
* passed to a RTCVideoCapturer implementation, e.g.
* RTCCameraVideoCapturer, in order to produce frames.
*/
- (RTC_OBJC_TYPE(RTCVideoSource) *)videoSource;
/** Initialize a generic RTCVideoSource with he posibility of marking
* it as usable for screen sharing. The RTCVideoSource should be
* passed to a RTCVideoCapturer implementation, e.g.
* RTCCameraVideoCapturer, in order to produce frames.
*/
- (RTC_OBJC_TYPE(RTCVideoSource) *)videoSourceForScreenCast:(BOOL)forScreenCast;
/** Initialize an RTCVideoTrack with a source and an id. */
- (RTC_OBJC_TYPE(RTCVideoTrack) *)videoTrackWithSource:(RTC_OBJC_TYPE(RTCVideoSource) *)source
trackId:(NSString *)trackId;
/** Initialize an RTCMediaStream with an id. */
- (RTC_OBJC_TYPE(RTCMediaStream) *)mediaStreamWithStreamId:(NSString *)streamId;
/** Initialize an RTCPeerConnection with a configuration, constraints, and
* delegate.
*/
- (nullable RTC_OBJC_TYPE(RTCPeerConnection) *)
peerConnectionWithConfiguration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration
constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
delegate:(nullable id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate;
- (nullable RTC_OBJC_TYPE(RTCPeerConnection) *)
peerConnectionWithConfiguration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration
constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
certificateVerifier:
(id<RTC_OBJC_TYPE(RTCSSLCertificateVerifier)>)certificateVerifier
delegate:(nullable id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate;
/** Set the options to be used for subsequently created RTCPeerConnections */
- (void)setOptions:(nonnull RTC_OBJC_TYPE(RTCPeerConnectionFactoryOptions) *)options;
/** Start an AecDump recording. This API call will likely change in the future. */
- (BOOL)startAecDumpWithFilePath:(NSString *)filePath maxSizeInBytes:(int64_t)maxSizeInBytes;
/* Stop an active AecDump recording */
- (void)stopAecDump;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,38 @@
/*
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCPeerConnectionFactoryOptions) : NSObject
@property(nonatomic, assign) BOOL disableEncryption;
@property(nonatomic, assign) BOOL disableNetworkMonitor;
@property(nonatomic, assign) BOOL ignoreLoopbackNetworkAdapter;
@property(nonatomic, assign) BOOL ignoreVPNNetworkAdapter;
@property(nonatomic, assign) BOOL ignoreCellularNetworkAdapter;
@property(nonatomic, assign) BOOL ignoreWiFiNetworkAdapter;
@property(nonatomic, assign) BOOL ignoreEthernetNetworkAdapter;
- (instancetype)init NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,30 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCRtcpParameters) : NSObject
/** The Canonical Name used by RTCP. */
@property(nonatomic, readonly, copy) NSString *cname;
/** Whether reduced size RTCP is configured or compound RTCP. */
@property(nonatomic, assign) BOOL isReducedSize;
- (instancetype)init;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,73 @@
/*
* Copyright 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
RTC_EXTERN const NSString *const kRTCRtxCodecName;
RTC_EXTERN const NSString *const kRTCRedCodecName;
RTC_EXTERN const NSString *const kRTCUlpfecCodecName;
RTC_EXTERN const NSString *const kRTCFlexfecCodecName;
RTC_EXTERN const NSString *const kRTCOpusCodecName;
RTC_EXTERN const NSString *const kRTCIsacCodecName;
RTC_EXTERN const NSString *const kRTCL16CodecName;
RTC_EXTERN const NSString *const kRTCG722CodecName;
RTC_EXTERN const NSString *const kRTCIlbcCodecName;
RTC_EXTERN const NSString *const kRTCPcmuCodecName;
RTC_EXTERN const NSString *const kRTCPcmaCodecName;
RTC_EXTERN const NSString *const kRTCDtmfCodecName;
RTC_EXTERN const NSString *const kRTCComfortNoiseCodecName;
RTC_EXTERN const NSString *const kRTCVp8CodecName;
RTC_EXTERN const NSString *const kRTCVp9CodecName;
RTC_EXTERN const NSString *const kRTCH264CodecName;
/** Defined in https://www.w3.org/TR/webrtc/#idl-def-rtcrtpcodecparameters */
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCRtpCodecParameters) : NSObject
/** The RTP payload type. */
@property(nonatomic, assign) int payloadType;
/**
* The codec MIME subtype. Valid types are listed in:
* http://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml#rtp-parameters-2
*
* Several supported types are represented by the constants above.
*/
@property(nonatomic, readonly, nonnull) NSString *name;
/**
* The media type of this codec. Equivalent to MIME top-level type.
*
* Valid values are kRTCMediaStreamTrackKindAudio and
* kRTCMediaStreamTrackKindVideo.
*/
@property(nonatomic, readonly, nonnull) NSString *kind;
/** The codec clock rate expressed in Hertz. */
@property(nonatomic, readonly, nullable) NSNumber *clockRate;
/**
* The number of channels (mono=1, stereo=2).
* Set to null for video codecs.
**/
@property(nonatomic, readonly, nullable) NSNumber *numChannels;
/** The "format specific parameters" field from the "a=fmtp" line in the SDP */
@property(nonatomic, readonly, nonnull) NSDictionary *parameters;
- (instancetype)init;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,76 @@
/*
* Copyright 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
/** Corresponds to webrtc::Priority. */
typedef NS_ENUM(NSInteger, RTCPriority) {
RTCPriorityVeryLow,
RTCPriorityLow,
RTCPriorityMedium,
RTCPriorityHigh
};
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCRtpEncodingParameters) : NSObject
/** The idenfifier for the encoding layer. This is used in simulcast. */
@property(nonatomic, copy, nullable) NSString *rid;
/** Controls whether the encoding is currently transmitted. */
@property(nonatomic, assign) BOOL isActive;
/** The maximum bitrate to use for the encoding, or nil if there is no
* limit.
*/
@property(nonatomic, copy, nullable) NSNumber *maxBitrateBps;
/** The minimum bitrate to use for the encoding, or nil if there is no
* limit.
*/
@property(nonatomic, copy, nullable) NSNumber *minBitrateBps;
/** The maximum framerate to use for the encoding, or nil if there is no
* limit.
*/
@property(nonatomic, copy, nullable) NSNumber *maxFramerate;
/** The requested number of temporal layers to use for the encoding, or nil
* if the default should be used.
*/
@property(nonatomic, copy, nullable) NSNumber *numTemporalLayers;
/** Scale the width and height down by this factor for video. If nil,
* implementation default scaling factor will be used.
*/
@property(nonatomic, copy, nullable) NSNumber *scaleResolutionDownBy;
/** The SSRC being used by this encoding. */
@property(nonatomic, readonly, nullable) NSNumber *ssrc;
/** The relative bitrate priority. */
@property(nonatomic, assign) double bitratePriority;
/** The relative DiffServ Code Point priority. */
@property(nonatomic, assign) RTCPriority networkPriority;
/** Allow dynamic frame length changes for audio:
https://w3c.github.io/webrtc-extensions/#dom-rtcrtpencodingparameters-adaptiveptime */
@property(nonatomic, assign) BOOL adaptiveAudioPacketTime;
- (instancetype)init;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,33 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
NS_ASSUME_NONNULL_BEGIN
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCRtpHeaderExtension) : NSObject
/** The URI of the RTP header extension, as defined in RFC5285. */
@property(nonatomic, readonly, copy) NSString *uri;
/** The value put in the RTP packet to identify the header extension. */
@property(nonatomic, readonly) int id;
/** Whether the header extension is encrypted or not. */
@property(nonatomic, readonly, getter=isEncrypted) BOOL encrypted;
- (instancetype)init;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,58 @@
/*
* Copyright 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <WebRTC/RTCMacros.h>
#import <WebRTC/RTCRtcpParameters.h>
#import <WebRTC/RTCRtpCodecParameters.h>
#import <WebRTC/RTCRtpEncodingParameters.h>
#import <WebRTC/RTCRtpHeaderExtension.h>
NS_ASSUME_NONNULL_BEGIN
/** Corresponds to webrtc::DegradationPreference. */
typedef NS_ENUM(NSInteger, RTCDegradationPreference) {
RTCDegradationPreferenceDisabled,
RTCDegradationPreferenceMaintainFramerate,
RTCDegradationPreferenceMaintainResolution,
RTCDegradationPreferenceBalanced
};
RTC_OBJC_EXPORT
@interface RTC_OBJC_TYPE (RTCRtpParameters) : NSObject
/** A unique identifier for the last set of parameters applied. */
@property(nonatomic, copy) NSString *transactionId;
/** Parameters used for RTCP. */
@property(nonatomic, readonly, copy) RTC_OBJC_TYPE(RTCRtcpParameters) * rtcp;
/** An array containing parameters for RTP header extensions. */
@property(nonatomic, readonly, copy)
NSArray<RTC_OBJC_TYPE(RTCRtpHeaderExtension) *> *headerExtensions;
/** The currently active encodings in the order of preference. */
@property(nonatomic, copy) NSArray<RTC_OBJC_TYPE(RTCRtpEncodingParameters) *> *encodings;
/** The negotiated set of send codecs in order of preference. */
@property(nonatomic, copy) NSArray<RTC_OBJC_TYPE(RTCRtpCodecParameters) *> *codecs;
/**
* Degradation preference in case of CPU adaptation or constrained bandwidth.
* If nil, implementation default degradation preference will be used.
*/
@property(nonatomic, copy, nullable) NSNumber *degradationPreference;
- (instancetype)init;
@end
NS_ASSUME_NONNULL_END

Some files were not shown because too many files have changed in this diff Show more