Added Safari App Extension

Added macOS app wrapper to support building as a Safari App Extension
This commit is contained in:
amarcu5
2018-11-12 12:37:04 +00:00
parent b83ea6461b
commit 77ff154a0a
32 changed files with 1563 additions and 8 deletions
+114 -7
View File
@@ -4,7 +4,7 @@
EXTENSION_NAME="PiPer"
SOURCE_FILES=("main.js" "fix.js")
SOURCE_FILES=("main.js" "fix.js" "localization_bridge.js")
# Certifcate paths
LEAF_CERT_PATH="../certs/cert.pem"
@@ -20,12 +20,14 @@ Usage: make.sh [options]
Options:
-h -? --help Show this screen
-t --target (all|safari-legacy) Make extension for target browser [default: all]
-t --target (all|safari|safari-legacy) Make extension for target browser [default: all]
-p --profile (release|debug|distribute) Set settings according to profile [default: debug]
-c --compress-css Compress CSS
-j --compress-js Compress JavaScript
-s --compress-svg Compress SVG
-l --logging-level <number> Set logging level (0=all 10=trace 20=info 30=warning 40=error)
-i --development-team <id> Set development team ID
-a --archive-to-xcode Archive Safari extension to Xcode for Mac App Store distribution
-e --package-extension Package extension for distribution (safari-legacy requires private key)
-d --no-debug-js Remove JavaScript source maps to prevent debugging
-v --no-version-increment Disable automatic version incrementing
@@ -42,7 +44,7 @@ while :; do
-h|-\?|--help) show_help ;;
-p|--profile) [[ "$2" ]] && profile=$2 ;;
--profile=?*) profile=${1#*=} ;;
-l|-t|--logging-level|--target) shift ;;
-l|-t|-i|--logging-level|--target|--development-team) shift ;;
-?*) ;;
*) break
esac
@@ -78,6 +80,8 @@ case $profile in
;;
esac
update_version=1
archive_xcode=0
development_team=""
targets="all"
set -- "${arguments[@]}"
@@ -95,6 +99,9 @@ while :; do
--target=?*) targets=${1#*=} ;;
-l|--logging-level) [[ "$2" ]] && logging_level=$2 && shift ;;
--logging-level=?*) logging_level=${1#*=} ;;
-i|--development-team) [[ "$2" ]] && development_team=$2 && shift ;;
--development-team=?*) development_team=${1#*=} ;;
-a|--archive-to-xcode) archive_xcode=1 ;;
-p|--profile) shift ;;
-?*) ;;
*) break ;;
@@ -107,10 +114,12 @@ echo "Setting '${profile}' profile"
# Validate targets
case $targets in
safari) targets=("safari") ;;
safari-legacy) targets=("safari-legacy") ;;
*) targets=("safari-legacy")
*) targets=("safari" "safari-legacy")
esac
# Helper checks for build tool dependency and falls back to 'npx' if possible
function get_node_command() {
if type "$1" &>/dev/null; then
@@ -130,7 +139,28 @@ function get_node_command() {
# Target specific build checks
for i in "${!targets[@]}"; do
if [[ "${targets[$i]}" = "safari-legacy" ]]; then
if [[ "${targets[$i]}" = "safari" ]]; then
# Only build 'safari' extension target when running under macOS
if [[ "$(uname)" != "Darwin" ]]; then
echo "Warning: Building 'safari' extension skipped as requires macOS" >&2
unset "targets[$i]"
continue
fi
# Ensure with have Xcode command line tools installed
if [[ -z $(xcode-select --print-path) ]]; then
echo "Installing Xcode Command Line Tools (expect a GUI popup)"
xcode-select --install &>/dev/null
echo "Press any key after installation has completed"
read -rsn1
if [[ -z $(xcode-select --print-path) ]]; then
echo "Unable to find Xcode Command Line Tools"
exit 1
fi
fi
elif [[ "${targets[$i]}" = "safari-legacy" ]]; then
# Get 'safari-legacy' specific build tool path and exit if not found
[[ "${package_ext}" -eq 1 ]] && { XARJS_PATH=$(get_node_command "xarjs" "xar-js") || exit 1; }
@@ -277,6 +307,11 @@ for target in "${targets[@]}"; do
# Set target specific flags
case $target in
safari)
browser=1
target_extension=""
common_file_path="/Extension/Resources"
;;
safari-legacy)
browser=1
target_extension=".safariextension"
@@ -457,9 +492,81 @@ for target in "${targets[@]}"; do
done
fi
# Safari specific build steps
if [[ "${target}" == "safari-legacy" ]]; then
if [[ "${target}" == "safari" ]]; then
# Update version info from git
if [[ "${update_version}" -eq 1 ]]; then
multiline_sed_regex "out/${EXTENSION_NAME}-${target}/Extension/Info.plist" "s|(> *CFBundleShortVersionString *</key>[^>]+>)[^<]+|\1${git_release_version}|g"
multiline_sed_regex "out/${EXTENSION_NAME}-${target}/Extension/Info.plist" "s|(> *CFBundleVersion *</key>[^>]+>)[^<]+|\1${number_of_commits}|g"
multiline_sed_regex "out/${EXTENSION_NAME}-${target}/App/Info.plist" "s|(> *CFBundleShortVersionString *</key>[^>]+>)[^<]+|\1${git_release_version}|g"
multiline_sed_regex "out/${EXTENSION_NAME}-${target}/App/Info.plist" "s|(> *CFBundleVersion *</key>[^>]+>)[^<]+|\1${number_of_commits}|g"
fi
# Get development team id automatically if needed
if [[ -z "${development_team}" ]]; then
# Helper maintains unique list of ids
team_ids=()
function add_unique_team_ids() {
for i in "${!team_ids[@]}"; do
[[ ${team_ids[$i]} = "$1" ]] && return
done
team_ids+=("$1")
}
# Search mobileprovision files for team identifiers
regex="TeamIdentifier<\/key>[^\/]+>([A-Z0-9]{10})<\/"
for path in "${HOME}/Library/MobileDevice/Provisioning Profiles"/*.mobileprovision; do
source=$(cat "${path}" | iconv -f "ISO-8859-1" -t "UTF-8")
if [[ "${source}" =~ $regex ]]; then
add_unique_team_ids "${BASH_REMATCH[1]}"
fi
done
# If multiple or no identifiers found then prompt the user
development_team_hint="(avoid this message in future by specifying --development-team)"
if (( ${#team_ids[@]} == 0 )); then
echo "Unable to find development team automatically, please enter below: ${development_team_hint}"
read development_team </dev/tty
elif (( ${#team_ids[@]} == 1 )); then
development_team="${team_ids[0]}"
else
echo "Multiple development team's found"
for (( i=0; i < ${#team_ids[@]}; i++ )); do
echo " [${i}]: ${team_ids[$i]}"
done
echo "Please select development team to use: ${development_team_hint}"
read selection </dev/tty
development_team="${team_ids[$selection]}"
fi
fi
# Build the xcode project
config_profile=$([[ "${profile}" == "debug" ]] && echo "Debug" || echo "Release")
xcodebuild -allowProvisioningUpdates -allowProvisioningDeviceRegistration -quiet -project "./out/${EXTENSION_NAME}-${target}/PiPer.xcodeproj" -scheme "PiPer" archive -archivePath "./out/${EXTENSION_NAME}-${target}.xcarchive" -configuration "${config_profile}" CODE_SIGN_STYLE="Automatic" CODE_SIGN_IDENTITY="Mac Developer" DEVELOPMENT_TEAM="${development_team}"
xcodebuild -allowProvisioningUpdates -allowProvisioningDeviceRegistration -quiet -exportArchive -archivePath "./out/${EXTENSION_NAME}-${target}.xcarchive" -exportPath "./out/" -exportOptionsPlist "./out/${EXTENSION_NAME}-${target}/exportOptions.plist" CODE_SIGN_STYLE="Automatic" CODE_SIGN_IDENTITY="Mac Developer" DEVELOPMENT_TEAM="${development_team}" &>/dev/null
# Copy archive to Xcode if needed
if [[ "${archive_xcode}" -eq 1 ]]; then
archive_time=$(date '+%d-%m-%Y, %H.%M')
mv "./out/${EXTENSION_NAME}-${target}.xcarchive" "${HOME}/Library/Developer/Xcode/Archives/${EXTENSION_NAME} ${archive_time}.xcarchive"
fi
# Package extension
if [[ "${package_ext}" -eq 1 ]]; then
productbuild --quiet --component "./out/PiPer.app" "/Applications" "./out/${EXTENSION_NAME}-${target}.pkg"
rm -rf "./out/PiPer.app"
else
mv "out/PiPer.app" "out/${EXTENSION_NAME}-${target}.app"
fi
# Remove everything else
rm -rf "out/${EXTENSION_NAME}-${target}.xcarchive"
rm -rf "out/${EXTENSION_NAME}-${target}"
elif [[ "${target}" == "safari-legacy" ]]; then
# Remove irrelevant target file
rm -f "out/${EXTENSION_NAME}-${target}${target_extension}/update.plist"
Binary file not shown.
Binary file not shown.
+18
View File
@@ -9,6 +9,24 @@ localizations['button-title'] = {
'fr': 'Démarrer Image dans limage',
};
localizations['donate'] = {
'en': 'Donate',
'de': 'Spenden',
};
localizations['report-bug'] = {
'en': 'Report a bug',
'de': 'Einen Fehler melden',
};
localizations['enable'] = {
'en': 'Enable',
};
localizations['safari-disabled-warning'] = {
'en': 'Extension is currently disabled, enable in Safari preferences',
};
// Set English as the default fallback language
const defaultLanguage = 'en';
+1 -1
View File
@@ -10,7 +10,7 @@
<key>CFBundleShortVersionString</key>
<string></string>
<key>CFBundleVersion</key>
<string>173</string>
<string>174</string>
<key>Developer Identifier</key>
<string>BQ6Q24MF9X</string>
<key>URL</key>
+25
View File
@@ -0,0 +1,25 @@
//
// AppDelegate.swift
// PiPer App
//
// Created by Adam Marcus on 19/07/2018.
// Copyright © 2018 Adam Marcus. All rights reserved.
//
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
}
func applicationWillTerminate(_ aNotification: Notification) {
}
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true;
}
}
Binary file not shown.
+36
View File
@@ -0,0 +1,36 @@
<?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>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string></string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIconFile</key>
<string>Icon.icns</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.0.0</string>
<key>CFBundleVersion</key>
<string>0</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2018 Adam Marcus. All rights reserved.</string>
<key>NSMainStoryboardFile</key>
<string>Main</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>
+49
View File
@@ -0,0 +1,49 @@
//
// LocalizationManager.swift
// PiPer
//
// Created by Adam Marcus on 12/10/2018.
// Copyright © 2018 Adam Marcus. All rights reserved.
//
import Foundation
import JavaScriptCore
class LocalizationManager {
let context: JSContext = JSContext()
let languageCode: String
static let `default` = LocalizationManager()
init(withLanguageCode languageCode: String? = Locale.current.languageCode) {
self.languageCode = languageCode ?? ""
#if DEBUG
context.exceptionHandler = { _, value in
print("Localization JavaScriptCore error: \(value!)")
}
#endif
context.evaluateScript("const window = {};")
if let extensionBundleURL = ResourceHelper.extensionBundleURL {
let localizationFile = extensionBundleURL.appendingPathComponent("scripts/localization_bridge.js").path
let localizationFileContents = try? String(contentsOfFile: localizationFile,
encoding: String.Encoding.utf8)
if let localizationScript = localizationFileContents {
context.evaluateScript(localizationScript)
}
}
}
func localizedString(forKey key: String) -> String {
let string = context.evaluateScript("window.localizedString('\(key)', '\(languageCode)');").toString()
return string ?? ""
}
}
+33
View File
@@ -0,0 +1,33 @@
//
// LocalizedButton.swift
// PiPer
//
// Created by Adam Marcus on 13/10/2018.
// Copyright © 2018 Adam Marcus. All rights reserved.
//
import Cocoa
@IBDesignable
class LocalizedButton: NSButton {
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
localizeTitle()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
localizeTitle()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
localizeTitle()
}
func localizeTitle() {
self.title = LocalizationManager.default.localizedString(forKey:self.title)
}
}
+33
View File
@@ -0,0 +1,33 @@
//
// LocalizedTextField.swift
// PiPer
//
// Created by Adam Marcus on 13/10/2018.
// Copyright © 2018 Adam Marcus. All rights reserved.
//
import Cocoa
@IBDesignable
class LocalizedTextField: NSTextField {
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
localizeValue()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
localizeValue()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
localizeValue()
}
func localizeValue() {
self.stringValue = LocalizationManager.default.localizedString(forKey:self.stringValue)
}
}
+190
View File
@@ -0,0 +1,190 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Application-->
<scene sceneID="JPo-4y-FX3">
<objects>
<application id="hnw-xV-0zn" sceneMemberID="viewController">
<menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
<items>
<menuItem title="PiPer" id="1Xt-HY-uBw">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="PiPer" systemMenu="apple" id="uQy-DD-JDr">
<items>
<menuItem title="Quit PiPer" keyEquivalent="q" id="4sb-4s-VLi">
<connections>
<action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
<connections>
<outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
</connections>
</application>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="PiPer" customModuleProvider="target"/>
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="360" y="-44"/>
</scene>
<!--Window Controller-->
<scene sceneID="R2V-B0-nI4">
<objects>
<windowController id="B8D-0N-5wS" sceneMemberID="viewController">
<window key="window" title="PiPer" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" titleVisibility="hidden" id="IQv-IB-iLA">
<windowStyleMask key="styleMask" titled="YES" closable="YES" fullSizeContentView="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="356" height="220"/>
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
<value key="minSize" type="size" width="356" height="220"/>
<value key="maxSize" type="size" width="356" height="220"/>
<connections>
<outlet property="delegate" destination="B8D-0N-5wS" id="98r-iN-zZc"/>
</connections>
</window>
<connections>
<segue destination="XfG-lQ-9wD" kind="relationship" relationship="window.shadowedContentViewController" id="cq2-FE-JQM"/>
</connections>
</windowController>
<customObject id="Oky-zY-oP4" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="75" y="55"/>
</scene>
<!--View Controller-->
<scene sceneID="hIz-AP-VOD">
<objects>
<viewController id="XfG-lQ-9wD" customClass="ViewController" customModule="PiPer" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" id="m2S-Jp-Qdl">
<rect key="frame" x="0.0" y="0.0" width="356" height="220"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<visualEffectView appearanceType="inheritedVibrantLight" blendingMode="behindWindow" material="underWindowBackground" state="followsWindowActiveState" translatesAutoresizingMaskIntoConstraints="NO" id="fhh-nv-kqK">
<rect key="frame" x="0.0" y="0.0" width="356" height="220"/>
</visualEffectView>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="fhh-nv-kqK" secondAttribute="trailing" id="R1a-1n-kYy"/>
<constraint firstItem="fhh-nv-kqK" firstAttribute="top" secondItem="m2S-Jp-Qdl" secondAttribute="top" id="Vgc-sd-EOP"/>
<constraint firstItem="fhh-nv-kqK" firstAttribute="leading" secondItem="m2S-Jp-Qdl" secondAttribute="leading" id="ZHb-JW-3Uc"/>
<constraint firstAttribute="bottom" secondItem="fhh-nv-kqK" secondAttribute="bottom" id="f4x-N6-X6o"/>
</constraints>
</view>
<connections>
<outlet property="extensionDisabledView" destination="Wtu-CL-ZAO" id="yuV-8q-YtZ"/>
<outlet property="mainView" destination="3Hb-XS-UyM" id="yUU-7Q-ncx"/>
<outlet property="viewContainer" destination="fhh-nv-kqK" id="c0U-Yq-xxu"/>
</connections>
</viewController>
<customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
<customView id="Wtu-CL-ZAO">
<rect key="frame" x="0.0" y="0.0" width="356" height="220"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="SlA-kL-hiD">
<rect key="frame" x="16" y="94" width="32" height="32"/>
<constraints>
<constraint firstAttribute="height" constant="32" id="ZWA-Q4-Gnv"/>
<constraint firstAttribute="width" constant="32" id="sOE-7r-348"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSCaution" id="dJM-ez-eQ2"/>
</imageView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5oh-0M-Zn6" customClass="LocalizedButton" customModule="PiPer" customModuleProvider="target">
<rect key="frame" x="265" y="93" width="81" height="32"/>
<buttonCell key="cell" type="push" title="enable" bezelStyle="rounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="HcB-QW-aQq">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="clickedEnableExtensionWithSender:" target="XfG-lQ-9wD" id="jgv-vd-Hd3"/>
</connections>
</button>
<textField horizontalHuggingPriority="200" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="500" translatesAutoresizingMaskIntoConstraints="NO" id="Gzc-Eb-L1r" customClass="LocalizedTextField" customModule="PiPer" customModuleProvider="target">
<rect key="frame" x="56" y="102" width="207" height="17"/>
<textFieldCell key="cell" alignment="left" title="safari-disabled-warning" drawsBackground="YES" id="LEL-vU-9sz">
<font key="font" metaFont="systemMedium" size="13"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="5oh-0M-Zn6" firstAttribute="leading" secondItem="Gzc-Eb-L1r" secondAttribute="trailing" constant="8" id="Hcd-kf-9uY"/>
<constraint firstItem="Gzc-Eb-L1r" firstAttribute="leading" secondItem="SlA-kL-hiD" secondAttribute="trailing" constant="8" id="IAC-H1-5u2"/>
<constraint firstItem="SlA-kL-hiD" firstAttribute="centerY" secondItem="Wtu-CL-ZAO" secondAttribute="centerY" id="P98-CO-DBI"/>
<constraint firstItem="5oh-0M-Zn6" firstAttribute="centerY" secondItem="Wtu-CL-ZAO" secondAttribute="centerY" id="Ttv-0y-TAb"/>
<constraint firstItem="Gzc-Eb-L1r" firstAttribute="centerY" secondItem="Wtu-CL-ZAO" secondAttribute="centerY" id="cWx-Ul-bxK"/>
<constraint firstItem="SlA-kL-hiD" firstAttribute="leading" secondItem="Wtu-CL-ZAO" secondAttribute="leading" constant="16" id="gUm-TC-3DN"/>
<constraint firstAttribute="trailing" secondItem="5oh-0M-Zn6" secondAttribute="trailing" constant="16" id="rAw-aH-ZXO"/>
</constraints>
</customView>
<customView id="3Hb-XS-UyM">
<rect key="frame" x="0.0" y="0.0" width="356" height="220"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="l9e-rg-eUq">
<rect key="frame" x="58" y="88" width="80" height="80"/>
<constraints>
<constraint firstAttribute="width" constant="80" id="52v-J9-pFo"/>
<constraint firstAttribute="height" constant="80" id="9ic-ED-CML"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="Icon" id="655-Gm-l0p"/>
</imageView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aXl-MI-TCo">
<rect key="frame" x="61" y="45" width="73" height="39"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="PiPer" drawsBackground="YES" id="pyu-MO-9NT">
<font key="font" metaFont="system" size="32"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="h9M-Bg-2Qi" customClass="LocalizedButton" customModule="PiPer" customModuleProvider="target">
<rect key="frame" x="196" y="104" width="107" height="32"/>
<buttonCell key="cell" type="push" title="report-bug" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="HPq-wV-jsz">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="clickedReportBugWithSender:" target="XfG-lQ-9wD" id="GA1-uc-3Zx"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="l7Q-NM-lYD" customClass="LocalizedButton" customModule="PiPer" customModuleProvider="target">
<rect key="frame" x="196" y="70" width="107" height="32"/>
<buttonCell key="cell" type="push" title="donate" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="jbL-wE-6Bb">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="clickedDonateWithSender:" target="XfG-lQ-9wD" id="DRM-9J-vKO"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="l9e-rg-eUq" firstAttribute="centerX" secondItem="3Hb-XS-UyM" secondAttribute="centerX" multiplier="0.55" id="0rd-47-5ke"/>
<constraint firstItem="l7Q-NM-lYD" firstAttribute="centerY" secondItem="3Hb-XS-UyM" secondAttribute="centerY" multiplier="1.2" id="1yu-Ya-ffe"/>
<constraint firstItem="aXl-MI-TCo" firstAttribute="top" secondItem="l9e-rg-eUq" secondAttribute="bottom" constant="4" id="9A4-i3-Pj0"/>
<constraint firstItem="l9e-rg-eUq" firstAttribute="centerY" secondItem="3Hb-XS-UyM" secondAttribute="centerY" constant="-18" id="NqP-Fs-Cka"/>
<constraint firstItem="aXl-MI-TCo" firstAttribute="centerX" secondItem="l9e-rg-eUq" secondAttribute="centerX" id="SqJ-aZ-Yox"/>
<constraint firstItem="h9M-Bg-2Qi" firstAttribute="centerY" secondItem="3Hb-XS-UyM" secondAttribute="centerY" multiplier="0.9" id="XJe-gR-gCd"/>
<constraint firstItem="l7Q-NM-lYD" firstAttribute="centerX" secondItem="3Hb-XS-UyM" secondAttribute="centerX" multiplier="1.4" id="b0H-tS-xdf"/>
<constraint firstItem="h9M-Bg-2Qi" firstAttribute="centerX" secondItem="3Hb-XS-UyM" secondAttribute="centerX" multiplier="1.4" id="bh5-aa-dpw"/>
<constraint firstItem="l7Q-NM-lYD" firstAttribute="width" secondItem="h9M-Bg-2Qi" secondAttribute="width" id="orO-L8-WbF"/>
</constraints>
</customView>
</objects>
<point key="canvasLocation" x="75" y="645"/>
</scene>
</scenes>
<resources>
<image name="Icon" width="512" height="512"/>
<image name="NSCaution" width="128" height="128"/>
</resources>
</document>
+14
View File
@@ -0,0 +1,14 @@
<?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>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>$(APP_GROUP_ID)</string>
</array>
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>
+23
View File
@@ -0,0 +1,23 @@
//
// ResourceHelper.swift
// PiPer
//
// Created by Adam Marcus on 13/10/2018.
// Copyright © 2018 Adam Marcus. All rights reserved.
//
import Foundation
class ResourceHelper {
static let extensionBundleURL: URL? = {
guard let pluginURL = Bundle.main.builtInPlugInsURL else {
return nil
}
guard let extensionBundle = Bundle(url: pluginURL.appendingPathComponent("PiPerExt.appex")) else {
return nil
}
return extensionBundle.resourceURL
}()
}
+69
View File
@@ -0,0 +1,69 @@
//
// ViewController.swift
// PiPer App
//
// Created by Adam Marcus on 19/07/2018.
// Copyright © 2018 Adam Marcus. All rights reserved.
//
import Cocoa
import SafariServices
class ViewController: NSViewController {
let extensionId = String(cString:EXTENSION_BUNDLE_ID)
@IBOutlet var viewContainer: NSVisualEffectView!
@IBOutlet var mainView: NSView!
@IBOutlet var extensionDisabledView: NSView!
override func viewDidLoad() {
super.viewDidLoad()
// Display the main view by default
viewContainer.addSubview(mainView)
// Poll every second for Safari extension state changes
Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(ViewController.checkExtensionState), userInfo: nil, repeats: true).fire()
}
// Display the requested view
func showView(_ newView: NSView) {
let oldView = viewContainer.subviews.first
if oldView == newView {
return
}
// Avoid animating the transition due to NSButton vibrancy rendering glitch in dark mode
// viewContainer.animator().replaceSubview(oldView!, with:newView)
viewContainer.replaceSubview(oldView!, with:newView)
}
// Check extension state and show extension disabled view if necessary
@objc func checkExtensionState() {
SFSafariExtensionManager.getStateOfSafariExtension(withIdentifier: extensionId) { state, error in
DispatchQueue.main.async {
if let status = state?.isEnabled {
self.showView(status ? self.mainView : self.extensionDisabledView)
}
}
}
}
@IBAction func clickedEnableExtension(sender: NSButton) {
SFSafariApplication.showPreferencesForExtension(withIdentifier: extensionId)
}
@IBAction func clickedReportBug(sender: NSButton) {
if let url = URL(string: "https://github.com/amarcu5/PiPer/issues") {
NSWorkspace.shared.open(url)
}
}
@IBAction func clickedDonate(sender: NSButton) {
if let url = URL(string: "https://paypal.me/adampmarcus") {
NSWorkspace.shared.open(url)
}
}
}
+15
View File
@@ -0,0 +1,15 @@
//
// Defines.c
// PiPer
//
// Created by Adam Marcus on 10/08/2018.
// Copyright © 2018 Adam Marcus. All rights reserved.
//
#define QUOTE(str) #str
#define EXPAND_AND_QUOTE(str) QUOTE(str)
const char * APP_GROUP_ID = EXPAND_AND_QUOTE(APP_GROUP_ID_CONST);
const char * APP_BUNDLE_ID = EXPAND_AND_QUOTE(APP_BUNDLE_ID_CONST);
const char * EXTENSION_BUNDLE_ID = EXPAND_AND_QUOTE(EXTENSION_BUNDLE_ID_CONST);
+12
View File
@@ -0,0 +1,12 @@
//
// Defines.h
// PiPer
//
// Created by Adam Marcus on 10/08/2018.
// Copyright © 2018 Adam Marcus. All rights reserved.
//
extern const char * APP_GROUP_ID;
extern const char * APP_BUNDLE_ID;
extern const char * EXTENSION_BUNDLE_ID;
+53
View File
@@ -0,0 +1,53 @@
<?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>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>PiPer</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>0.0.0</string>
<key>CFBundleVersion</key>
<string>0</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.Safari.extension</string>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).SafariExtensionHandler</string>
<key>SFSafariContentScript</key>
<array>
<dict>
<key>Script</key>
<string>scripts/main.js</string>
</dict>
</array>
<key>SFSafariExtensionBundleIdentifiersToUninstall</key>
<array>
<string>com.amarcus.safari.piper</string>
</array>
<key>SFSafariWebsiteAccess</key>
<dict>
<key>Level</key>
<string>All</string>
</dict>
</dict>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2018 Adam Marcus. All rights reserved.</string>
<key>NSHumanReadableDescription</key>
<string>Adds Picture in Picture functionality to Youtube, Netflix, Amazon Video, Twitch, and more!</string>
</dict>
</plist>
@@ -0,0 +1,12 @@
<?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>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>$(APP_GROUP_ID)</string>
</array>
</dict>
</plist>
@@ -0,0 +1,4 @@
import { localizedString } from './localization.js'
// Export localization functions
window['localizedString'] = localizedString;
@@ -0,0 +1,13 @@
//
// SafariExtensionHandler.swift
// PiPer
//
// Created by Adam Marcus on 19/07/2018.
// Copyright © 2018 Adam Marcus. All rights reserved.
//
import SafariServices
class SafariExtensionHandler: SFSafariExtensionHandler {
}
+563
View File
@@ -0,0 +1,563 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
85254C902100C6CA000CDDE0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85254C8F2100C6CA000CDDE0 /* AppDelegate.swift */; };
85254C922100C6CA000CDDE0 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85254C912100C6CA000CDDE0 /* ViewController.swift */; };
85254CA92100C703000CDDE0 /* SafariExtensionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85254CA82100C703000CDDE0 /* SafariExtensionHandler.swift */; };
85254CB72100C703000CDDE0 /* PiPerExt.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 85254CA32100C703000CDDE0 /* PiPerExt.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
854061A62171599100F60C11 /* LocalizationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 854061A52171599100F60C11 /* LocalizationManager.swift */; };
854061A8217167EA00F60C11 /* LocalizedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 854061A7217167EA00F60C11 /* LocalizedButton.swift */; };
854061AA2172234300F60C11 /* LocalizedTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 854061A92172234300F60C11 /* LocalizedTextField.swift */; };
857DA7332116237700B38873 /* Icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 857DA7322116237700B38873 /* Icon.icns */; };
85A0EA8021726E30000DB27C /* scripts in Resources */ = {isa = PBXBuildFile; fileRef = 85A0EA7A21726E2A000DB27C /* scripts */; };
85A0EA8121726E30000DB27C /* images in Resources */ = {isa = PBXBuildFile; fileRef = 85A0EA7B21726E2B000DB27C /* images */; };
85A0EA8621726F05000DB27C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 85A0EA8521726F05000DB27C /* Main.storyboard */; };
85A0EA8C2172850D000DB27C /* ResourceHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85A0EA8B2172850D000DB27C /* ResourceHelper.swift */; };
85E505AB211E330F003B446B /* Defines.c in Sources */ = {isa = PBXBuildFile; fileRef = 85E505AA211E330F003B446B /* Defines.c */; };
85E505AC211E3339003B446B /* Defines.c in Sources */ = {isa = PBXBuildFile; fileRef = 85E505AA211E330F003B446B /* Defines.c */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
85254CB52100C703000CDDE0 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 85254C842100C6C9000CDDE0 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 85254CA22100C703000CDDE0;
remoteInfo = PiPer;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
85254CBB2100C703000CDDE0 /* Embed App Extensions */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 13;
files = (
85254CB72100C703000CDDE0 /* PiPerExt.appex in Embed App Extensions */,
);
name = "Embed App Extensions";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
851C3AE62113D4F90052505E /* PiPer_App.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PiPer_App.entitlements; sourceTree = "<group>"; };
851C3AE72113D4FE0052505E /* PiPer_Extension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PiPer_Extension.entitlements; sourceTree = "<group>"; };
85254C8C2100C6CA000CDDE0 /* PiPer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PiPer.app; sourceTree = BUILT_PRODUCTS_DIR; };
85254C8F2100C6CA000CDDE0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
85254C912100C6CA000CDDE0 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
85254C982100C6CA000CDDE0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
85254CA32100C703000CDDE0 /* PiPerExt.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = PiPerExt.appex; sourceTree = BUILT_PRODUCTS_DIR; };
85254CA82100C703000CDDE0 /* SafariExtensionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariExtensionHandler.swift; sourceTree = "<group>"; };
85254CAF2100C703000CDDE0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
854061A52171599100F60C11 /* LocalizationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizationManager.swift; sourceTree = "<group>"; };
854061A7217167EA00F60C11 /* LocalizedButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizedButton.swift; sourceTree = "<group>"; };
854061A92172234300F60C11 /* LocalizedTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizedTextField.swift; sourceTree = "<group>"; };
857DA7322116237700B38873 /* Icon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Icon.icns; sourceTree = "<group>"; };
85A0EA7A21726E2A000DB27C /* scripts */ = {isa = PBXFileReference; lastKnownFileType = folder; path = scripts; sourceTree = "<group>"; };
85A0EA7B21726E2B000DB27C /* images */ = {isa = PBXFileReference; lastKnownFileType = folder; path = images; sourceTree = "<group>"; };
85A0EA8521726F05000DB27C /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
85A0EA8B2172850D000DB27C /* ResourceHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResourceHelper.swift; sourceTree = "<group>"; };
85E505A7211E22A4003B446B /* Defines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Defines.h; sourceTree = "<group>"; };
85E505AA211E330F003B446B /* Defines.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = Defines.c; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
85254C892100C6CA000CDDE0 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
85254CA02100C703000CDDE0 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
85254C832100C6C9000CDDE0 = {
isa = PBXGroup;
children = (
85E505A9211E2D83003B446B /* Common */,
85254C8E2100C6CA000CDDE0 /* App */,
85254CA72100C703000CDDE0 /* Extension */,
85254C8D2100C6CA000CDDE0 /* Products */,
8589A341211E42FD006F9C65 /* Frameworks */,
);
sourceTree = "<group>";
};
85254C8D2100C6CA000CDDE0 /* Products */ = {
isa = PBXGroup;
children = (
85254C8C2100C6CA000CDDE0 /* PiPer.app */,
85254CA32100C703000CDDE0 /* PiPerExt.appex */,
);
name = Products;
sourceTree = "<group>";
};
85254C8E2100C6CA000CDDE0 /* App */ = {
isa = PBXGroup;
children = (
85254C8F2100C6CA000CDDE0 /* AppDelegate.swift */,
85A0EA8B2172850D000DB27C /* ResourceHelper.swift */,
85254C912100C6CA000CDDE0 /* ViewController.swift */,
854061A7217167EA00F60C11 /* LocalizedButton.swift */,
854061A92172234300F60C11 /* LocalizedTextField.swift */,
854061A52171599100F60C11 /* LocalizationManager.swift */,
85A0EA8521726F05000DB27C /* Main.storyboard */,
857DA7322116237700B38873 /* Icon.icns */,
851C3AE62113D4F90052505E /* PiPer_App.entitlements */,
85254C982100C6CA000CDDE0 /* Info.plist */,
);
path = App;
sourceTree = "<group>";
};
85254CA72100C703000CDDE0 /* Extension */ = {
isa = PBXGroup;
children = (
85A0EA7321726E12000DB27C /* Resources */,
85254CA82100C703000CDDE0 /* SafariExtensionHandler.swift */,
851C3AE72113D4FE0052505E /* PiPer_Extension.entitlements */,
85254CAF2100C703000CDDE0 /* Info.plist */,
);
path = Extension;
sourceTree = "<group>";
};
8589A341211E42FD006F9C65 /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
85A0EA7321726E12000DB27C /* Resources */ = {
isa = PBXGroup;
children = (
85A0EA7A21726E2A000DB27C /* scripts */,
85A0EA7B21726E2B000DB27C /* images */,
);
path = Resources;
sourceTree = "<group>";
};
85E505A9211E2D83003B446B /* Common */ = {
isa = PBXGroup;
children = (
85E505A7211E22A4003B446B /* Defines.h */,
85E505AA211E330F003B446B /* Defines.c */,
);
path = Common;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
85254C8B2100C6CA000CDDE0 /* PiPer */ = {
isa = PBXNativeTarget;
buildConfigurationList = 85254C9C2100C6CA000CDDE0 /* Build configuration list for PBXNativeTarget "PiPer" */;
buildPhases = (
85254C882100C6CA000CDDE0 /* Sources */,
85254C892100C6CA000CDDE0 /* Frameworks */,
85254C8A2100C6CA000CDDE0 /* Resources */,
85254CBB2100C703000CDDE0 /* Embed App Extensions */,
);
buildRules = (
);
dependencies = (
85254CB62100C703000CDDE0 /* PBXTargetDependency */,
);
name = PiPer;
productName = PiPer;
productReference = 85254C8C2100C6CA000CDDE0 /* PiPer.app */;
productType = "com.apple.product-type.application";
};
85254CA22100C703000CDDE0 /* PiPerExt */ = {
isa = PBXNativeTarget;
buildConfigurationList = 85254CB82100C703000CDDE0 /* Build configuration list for PBXNativeTarget "PiPerExt" */;
buildPhases = (
85254C9F2100C703000CDDE0 /* Sources */,
85254CA02100C703000CDDE0 /* Frameworks */,
85254CA12100C703000CDDE0 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = PiPerExt;
productName = PiPer;
productReference = 85254CA32100C703000CDDE0 /* PiPerExt.appex */;
productType = "com.apple.product-type.app-extension";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
85254C842100C6C9000CDDE0 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1000;
LastUpgradeCheck = 1000;
ORGANIZATIONNAME = "Adam Marcus";
TargetAttributes = {
85254C8B2100C6CA000CDDE0 = {
CreatedOnToolsVersion = 10.0;
LastSwiftMigration = 1000;
SystemCapabilities = {
com.apple.ApplicationGroups.Mac = {
enabled = 1;
};
com.apple.NetworkExtensions = {
enabled = 0;
};
com.apple.Sandbox = {
enabled = 1;
};
};
};
85254CA22100C703000CDDE0 = {
CreatedOnToolsVersion = 10.0;
SystemCapabilities = {
com.apple.ApplicationGroups.Mac = {
enabled = 1;
};
com.apple.NetworkExtensions = {
enabled = 0;
};
};
};
};
};
buildConfigurationList = 85254C872100C6C9000CDDE0 /* Build configuration list for PBXProject "PiPer" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 85254C832100C6C9000CDDE0;
productRefGroup = 85254C8D2100C6CA000CDDE0 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
85254C8B2100C6CA000CDDE0 /* PiPer */,
85254CA22100C703000CDDE0 /* PiPerExt */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
85254C8A2100C6CA000CDDE0 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
857DA7332116237700B38873 /* Icon.icns in Resources */,
85A0EA8621726F05000DB27C /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
85254CA12100C703000CDDE0 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
85A0EA8021726E30000DB27C /* scripts in Resources */,
85A0EA8121726E30000DB27C /* images in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
85254C882100C6CA000CDDE0 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
854061A8217167EA00F60C11 /* LocalizedButton.swift in Sources */,
85E505AB211E330F003B446B /* Defines.c in Sources */,
85254C922100C6CA000CDDE0 /* ViewController.swift in Sources */,
85254C902100C6CA000CDDE0 /* AppDelegate.swift in Sources */,
85A0EA8C2172850D000DB27C /* ResourceHelper.swift in Sources */,
854061A62171599100F60C11 /* LocalizationManager.swift in Sources */,
854061AA2172234300F60C11 /* LocalizedTextField.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
85254C9F2100C703000CDDE0 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
85254CA92100C703000CDDE0 /* SafariExtensionHandler.swift in Sources */,
85E505AC211E3339003B446B /* Defines.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
85254CB62100C703000CDDE0 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 85254CA22100C703000CDDE0 /* PiPerExt */;
targetProxy = 85254CB52100C703000CDDE0 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
85254C9A2100C6CA000CDDE0 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
APP_BUNDLE_ID = com.amarcus.PiPer;
APP_GROUP_ID = "$(TeamIdentifierPrefix)group.amarcus.piper";
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
EXTENSION_BUNDLE_ID = com.amarcus.PiPer.PiPerExt;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"APP_GROUP_ID_CONST=\"$(APP_GROUP_ID)\"",
"APP_BUNDLE_ID_CONST=\"$(APP_BUNDLE_ID)\"",
"EXTENSION_BUNDLE_ID_CONST=\"$(EXTENSION_BUNDLE_ID)\"",
"DEBUG=1",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OBJC_BRIDGING_HEADER = Common/Defines.h;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
85254C9B2100C6CA000CDDE0 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
APP_BUNDLE_ID = com.amarcus.PiPer;
APP_GROUP_ID = "$(TeamIdentifierPrefix)group.amarcus.piper";
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
EXTENSION_BUNDLE_ID = com.amarcus.PiPer.PiPerExt;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
"APP_GROUP_ID_CONST=\"$(APP_GROUP_ID)\"",
"APP_BUNDLE_ID_CONST=\"$(APP_BUNDLE_ID)\"",
"EXTENSION_BUNDLE_ID_CONST=\"$(EXTENSION_BUNDLE_ID)\"",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OBJC_BRIDGING_HEADER = Common/Defines.h;
SWIFT_OPTIMIZATION_LEVEL = "-O";
};
name = Release;
};
85254C9D2100C6CA000CDDE0 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = App/PiPer_App.entitlements;
CODE_SIGN_IDENTITY = "Mac Developer";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = App/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.12;
PRODUCT_BUNDLE_IDENTIFIER = "$(APP_BUNDLE_ID)";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.2;
};
name = Debug;
};
85254C9E2100C6CA000CDDE0 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = App/PiPer_App.entitlements;
CODE_SIGN_IDENTITY = "Mac Developer";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = App/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.12;
PRODUCT_BUNDLE_IDENTIFIER = "$(APP_BUNDLE_ID)";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 4.2;
};
name = Release;
};
85254CB92100C703000CDDE0 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = Extension/PiPer_Extension.entitlements;
CODE_SIGN_IDENTITY = "Mac Developer";
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = Extension/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@executable_path/../../../../Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = "$(EXTENSION_BUNDLE_ID)";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
SWIFT_VERSION = 4.2;
};
name = Debug;
};
85254CBA2100C703000CDDE0 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = Extension/PiPer_Extension.entitlements;
CODE_SIGN_IDENTITY = "Mac Developer";
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = Extension/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@executable_path/../../../../Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = "$(EXTENSION_BUNDLE_ID)";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
SWIFT_VERSION = 4.2;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
85254C872100C6C9000CDDE0 /* Build configuration list for PBXProject "PiPer" */ = {
isa = XCConfigurationList;
buildConfigurations = (
85254C9A2100C6CA000CDDE0 /* Debug */,
85254C9B2100C6CA000CDDE0 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
85254C9C2100C6CA000CDDE0 /* Build configuration list for PBXNativeTarget "PiPer" */ = {
isa = XCConfigurationList;
buildConfigurations = (
85254C9D2100C6CA000CDDE0 /* Debug */,
85254C9E2100C6CA000CDDE0 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
85254CB82100C703000CDDE0 /* Build configuration list for PBXNativeTarget "PiPerExt" */ = {
isa = XCConfigurationList;
buildConfigurations = (
85254CB92100C703000CDDE0 /* Debug */,
85254CBA2100C703000CDDE0 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 85254C842100C6C9000CDDE0 /* Project object */;
}
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:/Users/amarcus/Developer/PiPer Chrome/PiPer/out/PiPer-safari/PiPer.xcodeproj">
</FileRef>
</Workspace>
@@ -0,0 +1,8 @@
<?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>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -0,0 +1,5 @@
<?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/>
</plist>
@@ -0,0 +1,18 @@
<?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>BuildLocationStyle</key>
<string>UseAppPreferences</string>
<key>CustomBuildLocationType</key>
<string>RelativeToDerivedData</string>
<key>DerivedDataLocationStyle</key>
<string>Default</string>
<key>EnabledFullIndexStoreVisibility</key>
<false/>
<key>IssueFilterStyle</key>
<string>ShowActiveSchemeOnly</string>
<key>LiveSourceIssuesEnabled</key>
<true/>
</dict>
</plist>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
type = "1"
version = "2.0">
</Bucket>
@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1000"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "85254C8B2100C6CA000CDDE0"
BuildableName = "PiPer.app"
BlueprintName = "PiPer"
ReferencedContainer = "container:PiPer.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "85254C8B2100C6CA000CDDE0"
BuildableName = "PiPer.app"
BlueprintName = "PiPer"
ReferencedContainer = "container:PiPer.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "85254C8B2100C6CA000CDDE0"
BuildableName = "PiPer.app"
BlueprintName = "PiPer"
ReferencedContainer = "container:PiPer.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "85254C8B2100C6CA000CDDE0"
BuildableName = "PiPer.app"
BlueprintName = "PiPer"
ReferencedContainer = "container:PiPer.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1000"
wasCreatedForAppExtension = "YES"
version = "2.0">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "85254CA22100C703000CDDE0"
BuildableName = "PiPerExt.appex"
BlueprintName = "PiPerExt"
ReferencedContainer = "container:PiPer.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "85254C8B2100C6CA000CDDE0"
BuildableName = "PiPer.app"
BlueprintName = "PiPer"
ReferencedContainer = "container:PiPer.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "85254CA22100C703000CDDE0"
BuildableName = "PiPerExt.appex"
BlueprintName = "PiPerExt"
ReferencedContainer = "container:PiPer.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "2">
<RemoteRunnable
runnableDebuggingMode = "0"
BundleIdentifier = "com.apple.SafariTechnologyPreview"
RemotePath = "/Applications/Safari Technology Preview.app">
</RemoteRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "85254C8B2100C6CA000CDDE0"
BuildableName = "PiPer.app"
BlueprintName = "PiPer"
ReferencedContainer = "container:PiPer.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES"
launchAutomaticallySubstyle = "2">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "85254C8B2100C6CA000CDDE0"
BuildableName = "PiPer.app"
BlueprintName = "PiPer"
ReferencedContainer = "container:PiPer.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,32 @@
<?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>SchemeUserState</key>
<dict>
<key>PiPer.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>PiPerExt.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>85254C8B2100C6CA000CDDE0</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>85254CA22100C703000CDDE0</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>
+8
View File
@@ -0,0 +1,8 @@
<?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>method</key>
<string>mac-application</string>
</dict>
</plist>