Archiving Xcode project using the CLI

Introduction When you are working on different projects sometimes you need to use different IDE’s. You need to find a way to archive a project in the fastest way. One of such ways is by using the xcodebuild archive command Basic outline of the process Open Terminal: Open the Terminal application on your Mac. Navigate to Project Directory: Use the cd command to navigate to the directory containing your Xcode project. Run xcodebuild archive: Once you’re in the project directory, you can run xcodebuild archive with the appropriate parameters to build your project. Example: xcodebuild archive -scheme YourSchemeName -archivePath ~/Desktop/YourAppName.xcarchive Another way is by integrating fastlane into your workflow: Outline of the process Install Fastlane: If you haven’t already installed Fastlane, you can do so using RubyGems, which is the Ruby package manager: ...

April 16, 2024 · 2 min · Dmytro Chumakov

Testing Xcode project using the CLI

Introduction When you are working on different projects sometimes you need to use different IDE’s. You need to find a way to test a project in the fastest way. One of such ways is by using the xcodebuild command Basic outline of the process Open Terminal: Open the Terminal application on your Mac. Navigate to Project Directory: Use the cd command to navigate to the directory containing your Xcode project. Run xcodebuild: Once you’re in the project directory, you can run xcodebuild with the appropriate parameters to build your project. Example: xcodebuild -project YourProject.xcodeproj -scheme YourSchemeName test Another way is by integrating fastlane into your workflow: Outline of the process Install Fastlane: If you haven’t already installed Fastlane, you can do so using RubyGems, which is the Ruby package manager: ...

April 12, 2024 · 2 min · Dmytro Chumakov

Building Xcode project using the CLI

Introduction When you are working on different projects sometimes you need to use different IDE’s. You need to find a way to build a project in the fastest way. One of such ways is by using the xcodebuild command Basic outline of the process Open Terminal: Open the Terminal application on your Mac. Navigate to Project Directory: Use the cd command to navigate to the directory containing your Xcode project. Run xcodebuild: Once you’re in the project directory, you can run xcodebuild with the appropriate parameters to build your project. Example: xcodebuild -project YourProjectName.xcodeproj -scheme YourSchemeName Another way is by integrating fastlane into your workflow: Outline of the process Install Fastlane: If you haven’t already installed Fastlane, you can do so using RubyGems, which is the Ruby package manager: ...

April 5, 2024 · 2 min · Dmytro Chumakov

The Visitor Pattern

What is a Visitor Pattern? The Visitor Pattern helps add new capabilities to a composite of objects. Source What problems does it solve? The Visitor Pattern helps solve following problems: Separation of Concerns: The Visitor Pattern separates algorithms from the objects on which they operate. This allows for clean code organization by keeping algorithms and operations separate from the data structures they operate on. Extensibility: It allows you to add new operations to existing object structures without modifying those structures. This is especially useful when dealing with complex object hierarchies where adding new functionality directly to the classes would lead to code bloat and tight coupling. Traversal of Object Structures: It provides a way to traverse complex object structures while performing some action on each element of the structure. This is particularly useful in scenarios where you need to process every element of a data structure in a specific order or with a specific algorithm. Real-world code example // Element protocol representing the items on the menu protocol MenuItem { func accept(visitor: OrderVisitor) } // Concrete item types class Coffee: MenuItem { let name: String let price: Double init(name: String, price: Double) { self.name = name self.price = price } func accept(visitor: OrderVisitor) { visitor.visit(self) } } class Tea: MenuItem { let name: String let price: Double init(name: String, price: Double) { self.name = name self.price = price } func accept(visitor: OrderVisitor) { visitor.visit(self) } } class Pastry: MenuItem { let name: String let price: Double init(name: String, price: Double) { self.name = name self.price = price } func accept(visitor: OrderVisitor) { visitor.visit(self) } } // Visitor protocol defining the operations to be performed on menu items protocol OrderVisitor { func visit(_ item: Coffee) func visit(_ item: Tea) func visit(_ item: Pastry) } // Concrete visitor implementing operations on menu items class TotalCostVisitor: OrderVisitor { var totalCost = 0.0 func visit(_ item: Coffee) { totalCost += item.price } func visit(_ item: Tea) { totalCost += item.price } func visit(_ item: Pastry) { totalCost += item.price } } class ItemDetailsVisitor: OrderVisitor { var details = "" func visit(_ item: Coffee) { details += "Coffee: \(item.name), Price: $\(item.price)\n" } func visit(_ item: Tea) { details += "Tea: \(item.name), Price: $\(item.price)\n" } func visit(_ item: Pastry) { details += "Pastry: \(item.name), Price: $\(item.price)\n" } } // Example usage let items: [MenuItem] = [Coffee(name: "Espresso", price: 2.5), Tea(name: "Green Tea", price: 2.0), Pastry(name: "Croissant", price: 3.0)] let totalCostVisitor = TotalCostVisitor() for item in items { item.accept(visitor: totalCostVisitor) } print("Total cost of the order: $\(totalCostVisitor.totalCost)") let itemDetailsVisitor = ItemDetailsVisitor() for item in items { item.accept(visitor: itemDetailsVisitor) } print("Order details:") print(itemDetailsVisitor.details)

April 1, 2024 · 3 min · Dmytro Chumakov

The Memento Pattern

What is a Memento Pattern? The Memento Pattern helps return an object to one of its previous states; for instance, if the user requests an “undo” operation. Source What problems does it solve? The Memento Pattern helps solve following problems: Undo/Redo Functionality: Memento allows you to capture an object’s state at a specific point in time and store it externally. This enables you to implement undo/redo functionality by restoring the object to its previous state. Checkpointing: In applications where users need to save progress or create checkpoints (such as in games or long processes), the Memento Pattern allows you to save the state of an object at various intervals so that users can return to those points later. Real-world code example // Memento: Represents the state of the TextEditor struct TextEditorMemento { let text: String } // Originator: Creates and stores states in Memento objects class TextEditor { private var text: String = "" func setText(_ text: String) { self.text = text } func getText() -> String { return text } func save() -> TextEditorMemento { return TextEditorMemento(text: text) } func restore(fromMemento memento: TextEditorMemento) { self.text = memento.text } } // Caretaker: Manages the mementos class TextEditorHistory { private var history: [TextEditorMemento] = [] private let editor: TextEditor init(editor: TextEditor) { self.editor = editor } func save() { let snapshot = editor.save() history.append(snapshot) } func undo() { guard let lastSnapshot = history.popLast() else { print("Nothing to undo.") return } editor.restore(fromMemento: lastSnapshot) } func printHistory() { print("Text Editor History:") for (index, snapshot) in history.enumerated() { print("Step \(index + 1): \(snapshot.text)") } print("Current text: \(editor.getText())") } } // Example usage let textEditor = TextEditor() let history = TextEditorHistory(editor: textEditor) textEditor.setText("Hello, World!") history.save() textEditor.setText("This is a Swift example.") history.save() textEditor.setText("Using Memento Pattern.") history.save() history.printHistory() history.undo() print("After Undo:") history.printHistory() Thank you for reading! 😊

March 22, 2024 · 2 min · Dmytro Chumakov