Development Setup - MKS2508/MKS-IPTV-App GitHub Wiki

<style> body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; line-height: 1.6; color: #333; max-width: 960px; margin: 0 auto; padding: 20px; } h1, h2, h3, h4, h5, h6 { font-weight: 600; color: #111; } a { color: #0366d6; text-decoration: none; } a:hover { text-decoration: underline; } code { font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; background-color: #f6f8fa; padding: .2em .4em; margin: 0; font-size: 85%; border-radius: 3px; } pre { background-color: #f6f8fa; padding: 16px; overflow: auto; line-height: 1.45; border-radius: 3px; } pre code { padding: 0; margin: 0; font-size: 100%; background-color: transparent; border: 0; } footer { margin-top: 40px; padding-top: 20px; border-top: 1px solid #eee; font-size: 12px; color: #586069; } </style>

Home > Development > Development Setup

โš™๏ธ Development Setup

Complete guide for setting up a development environment for MKS-IPTV-App contributors.


๐ŸŽฏ Prerequisites

Required Software

Tool Version Purpose
Xcode 16 Beta+ Primary IDE and compiler
macOS 26 Beta+ Development platform
Swift 6.0+ Language runtime
Git 2.30+ Version control

Apple Developer Account

  • Free Account: Sufficient for simulator testing and basic development
  • Paid Account: Required for device deployment and distribution
  • Enterprise Account: For internal distribution (optional)

๐Ÿ”ง Environment Setup

1. Clone the Repository

# Clone the main repository
git clone https://github.com/MKS2508/MKS-IPTV-App.git
cd MKS-IPTV-App

# Create your feature branch
git checkout -b feature/your-feature-name

2. Xcode Configuration

Project Settings

# Open project in Xcode
open mks-multiplatform-iptv.xcodeproj

Code Signing Setup

  1. Select Project โ†’ Signing & Capabilities
  2. Team: Select your Apple Developer team
  3. Bundle Identifier: Use unique identifier (e.g., com.yourname.mks-iptv)
  4. Automatic Signing: Enable for development

Build Schemes Configuration

  • mks-multiplatform-iptv: Main iOS/macOS app
  • mks-multiplataforma-tvos-iptv: tvOS variant
  • Debug: Development with debug symbols
  • Release: Optimized builds for distribution

3. Dependencies Management

Swift Package Manager

The project uses SPM for dependency management. Dependencies are defined in Package.swift (if present) or integrated directly in Xcode.

Adding New Dependencies:

  1. File โ†’ Add Package Dependencies
  2. Enter package URL
  3. Select version requirements
  4. Choose target integration

Common Dependencies

// Example Package.swift structure
// swift-tools-version:5.9
import PackageDescription

let package = Package(
    name: "MKS-IPTV-App",
    platforms: [
        .iOS(.v17),
        .macOS(.v14),
        .tvOS(.v17)
    ],
    dependencies: [
        // Add external dependencies here
        .package(url: "https://github.com/apple/swift-log.git", from: "1.0.0")
    ],
    targets: [
        .target(
            name: "IPTVCore",
            dependencies: [
                .product(name: "Logging", package: "swift-log")
            ]
        )
    ]
)

๐Ÿ—๏ธ Project Structure Deep Dive

Directory Organization

mks-multiplatform-iptv/
โ”œโ”€โ”€ IPTVDownloader/                 # Main app target
โ”‚   โ”œโ”€โ”€ Core/                      # Core functionality
โ”‚   โ”‚   โ”œโ”€โ”€ Configuration/         # App configuration
โ”‚   โ”‚   โ”œโ”€โ”€ Networking/           # Network layer
โ”‚   โ”‚   โ””โ”€โ”€ Player/               # Video player components
โ”‚   โ”œโ”€โ”€ Features/                 # Feature modules
โ”‚   โ”‚   โ”œโ”€โ”€ Downloads/            # Download management
โ”‚   โ”‚   โ”œโ”€โ”€ LiveChannels/         # Live TV streaming
โ”‚   โ”‚   โ”œโ”€โ”€ Movies/               # VOD Movies
โ”‚   โ”‚   โ”œโ”€โ”€ Series/               # VOD Series
โ”‚   โ”‚   โ””โ”€โ”€ TouchBar/             # macOS TouchBar
โ”‚   โ”œโ”€โ”€ Models/                   # Data models
โ”‚   โ”œโ”€โ”€ Services/                 # Business logic services
โ”‚   โ”œโ”€โ”€ Utils/                    # Utility functions
โ”‚   โ””โ”€โ”€ Views/                    # SwiftUI views
โ”œโ”€โ”€ mks-multiplataforma-tvos-iptv/ # tvOS target
โ”œโ”€โ”€ Shared/                       # Shared components
โ”œโ”€โ”€ Tests/                        # Unit tests
โ””โ”€โ”€ UITests/                      # UI automation tests

Code Organization Principles

MVVM Architecture

// Model
struct IPTVStream: Codable, Identifiable {
    let id: UUID
    let name: String
    let url: URL
}

// View
struct StreamListView: View {
    @StateObject private var viewModel = StreamListViewModel()
    
    var body: some View {
        List(viewModel.streams) { stream in
            StreamRowView(stream: stream)
        }
    }
}

// ViewModel
@MainActor
class StreamListViewModel: ObservableObject {
    @Published var streams: [IPTVStream] = []
    
    func loadStreams() async {
        // Business logic here
    }
}

Actor-Based Services

actor StreamManager {
    private var activeStreams: [UUID: AVPlayer] = [:]
    
    func createStream(url: URL) async throws -> UUID {
        let streamId = UUID()
        let player = AVPlayer(url: url)
        activeStreams[streamId] = player
        return streamId
    }
}

๐ŸŽจ Code Style Guidelines

Swift Style Guide

Naming Conventions

// Types: PascalCase
class StreamManager { }
struct IPTVConfiguration { }
enum PlaybackState { }

// Variables and functions: camelCase
var currentStream: IPTVStream?
func loadStream(_ url: URL) async throws

// Constants: camelCase
let maxRetryAttempts = 3
let defaultTimeout: TimeInterval = 30

// Private properties: leading underscore (optional)
private var _internalCache: [String: Any] = [:]

Function Documentation

/// Loads and prepares an IPTV stream for playback
/// - Parameters:
///   - url: The stream URL to load
///   - metadata: Optional stream metadata
/// - Returns: Unique identifier for the stream session
/// - Throws: `StreamError` if the stream cannot be loaded
func loadStream(
    _ url: URL, 
    metadata: StreamMetadata? = nil
) async throws -> UUID {
    // Implementation
}

Error Handling

enum StreamError: LocalizedError {
    case invalidURL(URL)
    case networkFailure(Error)
    case unsupportedFormat
    
    var errorDescription: String? {
        switch self {
        case .invalidURL(let url):
            return "Invalid stream URL: \(url)"
        case .networkFailure(let error):
            return "Network error: \(error.localizedDescription)"
        case .unsupportedFormat:
            return "Unsupported stream format"
        }
    }
}

SwiftUI Best Practices

View Composition

// Break down complex views
struct ContentView: View {
    var body: some View {
        NavigationStack {
            PlatformNavigationView {
                MainContentArea()
            }
        }
        .overlay(alignment: .bottom) {
            PlayerControlsOverlay()
        }
    }
}

// Extract subviews
struct MainContentArea: View {
    var body: some View {
        TabView {
            LiveTVView()
                .tabItem { Label("Live TV", systemImage: "tv") }
            
            MoviesView()
                .tabItem { Label("Movies", systemImage: "film") }
        }
    }
}

State Management

// Use @StateObject for owned objects
struct ContentView: View {
    @StateObject private var downloadManager = DownloadManager()
    
    var body: some View {
        // View content
    }
}

// Use @ObservedObject for injected dependencies
struct DownloadListView: View {
    @ObservedObject var downloadManager: DownloadManager
    
    var body: some View {
        // View content
    }
}

๐Ÿงช Testing Setup

Unit Testing Structure

import XCTest
@testable import IPTVDownloader

@MainActor
final class StreamManagerTests: XCTestCase {
    var streamManager: StreamManager!
    var mockNetworkService: MockNetworkService!
    
    override func setUp() async throws {
        mockNetworkService = MockNetworkService()
        streamManager = StreamManager(networkService: mockNetworkService)
    }
    
    override func tearDown() async throws {
        streamManager = nil
        mockNetworkService = nil
    }
    
    func testStreamLoading() async throws {
        // Given
        let testURL = URL(string: "https://test.stream.url")!
        mockNetworkService.shouldSucceed = true
        
        // When
        let streamId = try await streamManager.loadStream(testURL)
        
        // Then
        XCTAssertNotNil(streamId)
        XCTAssertTrue(mockNetworkService.loadStreamCalled)
    }
}

UI Testing Setup

import XCTest

final class IPTVAppUITests: XCTestCase {
    var app: XCUIApplication!
    
    override func setUp() {
        continueAfterFailure = false
        app = XCUIApplication()
        app.launchEnvironment["TESTING"] = "1"
        app.launch()
    }
    
    func testDownloadFlow() throws {
        // Navigate to Downloads
        app.tabBars.buttons["Downloads"].tap()
        
        // Verify empty state
        XCTAssertTrue(app.staticTexts["No Downloads"].exists)
        
        // Test download initiation
        // (Implementation depends on UI flow)
    }
}

Mock Services

#if DEBUG
class MockStreamService: StreamServiceProtocol {
    var shouldSucceed = true
    var loadStreamCalled = false
    var mockStreams: [IPTVStream] = []
    
    func loadStream(_ url: URL) async throws -> UUID {
        loadStreamCalled = true
        
        if !shouldSucceed {
            throw StreamError.networkFailure(URLError(.networkConnectionLost))
        }
        
        return UUID()
    }
    
    func fetchStreams() async throws -> [IPTVStream] {
        return mockStreams
    }
}
#endif

๐Ÿ”ง Build Configuration

Build Settings

Debug Configuration

// Debug preprocessor macros
#if DEBUG
let isDebugBuild = true
let logLevel: LogLevel = .debug
let apiBaseURL = URL(string: "https://dev-api.example.com")!
#else
let isDebugBuild = false
let logLevel: LogLevel = .error
let apiBaseURL = URL(string: "https://api.example.com")!
#endif

Custom Build Schemes

Development Scheme:

  • Configuration: Debug
  • Code Signing: Automatic
  • Preprocessor Macros: DEBUG=1, DEVELOPMENT=1

Testing Scheme:

  • Configuration: Debug
  • Code Signing: Automatic
  • Preprocessor Macros: DEBUG=1, TESTING=1
  • Test Plans: All test targets

Release Scheme:

  • Configuration: Release
  • Code Signing: Manual (Distribution)
  • Preprocessor Macros: RELEASE=1
  • Optimization: Aggressive

Platform-Specific Builds

iOS Build Configuration

# Debug build for simulator
xcodebuild -project mks-multiplatform-iptv.xcodeproj \
  -scheme mks-multiplatform-iptv \
  -destination 'platform=iOS Simulator,name=iPhone 15 Pro' \
  -configuration Debug \
  build

# Device build (requires provisioning profile)
xcodebuild -project mks-multiplatform-iptv.xcodeproj \
  -scheme mks-multiplatform-iptv \
  -destination 'platform=iOS,name=My iPhone' \
  -configuration Debug \
  build

macOS Build Configuration

# Native macOS build
xcodebuild -project mks-multiplatform-iptv.xcodeproj \
  -scheme mks-multiplatform-iptv \
  -destination 'platform=macOS' \
  -configuration Debug \
  build

# Universal binary (Intel + Apple Silicon)
xcodebuild -project mks-multiplatform-iptv.xcodeproj \
  -scheme mks-multiplatform-iptv \
  -destination 'platform=macOS,arch=x86_64' \
  -configuration Release \
  ARCHS="arm64 x86_64" \
  build

tvOS Build Configuration

# tvOS simulator build
xcodebuild -project mks-multiplatform-iptv.xcodeproj \
  -scheme mks-multiplataforma-tvos-iptv \
  -destination 'platform=tvOS Simulator,name=Apple TV' \
  -configuration Debug \
  build

# Apple TV device build
xcodebuild -project mks-multiplatform-iptv.xcodeproj \
  -scheme mks-multiplataforma-tvos-iptv \
  -destination 'platform=tvOS,name=My Apple TV' \
  -configuration Debug \
  build

๐Ÿš€ Running and Debugging

Launch Configuration

Environment Variables

// Set in Xcode Scheme โ†’ Run โ†’ Environment Variables
TESTING=1              // Enable testing mode
DEBUG_NETWORKING=1     // Verbose network logging
MOCK_STREAMS=1         // Use mock stream data
LOG_LEVEL=DEBUG        // Set logging level

Launch Arguments

// Set in Xcode Scheme โ†’ Run โ†’ Arguments Passed On Launch
-com.apple.CoreData.SQLDebug 1    // Core Data SQL logging
-com.apple.CoreData.Logging.stderr 1    // Core Data error logging

Debugging Tools

Network Debugging

#if DEBUG
extension URLSession {
    static let debug: URLSession = {
        let config = URLSessionConfiguration.default
        config.protocolClasses = [NetworkLoggingProtocol.self]
        return URLSession(configuration: config)
    }()
}

class NetworkLoggingProtocol: URLProtocol {
    override func startLoading() {
        print("๐ŸŒ Network Request: \(request.url?.absoluteString ?? "Unknown")")
        // Log request details
    }
}
#endif

Memory Debugging

#if DEBUG
import os

class MemoryMonitor {
    private let logger = Logger(subsystem: "com.mks.iptv", category: "memory")
    
    func logMemoryUsage() {
        let info = mach_task_basic_info()
        var count = mach_msg_type_number_t(MemoryLayout<mach_task_basic_info>.size)/4
        
        let kerr: kern_return_t = withUnsafeMutablePointer(to: &info) {
            $0.withMemoryRebound(to: integer_t.self, capacity: 1) {
                task_info(mach_task_self_,
                         task_flavor_t(MACH_TASK_BASIC_INFO),
                         $0,
                         &count)
            }
        }
        
        if kerr == KERN_SUCCESS {
            let memoryUsage = Float(info.resident_size) / 1024.0 / 1024.0
            logger.debug("Memory usage: \(memoryUsage, format: .fixed(precision: 2)) MB")
        }
    }
}
#endif

๐Ÿ“ฆ Continuous Integration

GitHub Actions Workflow

name: CI

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: macos-14
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Select Xcode
      run: sudo xcode-select -switch /Applications/Xcode_16.0.app/Contents/Developer
    
    - name: Build and Test iOS
      run: |
        xcodebuild test \
          -project mks-multiplatform-iptv.xcodeproj \
          -scheme mks-multiplatform-iptv \
          -destination 'platform=iOS Simulator,name=iPhone 15 Pro' \
          -enableCodeCoverage YES
    
    - name: Build and Test macOS
      run: |
        xcodebuild test \
          -project mks-multiplatform-iptv.xcodeproj \
          -scheme mks-multiplatform-iptv \
          -destination 'platform=macOS' \
          -enableCodeCoverage YES
    
    - name: Upload Coverage
      uses: codecov/codecov-action@v3
      with:
        file: ./coverage.lcov

๐Ÿ” Troubleshooting

Common Issues

Build Errors

Issue: "No such module 'IPTVCore'"

# Clean build folder
rm -rf ~/Library/Developer/Xcode/DerivedData
# Rebuild project
xcodebuild clean build

Issue: Code signing errors

  1. Check Apple Developer account status
  2. Verify provisioning profiles
  3. Update bundle identifier to unique value
  4. Enable "Automatically manage signing"

Runtime Issues

Issue: Network requests failing

  • Check App Transport Security settings in Info.plist
  • Verify network permissions
  • Test with HTTP instead of HTTPS (development only)

Issue: AVPlayer not playing streams

  • Verify stream URL format and accessibility
  • Check audio session configuration
  • Test with known working stream URLs

Debug Logging

import os

struct Logger {
    private let logger: os.Logger
    
    init(subsystem: String, category: String) {
        self.logger = os.Logger(subsystem: subsystem, category: category)
    }
    
    func debug(_ message: String, metadata: [String: Any] = [:]) {
        #if DEBUG
        let metadataString = metadata.map { "\($0.key)=\($0.value)" }.joined(separator: ", ")
        logger.debug("\(message) [\(metadataString)]")
        #endif
    }
    
    func error(_ message: String, error: Error? = nil) {
        logger.error("\(message) \(error?.localizedDescription ?? "")")
    }
}

This development setup ensures a productive and consistent development experience across all platforms while maintaining code quality and testing standards.


{{< include _Footer.md >}}

โš ๏ธ **GitHub.com Fallback** โš ๏ธ