snapshot current state before gitea sync

This commit is contained in:
2026-02-18 10:50:25 +01:00
parent 4b14d06bc8
commit 4f6ff705cd
31 changed files with 228 additions and 220 deletions

View File

@@ -0,0 +1,8 @@
{
"permissions": {
"allow": [
"Bash(xcodegen generate:*)",
"Bash(xcodebuild build:*)"
]
}
}

View File

@@ -1,9 +0,0 @@
import XCTest
@testable import CoopRunning
final class CoopRunningTests: XCTestCase {
func testLibraryLoads() {
let library = LocalTrack.loadLibrary()
XCTAssertNotNil(library)
}
}

View File

@@ -1,13 +1,13 @@
# CoopRunning Sync (MVP)
# Run+ Sync (MVP)
This is a minimal SwiftUI + MultipeerConnectivity prototype to sync **local MP3 playback** across iPhones. One device hosts and controls playback; peers join, receive the track file, and then sync playback.
## Setup (Xcode)
1. Create a new iOS App project in Xcode (SwiftUI, iOS 17+ or latest).
2. Replace the generated Swift files with the files in `CoopRunning/`.
2. Replace the generated Swift files with the files in `RunPlus/`.
3. Add these keys to your app's `Info.plist`:
- `NSLocalNetworkUsageDescription` = "Sync audio with nearby runners"
- `NSBonjourServices` (Array) with `_cooprun-sync._tcp`
- `NSBonjourServices` (Array) with `_runplus-sync._tcp`
- `NSBluetoothAlwaysUsageDescription` = "Find nearby runners"
## How It Works

View File

@@ -7,150 +7,150 @@
objects = {
/* Begin PBXBuildFile section */
1C5A896A43530D81174546BA /* CoopRunningTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7972CAD1B5B5FB6F3CBB4DC /* CoopRunningTests.swift */; };
2DDFF6B9DA48824AB7E348F4 /* SessionMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 989EE81E50A74AADB156B2F1 /* SessionMessage.swift */; };
4CC684E41D1241CE42FD7348 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0C06EA24EED7898D3555276 /* ContentView.swift */; };
5A81A364169B5FCD120F61FC /* PeerSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02763B5D5452C1CC1B93FD2B /* PeerSession.swift */; };
7D7B85F058BAFB619CCCE687 /* SyncClock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E882038912A0EC724092D5C /* SyncClock.swift */; };
8CB2509F6A60D8C785CD8F5F /* CoopRunningApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF044E360A40EA66C3AFE6AB /* CoopRunningApp.swift */; };
A0AA73D0AF4BDA2998897899 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 62CACEE84EEBE1E90C04433F /* LaunchScreen.storyboard */; };
A7E26605A0C2D722889DC978 /* AudioPlayerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3135CEE034E1997695E141E /* AudioPlayerController.swift */; };
BE79C4ECF76C74CA638B5E71 /* AppModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE69B1849CC70C66B4408E8D /* AppModel.swift */; };
D3F24682D211B5C8C703480A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0570D4F6BB0BB408E8A9A864 /* Assets.xcassets */; };
FBAD30B2745B7850ADC0BD10 /* LocalTrack.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82B84A69F8BDB61FB49066A1 /* LocalTrack.swift */; };
156C160DF778F27C79A17FE5 /* RunPlusTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04BCDAE10A279FB302BB43BB /* RunPlusTests.swift */; };
2F3EACD00BDE74F3B8E910EA /* LocalTrack.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C121924B17207A853051208 /* LocalTrack.swift */; };
6045F7A89ED35EFF6E1492BC /* SessionMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61EAEDFD4F6880835E95D55B /* SessionMessage.swift */; };
6115B8D560B77DC3A4D41F20 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FC6EEC5ABFC1AF6F5E370955 /* Assets.xcassets */; };
A599EACFD1739CD8B6B74BD6 /* AppModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B51D24578D9AFC6F460328F /* AppModel.swift */; };
BE5EFEFBD637CB82A50B2233 /* AudioPlayerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB42CA625F6C53318B48146F /* AudioPlayerController.swift */; };
C0C75478F495F054AD95F704 /* PeerSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F60C22FCD67282CDE8022C1 /* PeerSession.swift */; };
DD588F2D6B2FEBC85ED5A55E /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 548B11CCD7661F41B1B40FC6 /* ContentView.swift */; };
E918E7220DF266B8507D14F2 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1BF55753772F8B16D9D3C771 /* LaunchScreen.storyboard */; };
EE997CA26C6822FF70E7EC50 /* SyncClock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225E3A199DA434E89F5184DB /* SyncClock.swift */; };
F5BE435072E6FEE8D2C1E14D /* RunPlusApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8102076B5C48A26C6B1DDC68 /* RunPlusApp.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
D6C6FD151E41BF7E8F592C82 /* PBXContainerItemProxy */ = {
3B17CA897B21DAE8997359BB /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 45108C7370BA21AEC5D4E16A /* Project object */;
containerPortal = B994AC409B01DDDD340C5845 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 6D8086D1FAEE224EF0BE91DB;
remoteInfo = CoopRunning;
remoteGlobalIDString = 5C2F99C6F3AFB5DA6199A4A1;
remoteInfo = RunPlus;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
02763B5D5452C1CC1B93FD2B /* PeerSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeerSession.swift; sourceTree = "<group>"; };
0570D4F6BB0BB408E8A9A864 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
0E882038912A0EC724092D5C /* SyncClock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncClock.swift; sourceTree = "<group>"; };
62CACEE84EEBE1E90C04433F /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
642EFFBEF3D3144895D7F64A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
82B84A69F8BDB61FB49066A1 /* LocalTrack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalTrack.swift; sourceTree = "<group>"; };
955DE601980D43FC20175212 /* CoopRunningTests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = CoopRunningTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
989EE81E50A74AADB156B2F1 /* SessionMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionMessage.swift; sourceTree = "<group>"; };
A0C06EA24EED7898D3555276 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
B7972CAD1B5B5FB6F3CBB4DC /* CoopRunningTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoopRunningTests.swift; sourceTree = "<group>"; };
BE69B1849CC70C66B4408E8D /* AppModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppModel.swift; sourceTree = "<group>"; };
E3135CEE034E1997695E141E /* AudioPlayerController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlayerController.swift; sourceTree = "<group>"; };
ED1954343D7F24F4CE237989 /* CoopRunning.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = CoopRunning.app; sourceTree = BUILT_PRODUCTS_DIR; };
FF044E360A40EA66C3AFE6AB /* CoopRunningApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoopRunningApp.swift; sourceTree = "<group>"; };
04BCDAE10A279FB302BB43BB /* RunPlusTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunPlusTests.swift; sourceTree = "<group>"; };
1BF55753772F8B16D9D3C771 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
225E3A199DA434E89F5184DB /* SyncClock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncClock.swift; sourceTree = "<group>"; };
548B11CCD7661F41B1B40FC6 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
5F60C22FCD67282CDE8022C1 /* PeerSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeerSession.swift; sourceTree = "<group>"; };
61EAEDFD4F6880835E95D55B /* SessionMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionMessage.swift; sourceTree = "<group>"; };
6B51D24578D9AFC6F460328F /* AppModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppModel.swift; sourceTree = "<group>"; };
76A1F7156ED86F810D6BC595 /* RunPlusTests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = RunPlusTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
7C121924B17207A853051208 /* LocalTrack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalTrack.swift; sourceTree = "<group>"; };
8102076B5C48A26C6B1DDC68 /* RunPlusApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunPlusApp.swift; sourceTree = "<group>"; };
D5367D3BD526DC39625C926B /* RunPlus.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = RunPlus.app; sourceTree = BUILT_PRODUCTS_DIR; };
FB42CA625F6C53318B48146F /* AudioPlayerController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlayerController.swift; sourceTree = "<group>"; };
FC6EEC5ABFC1AF6F5E370955 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
FEF92C3E8A9DE5401F78BC82 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXGroup section */
0BCFD2D05DA713EECDE3A555 /* CoopRunning */ = {
28F7A30277F0012AB3487E15 /* Products */ = {
isa = PBXGroup;
children = (
BE69B1849CC70C66B4408E8D /* AppModel.swift */,
0570D4F6BB0BB408E8A9A864 /* Assets.xcassets */,
E3135CEE034E1997695E141E /* AudioPlayerController.swift */,
A0C06EA24EED7898D3555276 /* ContentView.swift */,
FF044E360A40EA66C3AFE6AB /* CoopRunningApp.swift */,
642EFFBEF3D3144895D7F64A /* Info.plist */,
62CACEE84EEBE1E90C04433F /* LaunchScreen.storyboard */,
82B84A69F8BDB61FB49066A1 /* LocalTrack.swift */,
02763B5D5452C1CC1B93FD2B /* PeerSession.swift */,
989EE81E50A74AADB156B2F1 /* SessionMessage.swift */,
0E882038912A0EC724092D5C /* SyncClock.swift */,
);
path = CoopRunning;
sourceTree = "<group>";
};
6F5BDF622927472CD32D0CD8 = {
isa = PBXGroup;
children = (
0BCFD2D05DA713EECDE3A555 /* CoopRunning */,
927D95C70CE5ED7ADB2C3F20 /* CoopRunningTests */,
CBC491D93FB088E0E6148B1A /* Products */,
);
sourceTree = "<group>";
};
927D95C70CE5ED7ADB2C3F20 /* CoopRunningTests */ = {
isa = PBXGroup;
children = (
B7972CAD1B5B5FB6F3CBB4DC /* CoopRunningTests.swift */,
);
path = CoopRunningTests;
sourceTree = "<group>";
};
CBC491D93FB088E0E6148B1A /* Products */ = {
isa = PBXGroup;
children = (
ED1954343D7F24F4CE237989 /* CoopRunning.app */,
955DE601980D43FC20175212 /* CoopRunningTests.xctest */,
D5367D3BD526DC39625C926B /* RunPlus.app */,
76A1F7156ED86F810D6BC595 /* RunPlusTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
6F346E56B2A585AA296F164F /* RunPlus */ = {
isa = PBXGroup;
children = (
6B51D24578D9AFC6F460328F /* AppModel.swift */,
FC6EEC5ABFC1AF6F5E370955 /* Assets.xcassets */,
FB42CA625F6C53318B48146F /* AudioPlayerController.swift */,
548B11CCD7661F41B1B40FC6 /* ContentView.swift */,
FEF92C3E8A9DE5401F78BC82 /* Info.plist */,
1BF55753772F8B16D9D3C771 /* LaunchScreen.storyboard */,
7C121924B17207A853051208 /* LocalTrack.swift */,
5F60C22FCD67282CDE8022C1 /* PeerSession.swift */,
8102076B5C48A26C6B1DDC68 /* RunPlusApp.swift */,
61EAEDFD4F6880835E95D55B /* SessionMessage.swift */,
225E3A199DA434E89F5184DB /* SyncClock.swift */,
);
path = RunPlus;
sourceTree = "<group>";
};
7A2EECCE69D919AAD7ECDDAB = {
isa = PBXGroup;
children = (
6F346E56B2A585AA296F164F /* RunPlus */,
BCCE23592AD997519492634F /* RunPlusTests */,
28F7A30277F0012AB3487E15 /* Products */,
);
sourceTree = "<group>";
};
BCCE23592AD997519492634F /* RunPlusTests */ = {
isa = PBXGroup;
children = (
04BCDAE10A279FB302BB43BB /* RunPlusTests.swift */,
);
path = RunPlusTests;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
6D8086D1FAEE224EF0BE91DB /* CoopRunning */ = {
5C2F99C6F3AFB5DA6199A4A1 /* RunPlus */ = {
isa = PBXNativeTarget;
buildConfigurationList = 5E860FBA956CBCBD03474441 /* Build configuration list for PBXNativeTarget "CoopRunning" */;
buildConfigurationList = FE58DB119F93CB8FCB3C5149 /* Build configuration list for PBXNativeTarget "RunPlus" */;
buildPhases = (
D35AAFE1ED99AD91623FC374 /* Sources */,
04C5D543DEB4F3CC401E7D42 /* Resources */,
BAAFDC05404E8AF42DA6E627 /* Sources */,
886AB81AC1EDA136A589C3B8 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = CoopRunning;
name = RunPlus;
packageProductDependencies = (
);
productName = CoopRunning;
productReference = ED1954343D7F24F4CE237989 /* CoopRunning.app */;
productName = RunPlus;
productReference = D5367D3BD526DC39625C926B /* RunPlus.app */;
productType = "com.apple.product-type.application";
};
7176FDC3954B3226DB5DEE48 /* CoopRunningTests */ = {
F407DEF9415CB11EF9A62BDD /* RunPlusTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 2322A6CDF4FC2AE59DD780B1 /* Build configuration list for PBXNativeTarget "CoopRunningTests" */;
buildConfigurationList = 19B80B19E7591F6011762D0C /* Build configuration list for PBXNativeTarget "RunPlusTests" */;
buildPhases = (
A54C28822F541CFCD33553AE /* Sources */,
EC0BC2D44C8A66ADAF3023C5 /* Sources */,
);
buildRules = (
);
dependencies = (
6D8868D6D8F73E641CA58B0F /* PBXTargetDependency */,
1C54C143DF90D15B0BF852E1 /* PBXTargetDependency */,
);
name = CoopRunningTests;
name = RunPlusTests;
packageProductDependencies = (
);
productName = CoopRunningTests;
productReference = 955DE601980D43FC20175212 /* CoopRunningTests.xctest */;
productName = RunPlusTests;
productReference = 76A1F7156ED86F810D6BC595 /* RunPlusTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
45108C7370BA21AEC5D4E16A /* Project object */ = {
B994AC409B01DDDD340C5845 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastUpgradeCheck = 1430;
TargetAttributes = {
6D8086D1FAEE224EF0BE91DB = {
5C2F99C6F3AFB5DA6199A4A1 = {
DevelopmentTeam = NG5W75WE8U;
ProvisioningStyle = Automatic;
};
7176FDC3954B3226DB5DEE48 = {
F407DEF9415CB11EF9A62BDD = {
DevelopmentTeam = NG5W75WE8U;
ProvisioningStyle = Automatic;
};
};
};
buildConfigurationList = 3BCFE323CCC2757AAFD6F452 /* Build configuration list for PBXProject "CoopRunning" */;
buildConfigurationList = CAC938FDE280688F31DE0CE4 /* Build configuration list for PBXProject "RunPlus" */;
compatibilityVersion = "Xcode 14.0";
developmentRegion = en;
hasScannedForEncodings = 0;
@@ -158,66 +158,85 @@
Base,
en,
);
mainGroup = 6F5BDF622927472CD32D0CD8;
mainGroup = 7A2EECCE69D919AAD7ECDDAB;
minimizedProjectReferenceProxies = 1;
preferredProjectObjectVersion = 77;
projectDirPath = "";
projectRoot = "";
targets = (
6D8086D1FAEE224EF0BE91DB /* CoopRunning */,
7176FDC3954B3226DB5DEE48 /* CoopRunningTests */,
5C2F99C6F3AFB5DA6199A4A1 /* RunPlus */,
F407DEF9415CB11EF9A62BDD /* RunPlusTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
04C5D543DEB4F3CC401E7D42 /* Resources */ = {
886AB81AC1EDA136A589C3B8 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D3F24682D211B5C8C703480A /* Assets.xcassets in Resources */,
A0AA73D0AF4BDA2998897899 /* LaunchScreen.storyboard in Resources */,
6115B8D560B77DC3A4D41F20 /* Assets.xcassets in Resources */,
E918E7220DF266B8507D14F2 /* LaunchScreen.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
A54C28822F541CFCD33553AE /* Sources */ = {
BAAFDC05404E8AF42DA6E627 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1C5A896A43530D81174546BA /* CoopRunningTests.swift in Sources */,
A599EACFD1739CD8B6B74BD6 /* AppModel.swift in Sources */,
BE5EFEFBD637CB82A50B2233 /* AudioPlayerController.swift in Sources */,
DD588F2D6B2FEBC85ED5A55E /* ContentView.swift in Sources */,
2F3EACD00BDE74F3B8E910EA /* LocalTrack.swift in Sources */,
C0C75478F495F054AD95F704 /* PeerSession.swift in Sources */,
F5BE435072E6FEE8D2C1E14D /* RunPlusApp.swift in Sources */,
6045F7A89ED35EFF6E1492BC /* SessionMessage.swift in Sources */,
EE997CA26C6822FF70E7EC50 /* SyncClock.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D35AAFE1ED99AD91623FC374 /* Sources */ = {
EC0BC2D44C8A66ADAF3023C5 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BE79C4ECF76C74CA638B5E71 /* AppModel.swift in Sources */,
A7E26605A0C2D722889DC978 /* AudioPlayerController.swift in Sources */,
4CC684E41D1241CE42FD7348 /* ContentView.swift in Sources */,
8CB2509F6A60D8C785CD8F5F /* CoopRunningApp.swift in Sources */,
FBAD30B2745B7850ADC0BD10 /* LocalTrack.swift in Sources */,
5A81A364169B5FCD120F61FC /* PeerSession.swift in Sources */,
2DDFF6B9DA48824AB7E348F4 /* SessionMessage.swift in Sources */,
7D7B85F058BAFB619CCCE687 /* SyncClock.swift in Sources */,
156C160DF778F27C79A17FE5 /* RunPlusTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
6D8868D6D8F73E641CA58B0F /* PBXTargetDependency */ = {
1C54C143DF90D15B0BF852E1 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 6D8086D1FAEE224EF0BE91DB /* CoopRunning */;
targetProxy = D6C6FD151E41BF7E8F592C82 /* PBXContainerItemProxy */;
target = 5C2F99C6F3AFB5DA6199A4A1 /* RunPlus */;
targetProxy = 3B17CA897B21DAE8997359BB /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
2A934AD016F05C8A94BF4DA8 /* Debug */ = {
025387CAFEC9F8982D05EAB3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
INFOPLIST_FILE = RunPlus/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LOCALIZED_STRING_SWIFT_SYMBOLS = YES;
PRODUCT_NAME = RunPlus;
SDKROOT = iphoneos;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_STRING_CATALOGS = YES;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
029D8ED443D4276C1F9AF969 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
@@ -231,22 +250,22 @@
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_STRING_CATALOGS = YES;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CoopRunning.app/CoopRunning";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RunPlus.app/RunPlus";
};
name = Debug;
name = Release;
};
5FDDE7CAF9D800EFEF79CEAB /* Release */ = {
7498E61B3963591BED3C7A48 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
INFOPLIST_FILE = CoopRunning/Info.plist;
INFOPLIST_FILE = RunPlus/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LOCALIZED_STRING_SWIFT_SYMBOLS = YES;
PRODUCT_NAME = CoopRunning;
PRODUCT_NAME = RunPlus;
SDKROOT = iphoneos;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_STRING_CATALOGS = YES;
@@ -254,44 +273,7 @@
};
name = Release;
};
84DDC04A355E486EE89AC7F8 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
LOCALIZED_STRING_SWIFT_SYMBOLS = YES;
SDKROOT = iphoneos;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_STRING_CATALOGS = YES;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CoopRunning.app/CoopRunning";
};
name = Release;
};
B10B4E0B66978D394F8DD3C9 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
INFOPLIST_FILE = CoopRunning/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LOCALIZED_STRING_SWIFT_SYMBOLS = YES;
PRODUCT_NAME = CoopRunning;
SDKROOT = iphoneos;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_STRING_CATALOGS = YES;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
DE756993C972E7F7EDB4067D /* Debug */ = {
7A3BDC985CAD548B3291FD0F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
@@ -351,14 +333,14 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
GENERATE_INFOPLIST_FILE = NO;
INFOPLIST_FILE = CoopRunning/Info.plist;
INFOPLIST_FILE = RunPlus/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 26.0;
LOCALIZED_STRING_SWIFT_SYMBOLS = YES;
MARKETING_VERSION = 0.1.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = de.felixfoertsch.cooprunning;
PRODUCT_BUNDLE_IDENTIFIER = de.felixfoertsch.runplus;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = iphoneos;
@@ -371,7 +353,25 @@
};
name = Debug;
};
F630219557065594A62AFA33 /* Release */ = {
86C6A2723CE077891FDDBB19 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
LOCALIZED_STRING_SWIFT_SYMBOLS = YES;
SDKROOT = iphoneos;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_STRING_CATALOGS = YES;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RunPlus.app/RunPlus";
};
name = Debug;
};
C273DFDF1D50D371159338ED /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
@@ -425,13 +425,13 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
GENERATE_INFOPLIST_FILE = NO;
INFOPLIST_FILE = CoopRunning/Info.plist;
INFOPLIST_FILE = RunPlus/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 26.0;
LOCALIZED_STRING_SWIFT_SYMBOLS = YES;
MARKETING_VERSION = 0.1.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = de.felixfoertsch.cooprunning;
PRODUCT_BUNDLE_IDENTIFIER = de.felixfoertsch.runplus;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = iphoneos;
@@ -447,34 +447,34 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
2322A6CDF4FC2AE59DD780B1 /* Build configuration list for PBXNativeTarget "CoopRunningTests" */ = {
19B80B19E7591F6011762D0C /* Build configuration list for PBXNativeTarget "RunPlusTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2A934AD016F05C8A94BF4DA8 /* Debug */,
84DDC04A355E486EE89AC7F8 /* Release */,
86C6A2723CE077891FDDBB19 /* Debug */,
029D8ED443D4276C1F9AF969 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
3BCFE323CCC2757AAFD6F452 /* Build configuration list for PBXProject "CoopRunning" */ = {
CAC938FDE280688F31DE0CE4 /* Build configuration list for PBXProject "RunPlus" */ = {
isa = XCConfigurationList;
buildConfigurations = (
DE756993C972E7F7EDB4067D /* Debug */,
F630219557065594A62AFA33 /* Release */,
7A3BDC985CAD548B3291FD0F /* Debug */,
C273DFDF1D50D371159338ED /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
5E860FBA956CBCBD03474441 /* Build configuration list for PBXNativeTarget "CoopRunning" */ = {
FE58DB119F93CB8FCB3C5149 /* Build configuration list for PBXNativeTarget "RunPlus" */ = {
isa = XCConfigurationList;
buildConfigurations = (
B10B4E0B66978D394F8DD3C9 /* Debug */,
5FDDE7CAF9D800EFEF79CEAB /* Release */,
025387CAFEC9F8982D05EAB3 /* Debug */,
7498E61B3963591BED3C7A48 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
/* End XCConfigurationList section */
};
rootObject = 45108C7370BA21AEC5D4E16A /* Project object */;
rootObject = B994AC409B01DDDD340C5845 /* Project object */;
}

View File

@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:CoopRunning.xcodeproj">
location = "self:">
</FileRef>
</Workspace>

View File

@@ -15,10 +15,10 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6D8086D1FAEE224EF0BE91DB"
BuildableName = "CoopRunning.app"
BlueprintName = "CoopRunning"
ReferencedContainer = "container:CoopRunning.xcodeproj">
BlueprintIdentifier = "5C2F99C6F3AFB5DA6199A4A1"
BuildableName = "RunPlus.app"
BlueprintName = "RunPlus"
ReferencedContainer = "container:RunPlus.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
@@ -32,10 +32,10 @@
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6D8086D1FAEE224EF0BE91DB"
BuildableName = "CoopRunning.app"
BlueprintName = "CoopRunning"
ReferencedContainer = "container:CoopRunning.xcodeproj">
BlueprintIdentifier = "5C2F99C6F3AFB5DA6199A4A1"
BuildableName = "RunPlus.app"
BlueprintName = "RunPlus"
ReferencedContainer = "container:RunPlus.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
@@ -44,10 +44,10 @@
parallelizable = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7176FDC3954B3226DB5DEE48"
BuildableName = "CoopRunningTests.xctest"
BlueprintName = "CoopRunningTests"
ReferencedContainer = "container:CoopRunning.xcodeproj">
BlueprintIdentifier = "F407DEF9415CB11EF9A62BDD"
BuildableName = "RunPlusTests.xctest"
BlueprintName = "RunPlusTests"
ReferencedContainer = "container:RunPlus.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
@@ -68,10 +68,10 @@
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6D8086D1FAEE224EF0BE91DB"
BuildableName = "CoopRunning.app"
BlueprintName = "CoopRunning"
ReferencedContainer = "container:CoopRunning.xcodeproj">
BlueprintIdentifier = "5C2F99C6F3AFB5DA6199A4A1"
BuildableName = "RunPlus.app"
BlueprintName = "RunPlus"
ReferencedContainer = "container:RunPlus.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
@@ -85,10 +85,10 @@
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6D8086D1FAEE224EF0BE91DB"
BuildableName = "CoopRunning.app"
BlueprintName = "CoopRunning"
ReferencedContainer = "container:CoopRunning.xcodeproj">
BlueprintIdentifier = "5C2F99C6F3AFB5DA6199A4A1"
BuildableName = "RunPlus.app"
BlueprintName = "RunPlus"
ReferencedContainer = "container:RunPlus.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>

View File

Before

Width:  |  Height:  |  Size: 154 KiB

After

Width:  |  Height:  |  Size: 154 KiB

View File

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

@@ -42,7 +42,7 @@ struct ContentView: View {
private var header: some View {
VStack(spacing: 6) {
Text("CoopRunning Sync")
Text("Run+")
.font(.title2).bold()
Text(appModel.statusText)
.font(.footnote)

View File

@@ -5,7 +5,7 @@
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>CoopRunning</string>
<string>Run+</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
@@ -26,7 +26,7 @@
<string>Find nearby runners</string>
<key>NSBonjourServices</key>
<array>
<string>_cooprun-sync._tcp</string>
<string>_runplus-sync._tcp</string>
</array>
<key>NSLocalNetworkUsageDescription</key>
<string>Sync audio with nearby runners</string>

View File

@@ -8,7 +8,7 @@
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="390" height="844"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="CoopRunning" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1aC-zt-x8B">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Run+" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1aC-zt-x8B">
<rect key="frame" x="120" y="412" width="150" height="20"/>
<fontDescription key="fontDescription" type="system" pointSize="17" weight="semibold"/>
<color key="textColor" systemColor="labelColor"/>

View File

@@ -9,7 +9,7 @@ struct LocalTrack: Identifiable, Hashable {
static func libraryDirectory() -> URL {
let docs = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let dir = docs.appendingPathComponent("CoopRunning", isDirectory: true)
let dir = docs.appendingPathComponent("RunPlus", isDirectory: true)
if !FileManager.default.fileExists(atPath: dir.path) {
try? FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true)
}

View File

@@ -10,7 +10,7 @@ final class PeerSession: NSObject, ObservableObject {
var onMessage: ((SessionMessage) -> Void)?
var onReceiveResource: ((String, URL) -> Void)?
private let serviceType = "cooprun-sync"
private let serviceType = "runplus-sync"
private let myPeerID = MCPeerID(displayName: UIDevice.current.name)
private var session: MCSession!

View File

@@ -1,7 +1,7 @@
import SwiftUI
@main
struct CoopRunningApp: App {
struct RunPlusApp: App {
@StateObject private var appModel = AppModel()
var body: some Scene {

View File

@@ -0,0 +1,9 @@
import XCTest
@testable import RunPlus
final class RunPlusTests: XCTestCase {
func testLibraryLoads() {
let library = LocalTrack.loadLibrary()
XCTAssertNotNil(library)
}
}

View File

@@ -1,4 +1,4 @@
name: CoopRunning
name: RunPlus
options:
bundleIdPrefix: de.felixfoertsch
deploymentTarget:
@@ -8,9 +8,9 @@ settings:
SWIFT_VERSION: 5.9
DEVELOPMENT_ASSET_PATHS: ""
TARGETED_DEVICE_FAMILY: "1" # iPhone
INFOPLIST_FILE: CoopRunning/Info.plist
INFOPLIST_FILE: RunPlus/Info.plist
CODE_SIGN_STYLE: Automatic
PRODUCT_BUNDLE_IDENTIFIER: de.felixfoertsch.cooprunning
PRODUCT_BUNDLE_IDENTIFIER: de.felixfoertsch.runplus
DEVELOPMENT_TEAM: NG5W75WE8U
CODE_SIGN_IDENTITY: "Apple Development"
PROVISIONING_PROFILE_SPECIFIER: ""
@@ -29,33 +29,33 @@ configs:
Release: release
schemes:
CoopRunning:
RunPlus:
build:
targets:
CoopRunning: all
RunPlus: all
test:
targets:
- CoopRunningTests
- RunPlusTests
targets:
CoopRunning:
RunPlus:
type: application
platform: iOS
sources:
- path: CoopRunning
- path: RunPlus
resources:
- path: CoopRunning/LaunchScreen.storyboard
- path: RunPlus/LaunchScreen.storyboard
settings:
base:
PRODUCT_NAME: CoopRunning
PRODUCT_NAME: RunPlus
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
LOCALIZED_STRING_SWIFT_SYMBOLS: "YES"
SWIFT_STRING_CATALOGS: "YES"
STRING_CATALOG_GENERATE_SYMBOLS: "YES"
info:
path: CoopRunning/Info.plist
path: RunPlus/Info.plist
properties:
CFBundleDisplayName: CoopRunning
CFBundleDisplayName: "Run+"
LSRequiresIPhoneOS: true
UILaunchStoryboardName: LaunchScreen
UISupportedInterfaceOrientations:
@@ -65,16 +65,16 @@ targets:
- UIInterfaceOrientationLandscapeRight
NSLocalNetworkUsageDescription: "Sync audio with nearby runners"
NSBonjourServices:
- "_cooprun-sync._tcp"
- "_runplus-sync._tcp"
NSBluetoothAlwaysUsageDescription: "Find nearby runners"
CoopRunningTests:
RunPlusTests:
type: bundle.unit-test
platform: iOS
sources:
- path: CoopRunningTests
- path: RunPlusTests
dependencies:
- target: CoopRunning
- target: RunPlus
settings:
base:
LOCALIZED_STRING_SWIFT_SYMBOLS: "YES"