Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6139af3394 | |||
| b034739065 | |||
| e410ed0cbc | |||
| dfee0e0e29 | |||
| 6129b57d39 | |||
| 0ac904cd51 | |||
| 9b675a8f92 | |||
| 399e1bfec2 | |||
| ec892ae746 | |||
| 3bd7b595fb | |||
| 3d8c83c720 | |||
| 466e70236c | |||
| 0fba2a6954 | |||
| 8afe1fe943 | |||
| fa7308fdd9 | |||
| f7568b6c16 | |||
| 12d7ba2960 | |||
| 0325de208a | |||
| bb1fa6fa5c | |||
| e3bb33873d | |||
| 4eb08279ac | |||
| eb70823f96 | |||
| e92ab66220 | |||
| c265763d25 | |||
| 3f31c97fc9 | |||
| 609f1653a4 | |||
| 07babd6e36 | |||
| 8ed72c71c4 | |||
| 05cd85c479 | |||
| d8009d69dd | |||
| 9173fc5297 | |||
| bc4d6aa47a | |||
| 64e0b73c3a | |||
| a35be9ee2d | |||
| f10f6928a3 | |||
| 380f79053e | |||
| 3197a6dc30 | |||
| a5f51af7eb | |||
| 3a5a357834 | |||
| 2f80f8dce2 | |||
| 2fa31da639 | |||
| d137dabe69 |
+3
-5
@@ -2,14 +2,12 @@ reporter: "xcode"
|
||||
|
||||
included:
|
||||
- ../Sources/
|
||||
- Example/Tests/
|
||||
|
||||
disabled_rules:
|
||||
- cyclomatic_complexity
|
||||
- identifier_name
|
||||
- file_length
|
||||
- line_length
|
||||
- nesting
|
||||
- unused_optional_binding
|
||||
- variable_name
|
||||
|
||||
# Specialized Rules
|
||||
file_length:
|
||||
- 500
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
31A1A1D27EA05F1E28033516 /* Pods-Example-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-Tests.release.xcconfig"; path = "Target Support Files/Pods-Example-Tests/Pods-Example-Tests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
3207656F9030B2912198AF2E /* Pods_Example_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
37940350BF612EEBD59D5DF4 /* Pods_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
55EC364A1E6BB98A00726F13 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = ../../Siren/Info.plist; sourceTree = "<group>"; };
|
||||
5A65216266BE44478A3B3AEB /* Pods-Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.debug.xcconfig"; path = "Target Support Files/Pods-Tests/Pods-Tests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
740DAA3321466F1ABE6CC37D /* Pods-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.debug.xcconfig"; path = "Target Support Files/Pods-Example/Pods-Example.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
8E3A6C041D07CB6F00A8B7CF /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@@ -121,7 +120,6 @@
|
||||
8EACA96B1F37F2D3003134CA /* Images.xcassets */,
|
||||
8EACA96C1F37F2D3003134CA /* Info.plist */,
|
||||
8EACA96D1F37F2D3003134CA /* ViewController.swift */,
|
||||
55EC364A1E6BB98A00726F13 /* Info.plist */,
|
||||
);
|
||||
path = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
@@ -428,7 +426,7 @@
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
INFOPLIST_FILE = Tests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.sabintsev.SirenTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@@ -448,7 +446,7 @@
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
INFOPLIST_FILE = Tests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.sabintsev.SirenTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@@ -505,7 +503,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
@@ -554,7 +552,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_VERSION = 4.2;
|
||||
@@ -570,8 +568,9 @@
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
DEVELOPMENT_TEAM = HT94948NDD;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/Example/Supporting Files/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
MARKETING_VERSION = 2.0.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.facebook.Facebook;
|
||||
PRODUCT_NAME = Example;
|
||||
SWIFT_VERSION = 5.0;
|
||||
@@ -587,8 +586,9 @@
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
DEVELOPMENT_TEAM = HT94948NDD;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/Example/Supporting Files/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
MARKETING_VERSION = 2.0.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.facebook.Facebook;
|
||||
PRODUCT_NAME = Example;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
|
||||
@@ -21,4 +21,3 @@ class ViewController: UIViewController {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
platform :ios, '11.0'
|
||||
platform :ios, '15.0'
|
||||
inhibit_all_warnings!
|
||||
use_frameworks!
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
PODS:
|
||||
- Siren (5.6.0)
|
||||
- Siren (6.0.2)
|
||||
|
||||
DEPENDENCIES:
|
||||
- Siren (from `../`)
|
||||
@@ -9,8 +9,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Siren: 600a3e991f8ff2ade8376ff2d10b287b9ff2df51
|
||||
Siren: 1be92ef5775f9b61ebb294c79c59268ab0afcf5d
|
||||
|
||||
PODFILE CHECKSUM: 1b0b20618a6fdca0d708c439075d1f6313cc3ff0
|
||||
PODFILE CHECKSUM: 5800641824958ea506d6ae52e89b594fe8270c18
|
||||
|
||||
COCOAPODS: 1.7.5
|
||||
COCOAPODS: 1.11.2
|
||||
|
||||
+6
-5
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Siren",
|
||||
"version": "5.6.0",
|
||||
"swift_versions": "5.3",
|
||||
"version": "6.0.2",
|
||||
"swift_versions": "5.5",
|
||||
"summary": "Notify users that a new version of your iOS app is available, and prompt them with the App Store link.",
|
||||
"homepage": "https://github.com/ArtSabintsev/Siren",
|
||||
"license": "MIT",
|
||||
@@ -10,14 +10,15 @@
|
||||
},
|
||||
"description": "Notify your users when a new version of your iOS app is available, and prompt them with the App Store link.",
|
||||
"platforms": {
|
||||
"ios": "11.0"
|
||||
"ios": "15.0",
|
||||
"tvos": "15.0"
|
||||
},
|
||||
"source": {
|
||||
"git": "https://github.com/ArtSabintsev/Siren.git",
|
||||
"tag": "5.6.0"
|
||||
"tag": "6.0.2"
|
||||
},
|
||||
"source_files": "Sources/**/*.swift",
|
||||
"resources": "Sources/Siren.bundle",
|
||||
"requires_arc": true,
|
||||
"swift_version": "5.3"
|
||||
"swift_version": "5.5"
|
||||
}
|
||||
|
||||
Generated
+4
-4
@@ -1,5 +1,5 @@
|
||||
PODS:
|
||||
- Siren (5.6.0)
|
||||
- Siren (6.0.2)
|
||||
|
||||
DEPENDENCIES:
|
||||
- Siren (from `../`)
|
||||
@@ -9,8 +9,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Siren: 600a3e991f8ff2ade8376ff2d10b287b9ff2df51
|
||||
Siren: 1be92ef5775f9b61ebb294c79c59268ab0afcf5d
|
||||
|
||||
PODFILE CHECKSUM: 1b0b20618a6fdca0d708c439075d1f6313cc3ff0
|
||||
PODFILE CHECKSUM: 5800641824958ea506d6ae52e89b594fe8270c18
|
||||
|
||||
COCOAPODS: 1.7.5
|
||||
COCOAPODS: 1.11.2
|
||||
|
||||
+445
-444
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1220"
|
||||
LastUpgradeVersion = "1340"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1220"
|
||||
LastUpgradeVersion = "1340"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1220"
|
||||
LastUpgradeVersion = "1340"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
+58
-43
@@ -19,9 +19,8 @@ mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
|
||||
COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
|
||||
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
|
||||
BCSYMBOLMAP_DIR="BCSymbolMaps"
|
||||
|
||||
# Used as a return value for each invocation of `strip_invalid_archs` function.
|
||||
STRIP_BINARY_RETVAL=0
|
||||
|
||||
# This protects against multiple targets copying the same framework dependency at the same time. The solution
|
||||
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
|
||||
@@ -45,9 +44,19 @@ install_framework()
|
||||
source="$(readlink "${source}")"
|
||||
fi
|
||||
|
||||
if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then
|
||||
# Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied
|
||||
find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do
|
||||
echo "Installing $f"
|
||||
install_bcsymbolmap "$f" "$destination"
|
||||
rm "$f"
|
||||
done
|
||||
rmdir "${source}/${BCSYMBOLMAP_DIR}"
|
||||
fi
|
||||
|
||||
# Use filter instead of exclude so missing patterns don't throw errors.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
|
||||
|
||||
local basename
|
||||
basename="$(basename -s .framework "$1")"
|
||||
@@ -80,35 +89,69 @@ install_framework()
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
# Copies and strips a vendored dSYM
|
||||
install_dsym() {
|
||||
local source="$1"
|
||||
warn_missing_arch=${2:-true}
|
||||
if [ -r "$source" ]; then
|
||||
# Copy the dSYM into a the targets temp dir.
|
||||
# Copy the dSYM into the targets temp dir.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
|
||||
|
||||
local basename
|
||||
basename="$(basename -s .framework.dSYM "$source")"
|
||||
binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}"
|
||||
basename="$(basename -s .dSYM "$source")"
|
||||
binary_name="$(ls "$source/Contents/Resources/DWARF")"
|
||||
binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}"
|
||||
|
||||
# Strip invalid architectures so "fat" simulator / device frameworks work on device
|
||||
# Strip invalid architectures from the dSYM.
|
||||
if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then
|
||||
strip_invalid_archs "$binary"
|
||||
strip_invalid_archs "$binary" "$warn_missing_arch"
|
||||
fi
|
||||
|
||||
if [[ $STRIP_BINARY_RETVAL == 1 ]]; then
|
||||
if [[ $STRIP_BINARY_RETVAL == 0 ]]; then
|
||||
# Move the stripped file into its final destination.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
|
||||
else
|
||||
# The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
|
||||
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM"
|
||||
mkdir -p "${DWARF_DSYM_FOLDER_PATH}"
|
||||
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Used as a return value for each invocation of `strip_invalid_archs` function.
|
||||
STRIP_BINARY_RETVAL=0
|
||||
|
||||
# Strip invalid architectures
|
||||
strip_invalid_archs() {
|
||||
binary="$1"
|
||||
warn_missing_arch=${2:-true}
|
||||
# Get architectures for current target binary
|
||||
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
|
||||
# Intersect them with the architectures we are building for
|
||||
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
|
||||
# If there are no archs supported by this binary then warn the user
|
||||
if [[ -z "$intersected_archs" ]]; then
|
||||
if [[ "$warn_missing_arch" == "true" ]]; then
|
||||
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
|
||||
fi
|
||||
STRIP_BINARY_RETVAL=1
|
||||
return
|
||||
fi
|
||||
stripped=""
|
||||
for arch in $binary_archs; do
|
||||
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
|
||||
# Strip non-valid architectures in-place
|
||||
lipo -remove "$arch" -output "$binary" "$binary"
|
||||
stripped="$stripped $arch"
|
||||
fi
|
||||
done
|
||||
if [[ "$stripped" ]]; then
|
||||
echo "Stripped $binary of architectures:$stripped"
|
||||
fi
|
||||
STRIP_BINARY_RETVAL=0
|
||||
}
|
||||
|
||||
# Copies the bcsymbolmap files of a vendored framework
|
||||
install_bcsymbolmap() {
|
||||
local bcsymbolmap_path="$1"
|
||||
@@ -132,34 +175,6 @@ code_sign_if_enabled() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Strip invalid architectures
|
||||
strip_invalid_archs() {
|
||||
binary="$1"
|
||||
# Get architectures for current target binary
|
||||
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
|
||||
# Intersect them with the architectures we are building for
|
||||
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
|
||||
# If there are no archs supported by this binary then warn the user
|
||||
if [[ -z "$intersected_archs" ]]; then
|
||||
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
|
||||
STRIP_BINARY_RETVAL=0
|
||||
return
|
||||
fi
|
||||
stripped=""
|
||||
for arch in $binary_archs; do
|
||||
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
|
||||
# Strip non-valid architectures in-place
|
||||
lipo -remove "$arch" -output "$binary" "$binary"
|
||||
stripped="$stripped $arch"
|
||||
fi
|
||||
done
|
||||
if [[ "$stripped" ]]; then
|
||||
echo "Stripped $binary of architectures:$stripped"
|
||||
fi
|
||||
STRIP_BINARY_RETVAL=1
|
||||
}
|
||||
|
||||
|
||||
if [[ "$CONFIGURATION" == "Debug" ]]; then
|
||||
install_framework "${BUILT_PRODUCTS_DIR}/Siren/Siren.framework"
|
||||
fi
|
||||
|
||||
+5
-1
@@ -1,8 +1,10 @@
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Siren"
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Siren/Siren.framework/Headers"
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift "$(PLATFORM_DIR)/Developer/Library/Frameworks" '@executable_path/Frameworks' '@loader_path/Frameworks'
|
||||
LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
|
||||
OTHER_CFLAGS = $(inherited) -isystem "${PODS_CONFIGURATION_BUILD_DIR}/Siren/Siren.framework/Headers" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/Siren"
|
||||
OTHER_LDFLAGS = $(inherited) -framework "Siren"
|
||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
||||
@@ -10,3 +12,5 @@ PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
|
||||
+5
-1
@@ -1,8 +1,10 @@
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Siren"
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Siren/Siren.framework/Headers"
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift "$(PLATFORM_DIR)/Developer/Library/Frameworks" '@executable_path/Frameworks' '@loader_path/Frameworks'
|
||||
LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
|
||||
OTHER_CFLAGS = $(inherited) -isystem "${PODS_CONFIGURATION_BUILD_DIR}/Siren/Siren.framework/Headers" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/Siren"
|
||||
OTHER_LDFLAGS = $(inherited) -framework "Siren"
|
||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
||||
@@ -10,3 +12,5 @@ PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
|
||||
+58
-43
@@ -19,9 +19,8 @@ mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
|
||||
COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
|
||||
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
|
||||
BCSYMBOLMAP_DIR="BCSymbolMaps"
|
||||
|
||||
# Used as a return value for each invocation of `strip_invalid_archs` function.
|
||||
STRIP_BINARY_RETVAL=0
|
||||
|
||||
# This protects against multiple targets copying the same framework dependency at the same time. The solution
|
||||
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
|
||||
@@ -45,9 +44,19 @@ install_framework()
|
||||
source="$(readlink "${source}")"
|
||||
fi
|
||||
|
||||
if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then
|
||||
# Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied
|
||||
find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do
|
||||
echo "Installing $f"
|
||||
install_bcsymbolmap "$f" "$destination"
|
||||
rm "$f"
|
||||
done
|
||||
rmdir "${source}/${BCSYMBOLMAP_DIR}"
|
||||
fi
|
||||
|
||||
# Use filter instead of exclude so missing patterns don't throw errors.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
|
||||
|
||||
local basename
|
||||
basename="$(basename -s .framework "$1")"
|
||||
@@ -80,35 +89,69 @@ install_framework()
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
# Copies and strips a vendored dSYM
|
||||
install_dsym() {
|
||||
local source="$1"
|
||||
warn_missing_arch=${2:-true}
|
||||
if [ -r "$source" ]; then
|
||||
# Copy the dSYM into a the targets temp dir.
|
||||
# Copy the dSYM into the targets temp dir.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
|
||||
|
||||
local basename
|
||||
basename="$(basename -s .framework.dSYM "$source")"
|
||||
binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}"
|
||||
basename="$(basename -s .dSYM "$source")"
|
||||
binary_name="$(ls "$source/Contents/Resources/DWARF")"
|
||||
binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}"
|
||||
|
||||
# Strip invalid architectures so "fat" simulator / device frameworks work on device
|
||||
# Strip invalid architectures from the dSYM.
|
||||
if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then
|
||||
strip_invalid_archs "$binary"
|
||||
strip_invalid_archs "$binary" "$warn_missing_arch"
|
||||
fi
|
||||
|
||||
if [[ $STRIP_BINARY_RETVAL == 1 ]]; then
|
||||
if [[ $STRIP_BINARY_RETVAL == 0 ]]; then
|
||||
# Move the stripped file into its final destination.
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
|
||||
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
|
||||
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
|
||||
else
|
||||
# The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
|
||||
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM"
|
||||
mkdir -p "${DWARF_DSYM_FOLDER_PATH}"
|
||||
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Used as a return value for each invocation of `strip_invalid_archs` function.
|
||||
STRIP_BINARY_RETVAL=0
|
||||
|
||||
# Strip invalid architectures
|
||||
strip_invalid_archs() {
|
||||
binary="$1"
|
||||
warn_missing_arch=${2:-true}
|
||||
# Get architectures for current target binary
|
||||
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
|
||||
# Intersect them with the architectures we are building for
|
||||
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
|
||||
# If there are no archs supported by this binary then warn the user
|
||||
if [[ -z "$intersected_archs" ]]; then
|
||||
if [[ "$warn_missing_arch" == "true" ]]; then
|
||||
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
|
||||
fi
|
||||
STRIP_BINARY_RETVAL=1
|
||||
return
|
||||
fi
|
||||
stripped=""
|
||||
for arch in $binary_archs; do
|
||||
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
|
||||
# Strip non-valid architectures in-place
|
||||
lipo -remove "$arch" -output "$binary" "$binary"
|
||||
stripped="$stripped $arch"
|
||||
fi
|
||||
done
|
||||
if [[ "$stripped" ]]; then
|
||||
echo "Stripped $binary of architectures:$stripped"
|
||||
fi
|
||||
STRIP_BINARY_RETVAL=0
|
||||
}
|
||||
|
||||
# Copies the bcsymbolmap files of a vendored framework
|
||||
install_bcsymbolmap() {
|
||||
local bcsymbolmap_path="$1"
|
||||
@@ -132,34 +175,6 @@ code_sign_if_enabled() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Strip invalid architectures
|
||||
strip_invalid_archs() {
|
||||
binary="$1"
|
||||
# Get architectures for current target binary
|
||||
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
|
||||
# Intersect them with the architectures we are building for
|
||||
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
|
||||
# If there are no archs supported by this binary then warn the user
|
||||
if [[ -z "$intersected_archs" ]]; then
|
||||
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
|
||||
STRIP_BINARY_RETVAL=0
|
||||
return
|
||||
fi
|
||||
stripped=""
|
||||
for arch in $binary_archs; do
|
||||
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
|
||||
# Strip non-valid architectures in-place
|
||||
lipo -remove "$arch" -output "$binary" "$binary"
|
||||
stripped="$stripped $arch"
|
||||
fi
|
||||
done
|
||||
if [[ "$stripped" ]]; then
|
||||
echo "Stripped $binary of architectures:$stripped"
|
||||
fi
|
||||
STRIP_BINARY_RETVAL=1
|
||||
}
|
||||
|
||||
|
||||
if [[ "$CONFIGURATION" == "Debug" ]]; then
|
||||
install_framework "${BUILT_PRODUCTS_DIR}/Siren/Siren.framework"
|
||||
fi
|
||||
|
||||
+5
-1
@@ -1,8 +1,10 @@
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Siren"
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Siren/Siren.framework/Headers"
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks'
|
||||
LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
|
||||
OTHER_CFLAGS = $(inherited) -isystem "${PODS_CONFIGURATION_BUILD_DIR}/Siren/Siren.framework/Headers" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/Siren"
|
||||
OTHER_LDFLAGS = $(inherited) -framework "Siren"
|
||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
||||
@@ -10,3 +12,5 @@ PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
|
||||
+5
-1
@@ -1,8 +1,10 @@
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Siren"
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Siren/Siren.framework/Headers"
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks'
|
||||
LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
|
||||
OTHER_CFLAGS = $(inherited) -isystem "${PODS_CONFIGURATION_BUILD_DIR}/Siren/Siren.framework/Headers" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/Siren"
|
||||
OTHER_LDFLAGS = $(inherited) -framework "Siren"
|
||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
|
||||
@@ -10,3 +12,5 @@ PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>5.6.0</string>
|
||||
<string>6.0.2</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Siren
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
|
||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -suppress-warnings
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_ROOT = ${SRCROOT}
|
||||
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||
SKIP_INSTALL = YES
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
@@ -0,0 +1,13 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Siren
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
|
||||
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -suppress-warnings
|
||||
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||
PODS_ROOT = ${SRCROOT}
|
||||
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
|
||||
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||
SKIP_INSTALL = YES
|
||||
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||
@@ -18,11 +18,9 @@ final class SirenTests: XCTestCase {
|
||||
// MARK: - API
|
||||
|
||||
extension SirenTests {
|
||||
|
||||
func testAPIDefaultsToUnitedStatesAppStore() {
|
||||
XCTAssertEqual(siren.apiManager.country, AppStoreCountry.unitedStates)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Updates
|
||||
@@ -230,7 +228,7 @@ extension SirenTests {
|
||||
let language: Localization.Language = .croatian
|
||||
|
||||
// Update Available
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Nova ažuriranje je stigla")
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Novo ažuriranje je dostupno")
|
||||
|
||||
// Next time
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Sljedeći put")
|
||||
@@ -353,19 +351,19 @@ extension SirenTests {
|
||||
// Update
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Update")
|
||||
}
|
||||
|
||||
|
||||
func testGreekLocalization() {
|
||||
let language: Localization.Language = .greek
|
||||
|
||||
// Update Available
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Διαθέσιμη Ενημέρωση")
|
||||
|
||||
|
||||
// Next time
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Άλλη φορά")
|
||||
|
||||
|
||||
// Skip this version
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Αγνόησε αυτήν την έκδοση")
|
||||
|
||||
|
||||
// Update
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Αναβάθμιση")
|
||||
}
|
||||
@@ -535,49 +533,49 @@ extension SirenTests {
|
||||
|
||||
// Update Available
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "بروزرسانی در دسترس")
|
||||
|
||||
|
||||
// Next time
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "دفعه بعد")
|
||||
|
||||
|
||||
// Skip this version
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "رد این نسخه")
|
||||
|
||||
|
||||
// Update
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "بروزرسانی")
|
||||
}
|
||||
|
||||
|
||||
func testPersianAfghanistanLocalization() {
|
||||
let language: Localization.Language = .persianAfghanistan
|
||||
|
||||
|
||||
// Update Available
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "بروزرسانی در دسترس")
|
||||
|
||||
|
||||
// Next time
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "دگر بار")
|
||||
|
||||
|
||||
// Skip this version
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "رد این نسخه")
|
||||
|
||||
|
||||
// Update
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "بروزرسانی")
|
||||
}
|
||||
|
||||
|
||||
func testPersianIranLocalization() {
|
||||
let language: Localization.Language = .persianIran
|
||||
|
||||
// Update Available
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "بروزرسانی در دسترس")
|
||||
|
||||
|
||||
// Next time
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "دفعه بعد")
|
||||
|
||||
|
||||
// Skip this version
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "رد این نسخه")
|
||||
|
||||
|
||||
// Update
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "بروزرسانی")
|
||||
}
|
||||
|
||||
|
||||
func testPolishLocalization() {
|
||||
let language: Localization.Language = .polish
|
||||
|
||||
@@ -775,17 +773,17 @@ extension SirenTests {
|
||||
|
||||
// Update Available
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Доступне Оновлення")
|
||||
|
||||
|
||||
// Next time
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Наступного разу")
|
||||
|
||||
|
||||
// Skip this version
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Пропустити версію")
|
||||
|
||||
|
||||
// Update
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Оновити")
|
||||
}
|
||||
|
||||
|
||||
func testUrduLocalization() {
|
||||
let language: Localization.Language = .urdu
|
||||
|
||||
@@ -801,7 +799,7 @@ extension SirenTests {
|
||||
// Update
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "اپڈیٹ کریں")
|
||||
}
|
||||
|
||||
|
||||
func testVietnameseLocalization() {
|
||||
let language: Localization.Language = .vietnamese
|
||||
|
||||
@@ -817,5 +815,5 @@ extension SirenTests {
|
||||
// Update
|
||||
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Cập nhật")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
CFPropertyList (3.0.2)
|
||||
activesupport (5.2.4.4)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
addressable (2.7.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
algoliasearch (1.27.5)
|
||||
httpclient (~> 2.8, >= 2.8.3)
|
||||
json (>= 1.5.1)
|
||||
atomos (0.1.3)
|
||||
claide (1.0.3)
|
||||
cocoapods (1.10.0)
|
||||
addressable (~> 2.6)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
cocoapods-core (= 1.10.0)
|
||||
cocoapods-deintegrate (>= 1.0.3, < 2.0)
|
||||
cocoapods-downloader (>= 1.4.0, < 2.0)
|
||||
cocoapods-plugins (>= 1.0.0, < 2.0)
|
||||
cocoapods-search (>= 1.0.0, < 2.0)
|
||||
cocoapods-trunk (>= 1.4.0, < 2.0)
|
||||
cocoapods-try (>= 1.1.0, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
escape (~> 0.0.4)
|
||||
fourflusher (>= 2.3.0, < 3.0)
|
||||
gh_inspector (~> 1.0)
|
||||
molinillo (~> 0.6.6)
|
||||
nap (~> 1.0)
|
||||
ruby-macho (~> 1.4)
|
||||
xcodeproj (>= 1.19.0, < 2.0)
|
||||
cocoapods-core (1.10.0)
|
||||
activesupport (> 5.0, < 6)
|
||||
addressable (~> 2.6)
|
||||
algoliasearch (~> 1.0)
|
||||
concurrent-ruby (~> 1.1)
|
||||
fuzzy_match (~> 2.0.4)
|
||||
nap (~> 1.0)
|
||||
netrc (~> 0.11)
|
||||
public_suffix
|
||||
typhoeus (~> 1.0)
|
||||
cocoapods-deintegrate (1.0.4)
|
||||
cocoapods-downloader (1.4.0)
|
||||
cocoapods-plugins (1.0.0)
|
||||
nap
|
||||
cocoapods-search (1.0.0)
|
||||
cocoapods-trunk (1.5.0)
|
||||
nap (>= 0.8, < 2.0)
|
||||
netrc (~> 0.11)
|
||||
cocoapods-try (1.2.0)
|
||||
colored2 (3.1.2)
|
||||
concurrent-ruby (1.1.7)
|
||||
escape (0.0.4)
|
||||
ethon (0.12.0)
|
||||
ffi (>= 1.3.0)
|
||||
ffi (1.13.1)
|
||||
fourflusher (2.3.1)
|
||||
fuzzy_match (2.0.4)
|
||||
gh_inspector (1.1.3)
|
||||
httpclient (2.8.3)
|
||||
i18n (1.8.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
json (2.3.1)
|
||||
minitest (5.14.2)
|
||||
molinillo (0.6.6)
|
||||
nanaimo (0.3.0)
|
||||
nap (1.1.0)
|
||||
netrc (0.11.0)
|
||||
public_suffix (4.0.6)
|
||||
ruby-macho (1.4.0)
|
||||
thread_safe (0.3.6)
|
||||
typhoeus (1.4.0)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (1.2.8)
|
||||
thread_safe (~> 0.1)
|
||||
xcodeproj (1.19.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
atomos (~> 0.1.3)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
nanaimo (~> 0.3.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
cocoapods
|
||||
|
||||
BUNDLED WITH
|
||||
2.1.4
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
// swift-tools-version:5.3
|
||||
// swift-tools-version:5.5
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "Siren",
|
||||
platforms: [.iOS(.v11), .tvOS(.v11)],
|
||||
platforms: [.iOS(.v13), .tvOS(.v13)],
|
||||
products: [.library(name: "Siren", targets: ["Siren"])],
|
||||
targets: [.target(name: "Siren", path: "Sources", resources: [.copy("Siren.bundle")])],
|
||||
targets: [.target(name: "Siren", path: "Sources", resources: [.copy("Siren.bundle"), .copy("PrivacyInfo.xcprivacy")])],
|
||||
swiftLanguageVersions: [.v5]
|
||||
)
|
||||
|
||||
@@ -2,7 +2,13 @@
|
||||
|
||||
### Notify users when a new version of your app is available and prompt them to upgrade.
|
||||
|
||||
[](https://travis-ci.org/ArtSabintsev/Siren)  [](https://cocoapods.org/pods/Siren) [](https://swift.org/package-manager/) [](https://github.com/JamitLabs/Accio)
|
||||
 [](https://cocoapods.org/pods/Siren) [](https://swift.org/package-manager/) [](https://github.com/JamitLabs/Accio)
|
||||
|
||||
---
|
||||
|
||||
# Important Information
|
||||
|
||||
I stopped being a proactive iOS engineer in 2021. For the time being, I will keep this library maintained for the community, but I will not be proactively adding features.
|
||||
|
||||
---
|
||||
|
||||
@@ -44,6 +50,7 @@ Siren is built to work with the [**Semantic Versioning**](https://semver.org/) s
|
||||
## Features
|
||||
|
||||
### Current Features
|
||||
- [x] Compatible with iOS 13+ and tvOS 13+
|
||||
- [x] CocoaPods and Swift Package Manager Support (see [Installation Instructions](https://github.com/ArtSabintsev/Siren#installation-instructions))
|
||||
- [x] Three Types of Alerts (see [Screenshots](https://github.com/ArtSabintsev/Siren#screenshots))
|
||||
- [x] Highly Customizable Presentation Rules (see [Implementation Examples](https://github.com/ArtSabintsev/Siren#implementation-examples))
|
||||
@@ -80,7 +87,8 @@ Siren is built to work with the [**Semantic Versioning**](https://semver.org/) s
|
||||
|
||||
| Swift Version | Branch Name | Will Continue to Receive Updates?
|
||||
| ------------- | ------------- | -------------
|
||||
| 5.1+ | master | **Yes**
|
||||
| 5.5+ | master | **Yes**
|
||||
| 5.1-5.4 | swift5.4 | No
|
||||
| 5.0 | swift5.0 | No
|
||||
| 4.2 | swift4.2 | No
|
||||
| 4.1 | swift4.1 | No
|
||||
@@ -90,7 +98,8 @@ Siren is built to work with the [**Semantic Versioning**](https://semver.org/) s
|
||||
|
||||
### CocoaPods
|
||||
```ruby
|
||||
pod 'Siren' # Swift 5.1+
|
||||
pod 'Siren' # Swift 5.5+
|
||||
pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'swift5.4' # Swift 5.1-5.4
|
||||
pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'swift5.0' # Swift 5.0
|
||||
pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'swift4.2' # Swift 4.2
|
||||
pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'swift4.1' # Swift 4.1
|
||||
@@ -101,7 +110,7 @@ pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'sw
|
||||
|
||||
### Swift Package Manager
|
||||
```swift
|
||||
.Package(url: "https://github.com/ArtSabintsev/Siren.git", majorVersion: 5)
|
||||
.Package(url: "https://github.com/ArtSabintsev/Siren.git", majorVersion: 6)
|
||||
```
|
||||
|
||||
## Implementation Examples
|
||||
|
||||
+8
-7
@@ -1,7 +1,7 @@
|
||||
Pod::Spec.new do |s|
|
||||
# Version
|
||||
s.version = "5.7.0"
|
||||
s.swift_version = "5.3"
|
||||
s.version = "6.1.3"
|
||||
s.swift_version = "5.5"
|
||||
|
||||
# Meta
|
||||
s.name = "Siren"
|
||||
@@ -14,9 +14,10 @@ Pod::Spec.new do |s|
|
||||
DESC
|
||||
|
||||
# Compatibility & Sources
|
||||
s.platform = :ios, "11.0"
|
||||
s.source = { :git => "https://github.com/ArtSabintsev/Siren.git", :tag => s.version.to_s }
|
||||
s.source_files = 'Sources/**/*.swift'
|
||||
s.resources = 'Sources/Siren.bundle'
|
||||
s.requires_arc = true
|
||||
s.ios.deployment_target = '13.0'
|
||||
s.tvos.deployment_target = '13.0'
|
||||
s.source = { :git => "https://github.com/ArtSabintsev/Siren.git", :tag => s.version.to_s }
|
||||
s.source_files = 'Sources/**/*.swift'
|
||||
s.resources = 'Sources/Siren.bundle'
|
||||
s.requires_arc = true
|
||||
end
|
||||
|
||||
@@ -83,11 +83,10 @@ private extension Bundle {
|
||||
/// - Returns: The bundle's path or `nil`.
|
||||
final class func sirenBundlePath() -> String? {
|
||||
#if SWIFT_PACKAGE
|
||||
let resourceBundle = Bundle.module
|
||||
return resourceBundle.path(forResource: "\(Siren.self)", ofType: Constants.bundleExtension)
|
||||
#endif
|
||||
|
||||
return Bundle.module.path(forResource: "\(Siren.self)", ofType: Constants.bundleExtension)
|
||||
#else
|
||||
return Bundle(for: Siren.self).path(forResource: "\(Siren.self)", ofType: Constants.bundleExtension)
|
||||
#endif
|
||||
}
|
||||
|
||||
/// The path for a particular language localizationin Siren's localization `Bundle`.
|
||||
|
||||
@@ -16,19 +16,36 @@ public struct APIManager {
|
||||
static let bundleID = "bundleId"
|
||||
/// Constant for the `country` parameter in the iTunes Lookup API request.
|
||||
static let country = "country"
|
||||
/// Constant for the `lang` parameter in the iTunes Lookup API request.
|
||||
static let language = "lang"
|
||||
/// Constant for the `entity` parameter in the iTunes Lookup API reqeust.
|
||||
static let entity = "entity"
|
||||
/// Constant for the `entity` parameter value when performing a tvOS iTunes Lookup API reqeust.
|
||||
static let tvSoftware = "tvSoftware"
|
||||
}
|
||||
|
||||
/// Return results or errors obtained from performing a version check with Siren.
|
||||
typealias CompletionHandler = (Result<APIModel, KnownError>) -> Void
|
||||
|
||||
/// The Bundle ID for the your application. Defaults to "Bundle.main.bundleIdentifier".
|
||||
let bundleID: String?
|
||||
|
||||
/// The region or country of an App Store in which the app is available.
|
||||
let country: AppStoreCountry
|
||||
|
||||
/// The language for the localization of App Store responses.
|
||||
let language: String?
|
||||
|
||||
/// Initializes `APIManager` to the region or country of an App Store in which the app is available.
|
||||
/// By default, all version check requests are performed against the US App Store.
|
||||
/// - Parameter country: The country for the App Store in which the app is available.
|
||||
public init(country: AppStoreCountry = .unitedStates) {
|
||||
/// By default, all version check requests are performed against the US App Store and the language of the copy/text is returned in English.
|
||||
/// - Parameters:
|
||||
/// - country: The country for the App Store in which the app is available.
|
||||
/// - language: The locale to use for the App Store notes. The default result the API returns is equivalent to passing "en_us", so passing `nil` is equivalent to passing "en_us".
|
||||
/// - bundleID: The bundleID for your app. Defaults to `Bundle.main.bundleIdentifier`. Passing `nil` will throw a `missingBundleID` error.
|
||||
public init(country: AppStoreCountry = .unitedStates, language: String? = nil, bundleID: String? = Bundle.main.bundleIdentifier) {
|
||||
self.country = country
|
||||
self.language = language
|
||||
self.bundleID = bundleID
|
||||
}
|
||||
|
||||
/// The default `APIManager`.
|
||||
@@ -48,22 +65,19 @@ extension APIManager {
|
||||
|
||||
/// Creates and performs a URLRequest against the iTunes Lookup API.
|
||||
///
|
||||
/// - Parameter handler: The completion handler for the iTunes Lookup API request.
|
||||
func performVersionCheckRequest(completion handler: CompletionHandler?) {
|
||||
guard Bundle.main.bundleIdentifier != nil else {
|
||||
handler?(.failure(.missingBundleID))
|
||||
return
|
||||
/// - returns APIModel: The decoded JSON as an instance of APIModel.
|
||||
func performVersionCheckRequest() async throws -> APIModel {
|
||||
guard bundleID != nil else {
|
||||
throw KnownError.missingBundleID
|
||||
}
|
||||
|
||||
do {
|
||||
let url = try makeITunesURL()
|
||||
let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 30)
|
||||
URLSession.shared.dataTask(with: request) { (data, response, error) in
|
||||
URLCache.shared.removeCachedResponse(for: request)
|
||||
self.processVersionCheckResults(withData: data, response: response, error: error, completion: handler)
|
||||
}.resume()
|
||||
let (data, response) = try await URLSession.shared.data(for: request)
|
||||
return try processVersionCheckResults(withData: data, response: response)
|
||||
} catch {
|
||||
handler?(.failure(.malformedURL))
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,33 +86,20 @@ extension APIManager {
|
||||
/// - Parameters:
|
||||
/// - data: The JSON data returned from the request.
|
||||
/// - response: The response metadata returned from the request.
|
||||
/// - error: The error returned from the request.
|
||||
/// - handler: The completion handler to call once the results of the request has been processed.
|
||||
private func processVersionCheckResults(withData data: Data?,
|
||||
response: URLResponse?,
|
||||
error: Error?,
|
||||
completion handler: CompletionHandler?) {
|
||||
if let error = error {
|
||||
handler?(.failure(.appStoreDataRetrievalFailure(underlyingError: error)))
|
||||
} else {
|
||||
guard let data = data else {
|
||||
handler?(.failure(.appStoreDataRetrievalFailure(underlyingError: nil)))
|
||||
return
|
||||
}
|
||||
do {
|
||||
let apiModel = try JSONDecoder().decode(APIModel.self, from: data)
|
||||
private func processVersionCheckResults(withData data: Data?, response: URLResponse?) throws -> APIModel {
|
||||
guard let data = data else {
|
||||
throw KnownError.appStoreDataRetrievalFailure(underlyingError: nil)
|
||||
}
|
||||
do {
|
||||
let apiModel = try JSONDecoder().decode(APIModel.self, from: data)
|
||||
|
||||
guard !apiModel.results.isEmpty else {
|
||||
handler?(.failure(.appStoreDataRetrievalEmptyResults))
|
||||
return
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
handler?(.success(apiModel))
|
||||
}
|
||||
} catch {
|
||||
handler?(.failure(.appStoreJSONParsingFailure(underlyingError: error)))
|
||||
guard !apiModel.results.isEmpty else {
|
||||
throw KnownError.appStoreDataRetrievalEmptyResults
|
||||
}
|
||||
|
||||
return apiModel
|
||||
} catch {
|
||||
throw KnownError.appStoreJSONParsingFailure(underlyingError: error)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,12 +113,22 @@ extension APIManager {
|
||||
components.host = "itunes.apple.com"
|
||||
components.path = "/lookup"
|
||||
|
||||
var items: [URLQueryItem] = [URLQueryItem(name: Constants.bundleID, value: Bundle.main.bundleIdentifier)]
|
||||
var items: [URLQueryItem] = [URLQueryItem(name: Constants.bundleID, value: bundleID)]
|
||||
|
||||
#if os(tvOS)
|
||||
let tvOSQueryItem = URLQueryItem(name: Constants.entity, value: Constants.tvSoftware)
|
||||
items.append(tvOSQueryItem)
|
||||
#endif
|
||||
|
||||
if let countryCode = country.code {
|
||||
let item = URLQueryItem(name: Constants.country, value: countryCode)
|
||||
items.append(item)
|
||||
}
|
||||
|
||||
if let language = language {
|
||||
let item = URLQueryItem(name: Constants.language, value: language)
|
||||
items.append(item)
|
||||
}
|
||||
|
||||
components.queryItems = items
|
||||
|
||||
|
||||
@@ -226,24 +226,19 @@ private extension PresentationManager {
|
||||
|
||||
private extension PresentationManager {
|
||||
private func createWindow() -> UIWindow? {
|
||||
var window = UIWindow()
|
||||
if #available(iOS 13.0, *) {
|
||||
guard let windowScene = getFirstForegroundScene() else { return nil }
|
||||
window = UIWindow(windowScene: windowScene)
|
||||
} else {
|
||||
window = UIWindow(frame: UIScreen.main.bounds)
|
||||
}
|
||||
guard let windowScene = getFirstForegroundScene() else { return nil }
|
||||
|
||||
let window = UIWindow(windowScene: windowScene)
|
||||
window.windowLevel = UIWindow.Level.alert + 1
|
||||
|
||||
let viewController = SirenViewController()
|
||||
viewController.retainedWindow = window
|
||||
|
||||
window.rootViewController = viewController
|
||||
|
||||
return window
|
||||
}
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
@available(iOS 13.0, tvOS 13.0, *)
|
||||
private func getFirstForegroundScene() -> UIWindowScene? {
|
||||
let connectedScenes = UIApplication.shared.connectedScenes
|
||||
if let windowActiveScene = connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<?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>NSPrivacyTracking</key>
|
||||
<false/>
|
||||
<key>NSPrivacyTrackingDomains</key>
|
||||
<array/>
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>CA92.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>NSPrivacyCollectedDataTypes</key>
|
||||
<array/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,8 +1,8 @@
|
||||
/* Update alert message: A new version of {APP NAME} is available. Please update to version {NEW VERSION} now.*/
|
||||
"A new version of %@ is available. Please update to version %@ now." = "Nova verzia %@ je stigla. Ažuriraj na verziju %@ sada.";
|
||||
"A new version of %@ is available. Please update to version %@ now." = "Nova verzija %@ je dostupna. Ažuriraj na verziju %@ sada.";
|
||||
|
||||
/* Update alert title */
|
||||
"Update Available" = "Nova ažuriranje je stigla";
|
||||
"Update Available" = "Novo ažuriranje je dostupno";
|
||||
|
||||
/* Update alert dismiss button title */
|
||||
"Next time" = "Sljedeći put";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Update alert message: A new version of {APP NAME} is available. Please update to version {NEW VERSION} now.*/
|
||||
"A new version of %@ is available. Please update to version %@ now." = "%@' nın yeni bir sürümü mevcut. Lütfen %@ sürümüne güncelleyin.";
|
||||
"A new version of %@ is available. Please update to version %@ now." = "%@ uygulamasının yeni bir sürümü mevcut. Lütfen %@ sürümüne güncelleyin.";
|
||||
|
||||
/* Update alert title */
|
||||
"Update Available" = "Güncelleme Mevcut";
|
||||
|
||||
+54
-28
@@ -52,12 +52,22 @@ public final class Siren: NSObject {
|
||||
/// The last date that an alert was presented to the user.
|
||||
private var alertPresentationDate: Date? = UserDefaults.alertPresentationDate
|
||||
|
||||
/// Prevents the update dialog from not displaying when the user swipes down
|
||||
/// on a notification center notification to the bottom of screen when calling
|
||||
/// the Siren.shared.wail notificaiton using the `.onForeground` performCheck option.
|
||||
private var appDidBecomeActiveWorkItem: DispatchWorkItem?
|
||||
|
||||
/// The minimal amount of time needed before calling the update notification
|
||||
/// after entering the app from a notificaiton.
|
||||
/// Refer to comment in `appDidBecomeActiveWorkItem` for more information.
|
||||
private let appDidBecomeActiveWorkItemTimeDelay = 0.02
|
||||
|
||||
/// The App Store's unique identifier for an app.
|
||||
private var appID: Int?
|
||||
|
||||
|
||||
/// The completion handler used to return the results or errors returned by Siren.
|
||||
private var resultsHandler: ResultsHandler?
|
||||
|
||||
|
||||
/// The deinitialization method that clears out all observers,
|
||||
deinit {
|
||||
presentationManager.cleanUp()
|
||||
@@ -81,7 +91,7 @@ public extension Siren {
|
||||
switch performCheck {
|
||||
case .onDemand:
|
||||
removeForegroundObservers()
|
||||
performVersionCheck()
|
||||
startVersionCheckFlow()
|
||||
case .onForeground:
|
||||
addForegroundObservers()
|
||||
}
|
||||
@@ -102,11 +112,7 @@ public extension Siren {
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
if #available(iOS 10.0, *) {
|
||||
UIApplication.shared.open(url, options: [:], completionHandler: nil)
|
||||
} else {
|
||||
UIApplication.shared.openURL(url)
|
||||
}
|
||||
UIApplication.shared.open(url, options: [:], completionHandler: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,16 +120,25 @@ public extension Siren {
|
||||
// MARK: - Version Check and Alert Presentation Flow
|
||||
|
||||
private extension Siren {
|
||||
/// Initiates the unidirectional version checking flow.
|
||||
func performVersionCheck() {
|
||||
/// Initiates the version checking flow.
|
||||
func startVersionCheckFlow() {
|
||||
alertPresentationDate = UserDefaults.alertPresentationDate
|
||||
apiManager.performVersionCheckRequest { result in
|
||||
switch result {
|
||||
case .success(let apiModel):
|
||||
Task {
|
||||
await performVersionCheck()
|
||||
}
|
||||
}
|
||||
|
||||
/// Initiatives the version check request.
|
||||
func performVersionCheck() async {
|
||||
do {
|
||||
let apiModel = try await apiManager.performVersionCheckRequest()
|
||||
DispatchQueue.main.async {
|
||||
self.validate(apiModel: apiModel)
|
||||
case .failure(let error):
|
||||
self.resultsHandler?(.failure(error))
|
||||
}
|
||||
} catch (let error as KnownError) {
|
||||
self.resultsHandler?(.failure(error))
|
||||
} catch {
|
||||
// Do nothing. Silences exhaustive error.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,23 +205,25 @@ private extension Siren {
|
||||
/// - currentAppStoreVersion: The curren version of the app in the App Store.
|
||||
/// - model: The iTunes Lookup Model.
|
||||
func determineIfAlertPresentationRulesAreSatisfied(forCurrentAppStoreVersion currentAppStoreVersion: String, andModel model: Model) {
|
||||
// Did the user:
|
||||
// - request to skip being prompted with version update alerts for a specific version
|
||||
// - and is the latest App Store update the same version that was requested?
|
||||
if let previouslySkippedVersion = UserDefaults.storedSkippedVersion,
|
||||
let currentInstalledVersion = currentInstalledVersion,
|
||||
!currentAppStoreVersion.isEmpty,
|
||||
currentAppStoreVersion == previouslySkippedVersion {
|
||||
resultsHandler?(.failure(.skipVersionUpdate(installedVersion: currentInstalledVersion,
|
||||
appStoreVersion: currentAppStoreVersion)))
|
||||
return
|
||||
}
|
||||
|
||||
let updateType = DataParser.parseForUpdate(forInstalledVersion: currentInstalledVersion,
|
||||
andAppStoreVersion: currentAppStoreVersion)
|
||||
do {
|
||||
let rules = try rulesManager.loadRulesForUpdateType(updateType)
|
||||
|
||||
// Did the user:
|
||||
// - request to skip being prompted with version update alerts for a specific version
|
||||
// - and is the latest App Store update the same version that was requested
|
||||
// - and app is not forcing updates?
|
||||
if let previouslySkippedVersion = UserDefaults.storedSkippedVersion,
|
||||
let currentInstalledVersion = currentInstalledVersion,
|
||||
!currentAppStoreVersion.isEmpty,
|
||||
currentAppStoreVersion == previouslySkippedVersion,
|
||||
rules.alertType != .force {
|
||||
resultsHandler?(.failure(.skipVersionUpdate(installedVersion: currentInstalledVersion,
|
||||
appStoreVersion: currentAppStoreVersion)))
|
||||
return
|
||||
}
|
||||
|
||||
if rules.frequency == .immediately {
|
||||
presentAlert(withRules: rules, forCurrentAppStoreVersion: currentAppStoreVersion, model: model, andUpdateType: updateType)
|
||||
} else {
|
||||
@@ -277,7 +294,14 @@ private extension Siren {
|
||||
object: nil,
|
||||
queue: nil) { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
self.performVersionCheck()
|
||||
self.appDidBecomeActiveWorkItem = DispatchWorkItem {
|
||||
Task {
|
||||
await self.performVersionCheck()
|
||||
}
|
||||
}
|
||||
if let appDidBecomeActiveWorkItem = self.appDidBecomeActiveWorkItem {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + self.appDidBecomeActiveWorkItemTimeDelay, execute: appDidBecomeActiveWorkItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,6 +315,8 @@ private extension Siren {
|
||||
object: nil,
|
||||
queue: nil) { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
self.appDidBecomeActiveWorkItem?.cancel()
|
||||
self.appDidBecomeActiveWorkItem = nil
|
||||
self.presentationManager.cleanUp()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user