Xcode

Xcode

Xcode is Apple's integrated development environment (IDE).
Rupert  Beatty

Rupert Beatty

1668153960

RsyncOSX: A MacOS GUI for Rsync. Compiled For MacOS Big Sur

Hi there 👋

RsyncOSX and RsyncUI are GUI´s on the Apple macOS plattform for the command line tool rsync.

It is rsync which executes the synchronize task. The GUI´s are only for setting parameters and make it more easy to use rsync, which is a fantastic tool.

The UI of RsyncOSX and RsyncUI can for users who dont know rsync be difficult to understand. Setting wrong parameters to rsync can result in deleted data. RsyncOSX nor RsyncUI will not stop you for doing so. That is why it is very important to execute a simulated run, a --dry-run, and verify the result before the real run.

If you have installed macOS Big Sur, RsyncOSX is the GUI for you. If you have installed macOS Monterey or macOS Ventura, you can use both GUI´s in parallell.

Please be aware it is an external task not controlled by RsyncOSX which executes the command line tool rsync. RsyncOSX is monitoring the task for progress and termination. The user can abort a tasks at any time. Please let the abort to finish and cleanup properly before starting a new task. It might take a few seconds. If not the apps might become unresponsive.

One of many advantages of utilizing rsync is that it can restart and continue the synchronize task from where it was aborted.

RsyncOSX is the only GUI which supports scheduling of task.

RsyncOSX is released for macOS Big Sur and later due to requirements in some features of Combine. Latest build is 8 September 2022.

RsyncUI is released for macOS Monterey and later.

Latest build is 5 November 2022.

My github stats

Metrics

Download Details:

Author: rsyncOSX
Source Code: https://github.com/rsyncOSX/RsyncOSX 
License: MIT license

#swift #backup #xcode 

RsyncOSX: A MacOS GUI for Rsync. Compiled For MacOS Big Sur
Rupert  Beatty

Rupert Beatty

1668134460

Alerttoast: Create Apple-like Alerts & Toasts using SwiftUI

AlertToast-SwiftUI

Present Apple-like alert & toast in SwiftUI

🌄 Example

ToastExample.gif

🔭 Overview

Currently in SwiftUI, the only way to inform the user about some process that finished for example, is by using Alert. Sometimes, you just want to pop a message that tells the user that something completed, or his message was sent. Apple doesn't provide any other method rather than using Alert even though Apple using all kinds of different pop-ups. The results are poor UX where the user would need to tap "OK/Dismiss" for every little information that he should be notified about.

Alert Toast is an open-source library in Github to use with SwiftUI. It allows you to present popups that don't need any user action to dismiss or to validate. Some great usage examples: Message Sent, Poor Network Connection, Profile Updated, Logged In/Out, Favorited, Loading and so on…

  • Built with pure SwiftUI.
  • 3 Display modes: Alert (pop at the center), HUD (drop from the top) and Banner (pop/slide from the bottom).
  • Complete, Error SystemImage, Image, Loading, and Regular (Only Text).
  • Supports Light & Dark Mode.
  • Works with any kind of view builder.
  • Localization support.
  • Font & Background customization.

If you like the project, don't forget to put star 🌟.

💻 Installation

Cocoapods

AlertToast Cocapods Website

CocoaPods is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate AlertToast into your Xcode project using CocoaPods, specify it in your Podfile:

pod 'AlertToast'

Swift Package Manager

The Swift Package Manager is a tool for managing the distribution of Swift code. It’s integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies.

To integrate AlertToast into your Xcode project using Xcode 12, specify it in File > Swift Packages > Add Package Dependency...:

https://github.com/elai950/AlertToast.git, :branch="master"

For Xcode 13, please refer this article to install AlertToast


Manually

If you prefer not to use any of dependency managers, you can integrate AlertToast into your project manually. Put Sources/AlertToast folder in your Xcode project. Make sure to enable Copy items if needed and Create groups.

🧳 Requirements

  • iOS 13.0+ | macOS 11+
  • Xcode 12.0+ | Swift 5+

🛠 Usage

First, add import AlertToast on every swift file you would like to use AlertToast.

Then, use the .toast view modifier:

Parameters:

  • isPresenting: (MUST) assign a Binding<Bool> to show or dismiss alert.
  • duration: default is 2, set 0 to disable auto dismiss.
  • tapToDismiss: default is true, set false to disable.
  • alert: (MUST) expects AlertToast.

Usage example with regular alert

import AlertToast
import SwiftUI

struct ContentView: View{

    @State private var showToast = false

    var body: some View{
        VStack{

            Button("Show Toast"){
                 showToast.toggle()
            }
        }
        .toast(isPresenting: $showToast){

            // `.alert` is the default displayMode
            AlertToast(type: .regular, title: "Message Sent!")
            
            //Choose .hud to toast alert from the top of the screen
            //AlertToast(displayMode: .hud, type: .regular, title: "Message Sent!")
            
            //Choose .banner to slide/pop alert from the bottom of the screen
            //AlertToast(displayMode: .banner(.slide), type: .regular, title: "Message Sent!")
        }
    }
}

Complete Modifier Example

.toast(isPresenting: $showAlert, duration: 2, tapToDismiss: true, alert: {
   //AlertToast goes here
}, onTap: {
   //onTap would call either if `tapToDismis` is true/false
   //If tapToDismiss is true, onTap would call and then dismis the alert
}, completion: {
   //Completion block after dismiss
})

Alert Toast Parameters

AlertToast(displayMode: DisplayMode,
           type: AlertType,
           title: Optional(String),
           subTitle: Optional(String),
           style: Optional(AlertStyle))
           
//This is the available customizations parameters:
AlertStyle(backgroundColor: Color?,
            titleColor: Color?,
            subTitleColor: Color?,
            titleFont: Font?,
            subTitleFont: Font?)

Available Alert Types:

  • Regular: text only (Title and Subtitle).
  • Complete: animated checkmark.
  • Error: animated xmark.
  • System Image: name image from SFSymbols.
  • Image: name image from Assets.
  • Loading: Activity Indicator (Spinner).

Alert dialog view modifier (with default settings):

.toast(isPresenting: Binding<Bool>, duration: Double = 2, tapToDismiss: true, alert: () -> AlertToast , onTap: () -> (), completion: () -> () )

Simple Text Alert:

AlertToast(type: .regular, title: Optional(String), subTitle: Optional(String))

Complete/Error Alert:

AlertToast(type: .complete(Color)/.error(Color), title: Optional(String), subTitle: Optional(String))

System Image Alert:

AlertToast(type: .systemImage(String, Color), title: Optional(String), subTitle: Optional(String))

Image Alert:

AlertToast(type: .image(String), title: Optional(String), subTitle: Optional(String))

Loading Alert:

//When using loading, duration won't auto dismiss and tapToDismiss is set to false
AlertToast(type: .loading, title: Optional(String), subTitle: Optional(String))

You can add many .toast on a single view.

📖 Article

I wrote an article that contains more usage examples.

Medium - How to toast an alert in SwiftUI

👨‍💻 Contributors

All issue reports, feature requests, pull requests and GitHub stars are welcomed and much appreciated.



Download Details:

Author: elai950
Source Code: https://github.com/elai950/AlertToast 
License: MIT license

#swift #apple #alert #xcode #dialog #popup 

Alerttoast: Create Apple-like Alerts & Toasts using SwiftUI
Rupert  Beatty

Rupert Beatty

1668130560

Pika: An Open-source Colour Picker App for MacOS

Pika

Pika (pronounced pi·kuh, like picker) is an easy to use, open-source, native colour picker for macOS. Pika makes it easy to quickly find colours onscreen, in the format you need, so you can get on with being a speedy, successful designer.

Screenshots of the dark and light Pika interface

Requirements

OS

  • macOS Catalina (Version 10.15+) and newer

Development

Getting started with contributing

Make sure you have mint installed, and bootstrap the toolchain dependencies:

brew install mint
mint bootstrap

Open Pika.xcodeproj and you should be good to go. If you run into any problems, please detail them in an issue.

Contributions

Any and all contributions are welcomed. Check for open issues, look through the project roadmap, and submit a PR.

Dependencies and thanks

And a huge thank you to Stormnoid for the incredible 2D vector field visualisation on Shadertoy.

Download the latest version of the app at superhighfives.com/pika.

Learn more about the motivations behind the project, and the product vision.

Download Details:

Author: Superhighfives
Source Code: https://github.com/superhighfives/pika 
License: MIT license

#swift #macos #app #xcode #swiftui 

Pika: An Open-source Colour Picker App for MacOS
Rupert  Beatty

Rupert Beatty

1668093240

Swiftinfo: Extract and analyze The Evolution Of An iOS App's Code

SwiftInfo

Note: I don't intend to ship further updates to this tool.

SwiftInfo is a CLI tool that extracts, tracks and analyzes metrics that are useful for Swift apps. Besides the default tracking options that are shipped with the tool, you can also customize SwiftInfo to track pretty much anything that can be conveyed in a simple .swift script.

By default SwiftInfo will assume you're extracting info from a release build and send the final results to Slack, but it can be used to extract info from individual pull requests as well with the danger-SwiftInfo danger plugin.

Available Providers

Type NameDescription
📦 IPASizeProviderSize of the .ipa archive (not the App Store size!)
📊 CodeCoverageProviderCode coverage percentage
👶 TargetCountProviderNumber of targets (dependencies)
🎯 TestCountProviderSum of all test target's test count
⚠️ WarningCountProviderNumber of warnings in a build
🧙‍♂️ OBJCFileCountProviderNumber of OBJ-C files and headers (for mixed OBJ-C / Swift projects)
⏰ LongestTestDurationProviderThe name and duration of the longest test
🛏 TotalTestDurationProviderTime it took to build and run all tests
🖼 LargestAssetCatalogProviderThe name and size of the largest asset catalog
🎨 TotalAssetCatalogsSizeProviderThe sum of the size of all asset catalogs
💻 LinesOfCodeProviderExecutable lines of code
🚚 ArchiveDurationProviderTime it took to build and archive the app
📷 LargestAssetProviderThe largest asset in the project. Only considers files inside asset catalogs.

Each provider may have a specific set of requirements in order for them to work. Check their documentation to learn more.

Usage

SwiftInfo extracts information by analyzing the logs that your build system generates when you build and/or test your app. Because it requires these logs to work, SwiftInfo is meant to be used alongside a build automation tool like fastlane. The following topics describe how you can retrieve these logs and setup SwiftInfo itself.

We'll show how to get the logs first as you'll need them to configure SwiftInfo.

Note: This repository contains an example project. Check it out to see the tool in action -- just go to the example project folder and run make swiftinfo in your terminal.

Retrieving raw logs with fastlane

If you use fastlane, you can expose raw logs to SwiftInfo by adding the buildlog_path argument to scan (test logs) and gym (build logs). Here's a simple example of a fastlane lane that runs tests, submits an archive to TestFlight and runs SwiftInfo (make sure to edit the folder paths to what's being used by your project):

desc "Submits a new beta build and runs SwiftInfo"
lane :beta do
  # Run tests, copying the raw logs to the project folder
  scan(
    scheme: "MyScheme",
    buildlog_path: "./build/tests_log"
  )

  # Archive the app, copying the raw logs to the project folder and the .ipa to the /build folder
  gym(
    workspace: "MyApp.xcworkspace",
    scheme: "Release",
    output_directory: "build",
    buildlog_path: "./build/build_log"
  )

  # Send to TestFlight
  pilot(
      skip_waiting_for_build_processing: true
  )

  # Run the CocoaPods version of SwiftInfo
  sh("../Pods/SwiftInfo/bin/swiftinfo")

  # Commit and push SwiftInfo's output
  sh("git add ../SwiftInfo-output/SwiftInfoOutput.json")
  sh("git commit -m \"[ci skip] Updating SwiftInfo Output JSON\"")
  push_to_git_remote
end

Retrieving raw logs manually

An alternative that doesn't require fastlane is to simply manually run xcodebuild / xctest and pipe the output to a file. We don't recommend doing this in a real project, but it can be useful if you just want to test the tool without having to setup fastlane.

xcodebuild -workspace ./Example.xcworkspace -scheme Example 2>&1 | tee ./build/build_log/Example-Release.log

Configuring SwiftInfo

SwiftInfo itself is configured by creating a Infofile.swift file in your project's root. Here's an example one with a detailed explanation:

import SwiftInfoCore

// Use `FileUtils` to configure the path of your logs. 
// If you're retrieving them with fastlane and don't know what the name of the log files are going to be, 
// just run it once to have it create them.

FileUtils.buildLogFilePath = "./build/build_log/MyApp-MyConfig.log"
FileUtils.testLogFilePath = "./build/tests_log/MyApp-MyConfig.log"

// Now, create a `SwiftInfo` instance by passing your project's information.

let projectInfo = ProjectInfo(xcodeproj: "MyApp.xcodeproj",
                              target: "MyTarget",
                              configuration: "MyConfig")

let api = SwiftInfo(projectInfo: projectInfo)

// Use SwiftInfo's `extract()` method to extract and append all the information you want into a single property.

let output = api.extract(IPASizeProvider.self) +
             api.extract(WarningCountProvider.self) +
             api.extract(TestCountProvider.self) +
             api.extract(TargetCountProvider.self, args: .init(mode: .complainOnRemovals)) +
             api.extract(CodeCoverageProvider.self, args: .init(targets: ["NetworkModule", "MyApp"])) +
             api.extract(LinesOfCodeProvider.self, args: .init(targets: ["NetworkModule", "MyApp"]))

// Lastly, process the output.

if isInPullRequestMode {
    // If called from danger-SwiftInfo, print the results to the pull request
    api.print(output: output)
} else {
    // If called manually, send the results to Slack...
    api.sendToSlack(output: output, webhookUrl: url)
    // ...and save the output to your repo so it serves as the basis for new comparisons.
    api.save(output: output)
}

Saving and visualizing the data

After successfully extracting data, you should call api.save(output: output) to have SwiftInfo add/update a json file in the {Infofile path}/SwiftInfo-output folder. It's important to add this file to version control after the running the tool as this is what SwiftInfo uses to compare new pieces of information.

You can then use SwiftInfo-Reader to transform this output into a more visual static HTML page.

Customizing Providers

To be able to support different types of projects, SwiftInfo provides customization options to some providers. See the documentation for each provider to see what it supports. If you wish to track something that's not handled by the default providers, you can also create your own providers. Click here to see how.

Customizing Runs

Any arguments you pass to SwiftInfo can be inspected inside your Infofile. This allows you to pass any custom information you want to the binary and use it to customize your runs.

For example, if you run SwiftInfo by calling swiftinfo --myCustomArgument, you can use ProcessInfo to check for its presence inside your Infofile.

if ProcessInfo.processInfo.arguments.contains("--myCustomArgument") {
    print("Yay, custom arguments!")
}

If the argument has a value, you can also fetch that value with UserDefaults.

Installation

CocoaPods

pod 'SwiftInfo'

Homebrew

To install SwiftInfo with Homebrew the first time, simply run these commands:

brew tap rockbruno/SwiftInfo https://github.com/rockbruno/SwiftInfo.git
brew install rockbruno/SwiftInfo/swiftinfo

To update to the newest Homebrew version of SwiftInfo when you have an old version already installed, run:

brew upgrade swiftinfo

Manually

Download the latest release and unzip the contents somewhere in your project's folder.

Swift Package Manager

SwiftPM is currently not supported due to the need of shipping additional files with the binary, which SwiftPM does not support. We might find a solution for this, but for now there's no way to use the tool with it.

Download Details:

Author: Rockbruno
Source Code: https://github.com/rockbruno/SwiftInfo 
License: MIT license

#swift #cli #ios #tools #xcode 

Swiftinfo: Extract and analyze The Evolution Of An iOS App's Code
Rupert  Beatty

Rupert Beatty

1667905560

Sitrep: A Source Code analyzer for Swift Projects

Sitrep

Sitrep is a source code analyzer for Swift projects, giving you a high-level overview of your code:

  • A count of your classes, structs, enums, protocols, and extensions.
  • Total lines of code, and also source lines of code (minus comments and whitespace).
  • Which file and type are the longest, plus their source lines of code.
  • Which imports you’re using and how often.
  • How many UIViews, UIViewControllers, and SwiftUI views are in your project.

Behind the scenes, Sitrep captures a lot more information that could be utilized – how many functions you have, how many comments (regular and documentation), how large your enums are, and more. These aren’t currently reported, but could be in a future release. It’s also written as both a library and an executable, so it can be integrated elsewhere as needed.

Sitrep is built using Apple’s SwiftSyntax, which means it parses Swift code accurately and efficiently.

Note: Please make sure that the SwiftSyntax version specified in Package.swift matches your current Swift tools version. For example, if you're using Swift tools 5.3 you need to change the spec from 0.50400.0 to 0.50300.0.

Installation

If you want to install the Sitrep command line tool, you have three options: Homebrew, Mint, or building it from the command line yourself.

Use this command for Homebrew:

brew install twostraws/brew/sitrep

Using Homebrew allows you to run sitrep directly from the command line.

For Mint, install and run Sitrep with these command:

mint install twostraws/Sitrep@main
mint run sitrep@main

And finally, to build and install the command line tool yourself, clone the repository and run make install:

git clone https://github.com/twostraws/Sitrep
cd Sitrep
make install

As with the Homebrew option, building the command line tool yourself allows you to use the sitrep command directly from the command line.

Using Sitrep as a library

Sitrep is implemented as a library that does all the hard work of scanning and reporting, plus a small front end that handles reading and writing on the command line. As an alternative to using Sitrep from the command line, you can also use its library SitrepCore from inside your own Swift code.

First, add Sitrep as a dependency in your Package.swift file:

let package = Package(
    //...
    dependencies: [
        .package(url: "https://github.com/twostraws/Sitrep", .branch("master"))
    ],
    //...
)

Then import SitrepCore wherever you’d like to use it.

Command line flags

When run on the command line without any flags, Sitrep will automatically scan your current directory and print its findings as text. To control this behavior, Sitrep supports several command line flags:

  • -c lets you specify a path to your .sitrep.yml configuration file, if you have one.
  • -f sets the output format. For example, -f json enables JSON output. The default behavior is text output, which is equivalent to -f text.
  • -i will print debug information, showing the settings Sitrep would use if a real scan were requested, then exits.
  • -p sets the path Sitrep should scan. This defaults to your current working directory.
  • -h prints command line help.

Configuration

You can customize the behavior of Sitrep by creating a .sitrep.yml file in the directory you wish to scan. This is a YAML file that allows you to provide permanent options for scanning this path, although right now this is limited to one thing: an array of directory names to exclude from the scan.

For example, if you wanted to exclude the .build directory and your tests, you might create a .sitrep.yml file such as this one:

excluded:
  - .build
  - Tests

You can ask Sitrep to use a custom configuration file using the -c parameter, for example sitrep -c /path/to/.sitrep.yml -p /path/to/swift/project.

Alternatively, you can use the -i parameter to have Sitrep tell you the configuration options it would use in a real analysis run. This will print the configuration information then exit.

Try it yourself

Sitrep is written using Swift 5.3. You can either build and run the executable directly, or integrate the SitrepCore library into your own code.

To build Sitrep, clone this repository and open Terminal in the repository root directory. Then run:

swift build
swift run sitrep -p ~/path/to/your/project/root

If you would like to keep a copy of the sitrep executable around, find it in the .debug directory after running swift build.

To run Sitrep from the command line just provide it with the name of a project directory to parse – it will locate all Swift files recursively from there. Alternatively, just using sitrep by itself will scan the current directory.

Contribution guide

Any help you can offer with this project is most welcome, and trust me: there are opportunities big and small, so that someone with only a small amount of Swift experience can help.

Some suggestions you might want to explore:

  • Converting more of the tracked data (number of functions, parameters to functions, length of functions, etc) into reported data.
  • Reading more data from the parsed files, and using it to calculate things such as cyclomatic complexity.
  • Reading non-Swift data, such as number of storyboard scenes, number of outlets, number of assets in asset catalogs, etc.

Please ensure you write tests to accompany any code you contribute, and that SwiftLint returns no errors or warnings.

Credits

Sitrep was designed and built by Paul Hudson, and is copyright © Paul Hudson 2021. Sitrep is licensed under the Apache License v2.0 with Runtime Library Exception; for the full license please see the LICENSE file.

Sitrep is built on top of Apple’s SwiftSyntax library for parsing code, which is also available under the Apache License v2.0 with Runtime Library Exception.

Swift, the Swift logo, and Xcode are trademarks of Apple Inc., registered in the U.S. and other countries.

If you find Sitrep useful, you might find my website full of Swift tutorials equally useful: Hacking with Swift.

Download Details:

Author: Twostraws
Source Code: https://github.com/twostraws/Sitrep 
License: Apache-2.0 license

#swift #xcode #analyzer 

Sitrep: A Source Code analyzer for Swift Projects
Rupert  Beatty

Rupert Beatty

1667838720

BartyCrouch: Localization/I18n

BartyCrouch

BartyCrouch incrementally updates your Strings files from your Code and from Interface Builder files. "Incrementally" means that BartyCrouch will by default keep both your already translated values and even your altered comments. Additionally you can also use BartyCrouch for machine translating from one language to 60+ other languages. Using BartyCrouch is as easy as running a few simple commands from the command line what can even be automated using a build script within your project.

Checkout this blog post to learn how you can effectively use BartyCrouch in your projects.

Requirements

  • Xcode 13.3+ & Swift 5.6+
  • Xcode Command Line Tools (see here for installation instructions)

Getting Started

Installation

Via Homebrew

To install Bartycrouch the first time, simply run the command:

brew install bartycrouch

To update to the newest version of BartyCrouch when you have an old version already installed run:

brew upgrade bartycrouch

Via Mint

To install or update to the latest version of BartyCrouch simply run this command:

mint install FlineDev/BartyCrouch

Configuration

To configure BartyCrouch for your project, first create a configuration file within your projects root directory. BartyCrouch can do this for you:

bartycrouch init

Now you should have a file named .bartycrouch.toml with the following contents:

[update]
tasks = ["interfaces", "code", "transform", "normalize"]

[update.interfaces]
paths = ["."]
subpathsToIgnore = [".git", "carthage", "pods", "build", ".build", "docs"]
defaultToBase = false
ignoreEmptyStrings = false
unstripped = false
ignoreKeys = ["#bartycrouch-ignore!", "#bc-ignore!", "#i!"]

[update.code]
codePaths = ["."]
subpathsToIgnore = [".git", "carthage", "pods", "build", ".build", "docs"]
localizablePaths = ["."]
defaultToKeys = false
additive = true
unstripped = false
ignoreKeys = ["#bartycrouch-ignore!", "#bc-ignore!", "#i!"]

[update.transform]
codePaths = ["."]
subpathsToIgnore = [".git", "carthage", "pods", "build", ".build", "docs"]
localizablePaths = ["."]
transformer = "foundation"
supportedLanguageEnumPath = "."
typeName = "BartyCrouch"
translateMethodName = "translate"

[update.normalize]
paths = ["."]
subpathsToIgnore = [".git", "carthage", "pods", "build", ".build", "docs"]
sourceLocale = "en"
harmonizeWithSource = true
sortByKeys = true

[lint]
paths = ["."]
subpathsToIgnore = [".git", "carthage", "pods", "build", ".build", "docs"]
duplicateKeys = true
emptyValues = true

This is the default configuration of BartyCrouch and should work for most projects as is. In order to use BartyCrouch to its extent, it is recommended though to consider making the following changes:

  1. To speed it up significantly, provide more specific paths for any key containing path if possible (especially in the update.transform section, e.g. ["App/Sources"] for codePaths or ["App/Supporting Files"] for supportedLanguageEnumPaths).
  2. Remove the code task if your project is Swift-only and you use the new transform update task.
  3. If you are using SwiftGen with the structured-swift4 template, you will probably want to use the transform task and change its transformer option to swiftgenStructured.
  4. If you decided to use the transform task, create a new file in your project (e.g. under SupportingFiles) named BartyCrouch.swift and copy the following code:
//  This file is required in order for the `transform` task of the translation helper tool BartyCrouch to work.
//  See here for more details: https://github.com/FlineDev/BartyCrouch

import Foundation

enum BartyCrouch {
    enum SupportedLanguage: String {
        // TODO: remove unsupported languages from the following cases list & add any missing languages
        case arabic = "ar"
        case chineseSimplified = "zh-Hans"
        case chineseTraditional = "zh-Hant"
        case english = "en"
        case french = "fr"
        case german = "de"
        case hindi = "hi"
        case italian = "it"
        case japanese = "ja"
        case korean = "ko"
        case malay = "ms"
        case portuguese = "pt-BR"
        case russian = "ru"
        case spanish = "es"
        case turkish = "tr"
    }

    static func translate(key: String, translations: [SupportedLanguage: String], comment: String? = nil) -> String {
        let typeName = String(describing: BartyCrouch.self)
        let methodName = #function

        print(
            "Warning: [BartyCrouch]",
            "Untransformed \(typeName).\(methodName) method call found with key '\(key)' and base translations '\(translations)'.",
            "Please ensure that BartyCrouch is installed and configured correctly."
        )

        // fall back in case something goes wrong with BartyCrouch transformation
        return "BC: TRANSFORMATION FAILED!"
    }
}
  1. If you don't develop in English as the first localized language, you should update the sourceLocale of the normalize task.
  2. If you want to use the machine translation feature of BartyCrouch, add translate to the tasks list at the top and copy the following section into the configuration file with secret replaced by your Microsoft Translator Text API Subscription Key:
[update.translate]
paths = "."
translator = "microsoftTranslator"
secret = "<#Subscription Key#>"
sourceLocale = "en"

Usage

Before using BartyCrouch please make sure you have committed your code. Also, we highly recommend using the build script method described below.


bartycrouch accepts one of the following sub commands:

  • update: Updates your .strings file contents according to your configuration.
  • lint: Checks your .strings file contents for empty values & duplicate keys.

Also the following command line options can be provided:

  • -v, --verbose: Prints more detailed information about the executed command.
  • -x, --xcode-output: Prints warnings & errors in Xcode compatible format.
  • -w, --fail-on-warnings: Returns a failed status code if any warning is encountered.
  • -p, --path: Specifies a different path than current to run BartyCrouch from there.

update subcommand

The update subcommand can be run with one or multiple of the following tasks:

  • interfaces: Updates .strings files of Storyboards & XIBs.
  • code: Updates Localizable.strings file from NSLocalizedString entries in code.
  • transform: A mode where BartyCrouch replaces a specific method call to provide translations in multiple languages in a single line. Only supports Swift files.
  • translate: Updates missing translations in other languages than the source language.
  • normalize: Sorts & cleans up .strings files.

In order to configure which tasks are executed, edit this section in the config file:

[update]
tasks = ["interfaces", "code", "transform", "normalize"]

Options for interfaces

  • paths: The directory / directories to search for Storyboards & XIB files.
  • subpathsToIgnore: The subpaths to be ignored inside the directories found via the paths option.
  • defaultToBase: Add Base translation as value to new keys.
  • ignoreEmptyStrings: Doesn't add views with empty values.
  • unstripped: Keeps whitespaces at beginning & end of Strings files.
  • ignoreKeys: Keys (e.g. in the comment) indicating that specific translation entries should be ignored when generating String files. Useful to ignore strings that are gonna be translated in code.

Options for code

  • codePaths: The directory / directories to search for Swift code files.
  • subpathsToIgnore: The subpaths to be ignored inside the directories found via the paths option.
  • localizablePaths: The enclosing path(s) containing the localized Localizable.strings files.
  • defaultToKeys: Add new keys both as key and value.
  • additive: Prevents cleaning up keys not found in code.
  • customFunction: Use alternative name to search for strings to localize, in addition to NSLocalizedString, and CFCopyLocalizedString. Defaults to LocalizedStringResource.
  • customLocalizableName: Use alternative name for Localizable.strings.
  • unstripped: Keeps whitespaces at beginning & end of Strings files.
  • plistArguments: Use a plist file to store all the code files for the ExtractLocStrings tool. (Recommended for large projects.)
  • ignoreKeys: Keys (e.g. in the comment) indicating that specific translation entries should be ignored when generating String files.
  • overrideComments: Always overrides the comment with the keys new translation, useful for IB files.

Options for transform

  • codePaths: The directory / directories to search for Swift code files.
  • subpathsToIgnore: The subpaths to be ignored inside the directories found via the paths option.
  • localizablePaths: The enclosing path(s) containing the localized Localizable.strings files.
  • transformer: Specifies the replacement code. Use foundation for NSLocalizedString or swiftgenStructured for L10n entries.
  • supportedLanguageEnumPath: The enclosing path containing the SupportedLanguage enum.
  • typeName: The name of the type enclosing the SupportedLanguage enum and translate method.
  • translateMethodName: The name of the translate method to be replaced.
  • customLocalizableName: Use alternative name for Localizable.strings.
  • separateWithEmptyLine: Set to false if you don't want to have empty lines between Strings entries. Defaults to `true.

Options for translate

  • paths: The directory / directories to search for Strings files.
  • subpathsToIgnore: The subpaths to be ignored inside the directories found via the paths option.
  • translator: Specifies the translation API. Use microsoftTranslator or deepL.
  • secret: Your Microsoft Translator Text API Subscription Key or Authentication Key for DeepL API.
  • sourceLocale: The source language to translate from.
  • separateWithEmptyLine: Set to false if you don't want to have empty lines between Strings entries. Defaults to `true.

Options for normalize

  • paths: The directory / directories to search for Strings files.
  • subpathsToIgnore: The subpaths to be ignored inside the directories found via the paths option.
  • sourceLocale: The source language to harmonize keys of other languages with.
  • harmonizeWithSource: Synchronizes keys with source language.
  • sortByKeys: Alphabetically sorts translations by their keys.
  • separateWithEmptyLine: Set to false if you don't want to have empty lines between Strings entries. Defaults to `true.

lint subcommand

The lint subcommand was designed to analyze a project for typical translation issues. The current checks include:

  • duplicateKeys: Finds duplicate keys within the same file.
  • emptyValues: Finds empty values for any language.

Note that the lint command can be used both on CI and within Xcode via the build script method:

  • In Xcode the -x or --xcode-output command line argument should be used to get warnings which point you directly to the found issue.
  • When running on the CI you should specify the -w or --fail-on-warnings argument to make sure BartyCrouch fails if any warnings are encountered.

Localization Workflow via transform

When the transform update task is configured (see recommended step 4 in the Configuration section above) and you are using the build script method, you can use the following simplified process for writing localized code during development:

  1. Instead of NSLocalizedString calls you can use BartyCrouch.translate and specify a key, translations (if any) and optionally a comment. For example:
self.title = BartyCrouch.translate(key: "onboarding.first-page.header-title",  translations: [.english: "Welcome!"])
  1. Once you build your app, BartyCrouch will automatically add the new translation key to all your Localizable.strings files and add the provided translations as values for the provided languages.
  2. Additionally, during the same build BartyCrouch will automatically replace the above call to BartyCrouch.translate with the proper translation call, depending on your transformer option setting.

The resulting code depends on your transformer option setting:

When set to foundation, the above code will transform to:

self.title = NSLocalizedString("onboarding.first-page.header-title", comment: "")

When set to swiftgenStructured it will transform to:

self.title = L10n.Onboarding.FirstPage.headerTitle

Advantages of transform over the code task:

  • You can provide translations for keys without switching to the Strings files.
  • In case you use SwiftGen, you don't need to replace calls to NSLocalizedString with L10n calls manually after running BartyCrouch.
  • Can be combined with the machine translation feature to provide a source language translation in code and let BartyCrouch translate it to all supported languages in a single line & without ever leaving the code.

Disadvantages of transform over the code task:

  • Only works for Swift Code. No support for Objective-C. (You can use both methods simultaneously though.)
  • Xcode will mark the freshly transformed code as errors (but build will succeed anyways) until next build.
  • Not as fast as code since SwiftSyntax currently isn't particularly fast. (But this should improve over time!)

NOTE: As of version 4.x of BartyCrouch formatted localized Strings are not supported by this automatic feature.

Localizing strings of LocalizableStringResource type (AppIntents, ...)

Historically, Apple platforms used CFCopyLocalizedString, and NSLocalizedString macros and their variants, to mark strings used in code to be localized, and to load their localized versions during runtime from Localizable.strings file.

Since introduction of the AppIntents framework, the localized strings in code can also be typed as LocalizedStringResource, and are no longer marked explicitly.

Let's examine this snippet of AppIntents code:

struct ExportAllTransactionsIntent: AppIntent {
    static var title: LocalizedStringResource = "Export all transactions"
    
    static var description =
        IntentDescription("Exports your transaction history as CSV data.")
}

In the example above, both the "Export all transactions", and "Exports your transaction history as CSV data." are actually StaticString instances that will be converted during compilation into LocalizedStringResource instances, and will lookup their respective localizations during runtime from Localized.strings file the same way as when using NSLocalizedString in the past. The only exception being that such strings are not marked explicitly, and require swift compiler to parse and extract such strings for localization. This is what Xcode does from version 13 when using Product -> Export Localizations... option.

In order to continue translating these strings with bartycrouch it is required to mark them explicitely with LocalizedStringResource(_: String, comment: String) call, and specify customFunction="LocalizedStringResource" in code task options.

The example AppIntents code that can be localized with bartycrouch will look like this:

struct ExportAllTransactionsIntent: AppIntent {
    static var title = LocalizedStringResource("Export all transactions", comment: "")
    
    static var description =
        IntentDescription(LocalizedStringResource("Exports your transaction history as CSV data.", comment: ""))
}

Note that you must use the full form of LocalizedStringResource(_: StaticString, comment: StaticString) for the bartycrouch, or more specifically for the extractLocStrings (see xcrun extractLocStrings) to properly parse the strings.

Build Script

In order to truly profit from BartyCrouch's ability to update & lint your .strings files you can make it a natural part of your development workflow within Xcode. In order to do this select your target, choose the Build Phases tab and click the + button on the top left corner of that pane. Select New Run Script Phase and copy the following into the text box below the Shell: /bin/sh of your new run script phase:

export PATH="$PATH:/opt/homebrew/bin"

if which bartycrouch > /dev/null; then
    bartycrouch update -x
    bartycrouch lint -x
else
    echo "warning: BartyCrouch not installed, download it from https://github.com/FlineDev/BartyCrouch"
fi

Next, make sure the BartyCrouch script runs before the steps Compiling Sources (and SwiftGen if used) by moving it per drag & drop, for example right after Target Dependencies.

Now BartyCrouch will be run on each build and you won't need to call it manually ever (again). Additionally, all your co-workers who don't have BartyCrouch installed will see a warning with a hint on how to install it.

Note: Please make sure you commit your code using source control regularly when using the build script method.


Exclude specific Views / NSLocalizedStrings from Localization

Sometimes you may want to ignore some specific views containing localizable texts e.g. because their values are going to be set programmatically.

For these cases you can simply include #bartycrouch-ignore! or the shorthand #bc-ignore! into your value within your base localized Storyboard/XIB file. Alternatively you can add #bc-ignore! into the field "Comment For Localizer" box in the utilities pane.

This will tell BartyCrouch to ignore this specific view when updating your .strings files.

Here's an example of how a base localized view in a XIB file with partly ignored strings might look like:

Here's an example with the alternative comment variant:

You can also use #bc-ignore! in your NSLocalizedString macros comment part to ignore them so they are not added to your Localizable.strings. This might be helpful when you are using a .stringsdict file to handle pluralization (see docs).

For example you can do something like this:

func updateTimeLabel(minutes: Int) {
  String.localizedStringWithFormat(NSLocalizedString("%d minute(s) ago", comment: "pluralized and localized minutes #bc-ignore!"), minutes)
}

The %d minute(s) ago key will be taken from Localizable.stringsdict file, not from Localizable.strings, that's why it should be ignored by BartyCrouch.

Donation

BartyCrouch was brought to you by Cihat Gündüz in his free time. If you want to thank me and support the development of this project, please make a small donation on PayPal. In case you also like my other open source contributions and articles, please consider motivating me by becoming a sponsor on GitHub or a patron on Patreon.

Thank you very much for any donation, it really helps out a lot! 💯

Migration Guides

See the file MIGRATION_GUIDES.md.

Contributing

Contributions are welcome. Feel free to open an issue on GitHub with your ideas or implement an idea yourself and post a pull request. If you want to contribute code, please try to follow the same syntax and semantic in your commit messages (see rationale here). Also, please make sure to add an entry to the CHANGELOG.md file which explains your change.

In order for the tests to run build issues, you need to run – also add an an API key in the new file to run the translations tests, too:

cp Tests/BartyCrouchTranslatorTests/Secrets/secrets.json.sample Tests/BartyCrouchTranslatorTests/Secrets/secrets.json

After Release Checklist:

  1. Run make portable_zip to generate .build/release/portable_bartycrouch.zip
  2. Create new release with text from new CHANGELOG.md section & attach portable_bartycrouch.zip as binary
  3. Run pod trunk push to make a new release known to CocoaPods
  4. Update tag and revision in Formula/bartycrouch.rb, commit & push change
  5. Run brew bump-formula-pr bartycrouch --tag=<tag> --revision=<revision>

Important Notice

There's now a new Mac app called ReMafoX which is the successor to BartyCrouch. It improves upon several aspects of BartyCrouch, such as having no flaky dependencies, adding pluralization support, smart machine translation, a built-in SwiftUI-compatible enum generator, built-in step-by-step instructions for easier setup, detailed explanations of all config options, and even a set of video guides for things like setup, key naming best practices and team onboarding. Get it for free here.

Note that ReMafoX is being actively worked on, you can even vote for or request new features here. In comparison, BartyCrouch is kept up-to-date mostly by the community.


Download Details:

Author: FlineDev
Source Code: https://github.com/FlineDev/BartyCrouch 
License: MIT license

#swift #language #translation #localization #xcode 

BartyCrouch: Localization/I18n
Rupert  Beatty

Rupert Beatty

1667637720

UITabBarController with swipe interaction between its tabs

SwipeableTabBarController

UITabBarController with swipe interaction between its tabs

🌟 Features

  •  Zero setup
  •  Different animations
  •  Enable/Disable interactions easily
  •  Fluid gestures

📲 Installation

Using CocoaPods

Edit your Podfile and specify the dependency:

pod 'SwipeableTabBarController'

Using Carthage

Edit your Cartfile and specify the dependency:

github "marcosgriselli/SwipeableTabBarController"

Manual

Drop the classes inside of SwipeableTabBarController/Classes into your project.

👩‍💻 How to use

Setup

If you don't need subclassing UITabBarController just set the UITabBarController on the Storyboard to be of type SwipeableTabBarController.

Otherwise, make a subclass of SwipeableTabBarController.

import SwipeableTabBarController

class TabBarController: SwipeableTabBarController {
    // Do all your subclassing as a regular UITabBarController.
}

Animations

SwipeableTabBarController supports 3 different types of animations out of the box. Setting the desired animation is easy. On your SwipeableTabBarController subclass just do:

swipeAnimatedTransitioning?.animationType = SwipeAnimationType.sideBySide

If you are supporting just one type of animation call it on viewDidLoad() otherwise call it as you need to change the desired animation.

Side by Side (default)

SideBySideAnimation.gif

The default animation is SwipeAnimationType.sideBySide where the newly selected tab will move in at the same speed the previous one moves out.

Overlap

OverlapAnimation.gif

SwipeAnimationType.overlap the newly selected tab will move in to take the central place on top of the previous one which will hold it's position.

Push

PushAnimation.gif

SwipeAnimationType.push follows iOS default push animation where the top view moves away while the bottom one slightly moves behind. In this case, the top view will be the previously selected tab view.

Enable Cycling

Enable Cycling

SwipeableTabBarController supports cycling between the first and last tab like a carousel. Simply set isCyclingEnabled to true.

Default value is false

isCyclingEnabled = true

Minimum/Maximum number of touches

You can set both the minimum and the maximum number of touches needed to handle the swipe gesture. Simply set minimumNumberOfTouches or maximumNumberOfTouches property.

Default value is 1

minimumNumberOfTouches = 2

Default value is Int.max

maximumNumberOfTouches = 2

Disable Interaction

Support for disabling/enabling the interactor, this can be used on a controller that uses horizontal scrollView or a Map (in the example).

Default value is true

isSwipeEnabled = false

❤️ Contributing

This is an open source project, so feel free to contribute. How?

  • Open an issue.
  • Send feedback via twitter.
  • Propose your own fixes, suggestions and open a pull request with the changes.

Download Details:

Author: Marcosgriselli
Source Code: https://github.com/marcosgriselli/SwipeableTabBarController 
License: MIT license

#swift #ios #ui #xcode #animation 

UITabBarController with swipe interaction between its tabs
Rupert  Beatty

Rupert Beatty

1667408880

Tool To Parse Xcode, Xcodebuild Logs Stored in Xcactivitylog format

XCLogParser

XCLogParser is a CLI tool that parses the SLF serialization format used by Xcode and xcodebuild to store its Build and Test logs (xcactivitylog files).

You can find more information about the format used in the logs here. You can also check Erick Camacho's talk at AltConf 2019 about it.

The tool supports creating reports of different kinds to analyze the content of the logs. XCLogParser can give a lot of insights in regards to build times for every module and file in your project, warnings, errors and unit tests results.

This is an example of a report created from the Build Log of the Kickstarter iOS open source app.

kickstarter build report

How and Why

XCLogParser is written as a SPM executable and it supports three commands:

  1. Dump the contents of an xcactivitylog into a JSON document.
  2. Parse the contents of an xcactivitylog into different kind of reports (json, flatJson, summaryJson, chromeTracer, issues and html).
  3. Dump the Manifest contents of a LogStoreManifest.plist file into a JSON document.

Depending on your needs, there are various use-cases where XCLogParser can help you:

  • Understanding and detailed tracking of build times.
  • Automatically retrieve unit test results, warnings and errors.
  • Build other developer tools for usage outside Xcode.
  • Automatically and continuously data delivery for historic analysis.

Installation

You can compile the executable with the command rake build[debug] or rake build[release] or simply use the Swift Package Manager commands directly. You can also run rake install to install the executable in your /usr/local/bin directory.

Homebrew

$ brew install xclogparser

We are currently working on adding more installation options.

Xcode Integration

You can automate the parsing of xcactivitylog files with a post-scheme build action. In this way, the last build log can be parsed as soon as a build finishes. To do that, open the scheme editor in a project and expand the "Build" panel on the left side. You can then add a new "Post-action" run script and invoke the xclogparser executable with the required parameters:

xclogparser parse --project MyApp --reporter html

This script assumes that the xclogparser executable is installed and present in your PATH.

The run script is executed in a temporary directory by Xcode, so you may find it useful to immediately open the generated output with open MyAppLogs at the end of the script. The Finder will automatically open the output folder after a build completes and you can then view the generated HTML page that contains a nice visualization of your build! ✨

Tips & Tricks

Errors thrown in post-action run scripts are silenced, so it could be hard to notice simple mistakes.

Since Xcode 11, xcodebuild only generates the .xcactivitylog build logs when the option -resultBundlePath is present. If you're compiling with that command and not with Xcode, be sure to set that option to a valid path ending in .xcresult.

Xcode likes to wait for all subprocesses to exit before completing the build. For this reason, you may notice a delayed "Build Succeeded" message if your post-scheme action is taking too long to execute. You can workaround this by offloading the execution to another script in the background and immediately close the input, output and error streams in order to let Xcode and xcodebuild finish cleanly. Create the following launcher script and invoke it from your post-scheme action as follows launcher command-that-parses-the-log-here:

#!/bin/sh

# The first argument is the directory of the executable you want to run.
# The following arguments are directly forwarded to the executable.
# We execute the command in the background and immediately close the input, output
# and error streams in order to let Xcode and xcodebuild finish cleanly.
# This is done to prevent Xcode and xcodebuild being stuck in waiting for all
# subprocesses to end before exiting.
executable=$1
shift;
$executable "$@" <&- >&- 2>&- &

The post-scheme action is not executed in case the build fails. An undocumented feature in Xcode allows you to execute it even in this case. Set the attribute runPostActionsOnFailure to YES in your scheme's BuildAction as follows:

<BuildAction buildImplicitDependencies='YES' parallelizeBuildables='YES' runPostActionsOnFailure='YES'>

Log Types

Build Logs

The xcactivitylog files are created by Xcode/xcodebuild a few seconds after a build completes. The log is placed in the DerivedData/YourProjectName-UUID/Logs/Build directory. It is a binary file in the SLF format compressed with gzip.

In the same directory, you will find a LogStoreManifest.plist file with the list of xcactivitylog files generated for the project. This file can be monitored in order to get notified every time a new log is ready.

Test Logs

The test logs are created inside the DerivedData/YourProjectName-UUID/Logs/Test directory. Xcode and xcodebuild create different logs. You can find a good description about which ones are created in this blog post.

Features

Dump Command

Dumps the whole content of an xcactivitylog file as JSON document. You can use this command if you want to have a raw but easy to parse representation of a log.

Examples:

xclogparser dump --file path/to/log.xcactivitylog --output activity.json
xclogparser dump --project MyProject --output activity.json --redacted

An example output has been omitted for brevity since it can contain a lot of information regarding a build.

Available parameters

Parameter NameDescriptionRequired
--fileThe path to the xcactivitylog.No *
--projectThe name of the project if you don't know the path to the log. The tool will try to find the latest Build log in a folder that starts with that name inside the DerivedData directory. Use --strictProjectName for stricter name matching.No *
--workspaceThe path to the xcworkspace file if you don't know the path to the log. It will generate the folder name for the project in the DerivedData folder using Xcode's hash algorithm and it will try to locate the latest Build Log inside that directory.No *
--xcodeprojThe path to the xcodeproj file if you don't know the path to the log and if the project doesn't have a xcworkspace file. It will generate the folder name for the project in the DerivedData folder using Xcode's hash algorithm and it will try to locate the latest Build Log inside that directory.No *
--derived_dataThe path to the derived data folder if you are using xcodebuild to build your project with the -derivedDataPath option.No
--outputIf specified, the JSON file will be written to the given path. If not defined, the command will output to the standard output.No
--redactedIf specified, the username will be replaced by the word redacted in the file paths contained in the logs. Useful for privacy reasons but slightly decreases the performance.No
--without_build_specific_infoIf specified, build specific information will be removed from the logs (for example bolnckhlbzxpxoeyfujluasoupft will be removed from DerivedData/Product-bolnckhlbzxpxoeyfujluasoupft/Build ). Useful for grouping logs by its content.No
--strictProjectNameUsed in conjunction with --project. If specified, a stricter name matching will be done for the project name.No

No *: One of --file, --project, --workspace, --xcodeproj parameters is required.

Parse Command

Parses the build information from a xcactivitylog and converts it into different representations such as a JSON file, flat JSON file, summary JSON file, issues JSON file, Chrome Tracer file or a static HTML page.

This command supports parsing additional data if some flags are passed to Xcode/xcodebuild:

  1. swiftc reported compilation times. For using that feature, you need to build your project with the options -Xfrontend -debug-time-expression-type-checking and -Xfrontend -debug-time-function-bodies.
  2. ld64's statistics output. The statistics info can be generated by adding -Xlinker -print_statistics to Xcode's "Other Linker Flags" and it's useful for tracking linking time regression.
  3. Clang's time trace data. When the -ftime-trace flag is specified, clang will generate a json tracing file for each translation unit and XCLogParser will collect them and add its data to the parser output.

Examples:

xclogparser parse --project MyApp --reporter json --output build.json
xclogparser parse --file /path/to/log.xcactivitylog --reporter chromeTracer
xclogparser parse --workspace /path/to/MyApp.xcworkspace --derived_data /path/to/custom/DerivedData --reporter html --redacted

Example output available in the reporters section.

Available parameters

Parameter NameDescriptionRequired
--reporterThe reporter used to transform the logs. It can be either json, flatJson, summaryJson, chromeTracer, issues or html. (required)Yes
--fileThe path to the xcactivitylog.No *
--projectThe name of the project if you don't know the path to the log. The tool will try to find the latest Build log in a folder that starts with that name inside the DerivedData directory. Use --strictProjectName for stricter name matching.No *
--workspaceThe path to the xcworkspace file if you don't know the path to the log. It will generate the folder name for the project in the DerivedData folder using Xcode's hash algorithm and it will try to locate the latest Build Log inside that directory.No *
--xcodeprojThe path to the xcodeproj file if you don't know the path to the log and if the project doesn't have a xcworkspace file. It will generate the folder name for the project in the DerivedData folder using Xcode's hash algorithm and it will try to locate the latest Build Log inside that directory.No *
--derived_dataThe path to the derived data folder if you are using xcodebuild to build your project with the -derivedDataPath option.No
--outputIf specified, the JSON file will be written to the given path. If not defined, the command will output to the standard output.No
--rootOutputIf specified, the HTML file will be written to the given folder, it has precedence over output if the folder doesn't exist will be created. It works with relative home path.~No
--redactedIf specified, the username will be replaced by the word redacted in the file paths contained in the logs. Useful for privacy reasons but slightly decreases the performance.No
--without_build_specific_infoIf specified, build specific information will be removed from the logs (for example bolnckhlbzxpxoeyfujluasoupft will be removed from DerivedData/Product-bolnckhlbzxpxoeyfujluasoupft/Build ). Useful for grouping logs by its content.No
--strictProjectNameUsed in conjunction with --project. If specified, a stricter name matching will be done for the project name.No
--machine_nameIf specified, the machine name will be used to create the buildIdentifier. If it is not specified, the host name will be used.No
--omit_warningsOmit the warnings details in the final report. This is useful if there are too many of them and the report's size is too big with them.No
--omit_notesOmit the notes details in the final report. This is useful if there are too many of them and the report's size is too big with them.No
--trunc_large_issuesIf an individual task has more than a 100 issues (Warnings, notes, errors) it truncates them to be 100. This is useful to reduce the amount of memory used.No

No *: One of --file, --project, --workspace, --xcodeproj parameters is required.

Manifest Command

Outputs the contents of LogStoreManifest.plist which lists all the xcactivitylog files generated for the project as JSON.

Example:

xclogparser manifest --project MyApp

Example output:

{
  "scheme" : "MyApp",
  "timestampEnd" : 1548337458,
  "fileName" : "D6539DED-8AC8-4508-9841-46606D0C794A.xcactivitylog",
  "title" : "Build MyApp",
  "duration" : 46,
  "timestampStart" : 1548337412,
  "uniqueIdentifier" : "D6539DED-8AC8-4508-9841-46606D0C794A",
  "type" : "xcode"
}

Available parameters

Parameter NameDescriptionRequired
--log_manifestThe path to an existing LogStoreManifest.plist.No *
--projectThe name of the project if you don't know the path to the log. The tool will try to find the latest Build log in a folder that starts with that name inside the DerivedData directory. Use --strictProjectName for stricter name matching.No *
--workspaceThe path to the xcworkspace file if you don't know the path to the log. It will generate the folder name for the project in the DerivedData folder using Xcode's hash algorithm and it will try to locate the latest Build Log inside that directory.No *
--xcodeprojThe path to the xcodeproj file if you don't know the path to the log and if the project doesn't have a xcworkspace file. It will generate the folder name for the project in the DerivedData folder using Xcode's hash algorithm and it will try to locate the latest Build Log inside that directory.No *
--derived_dataThe path to the derived data folder if you are using xcodebuild to build your project with the -derivedDataPath option.No
--outputIf specified, the JSON file will be written to the given path. If not defined, the command will output to the standard output.No
--strictProjectNameUsed in conjunction with --project. If specified, a stricter name matching will be done for the project name.No

No *: One of --log-manifest, --project, --workspace, --xcodeproj parameters is required.

Reporters

The parse command has different types of reporters built-in that can represent and visualize the data of the logs:

JSON Reporter

This reporter parses the log and outputs it as JSON. It contains information about the duration of each step in the build, along other metadata and interesting information such as errors and warnings.

Example:

xclogparser parse --project MyApp --reporter json

Example Output

{
    "detailStepType" : "swiftCompilation",
    "startTimestamp" : 1545143336.649699,
    "endTimestamp" : 1545143336.649699,
    "schema" : "MyApp",
    "domain" : "com.apple.dt.IDE.BuildLogSection",
    "parentIdentifier" : "095709ba230e4eda80ab43be3b68f99c_1545299644.4805899_20",
    "endDate" : "2018-12-18T14:28:56.650000+0000",
    "title" : "Compile \/Users\/<redacted>\/projects\/MyApp\/Libraries\/Utilities\/Sources\/Disposables\/Cancelable.swift",
    "identifier" : "095709ba230e4eda80ab43be3b68f99c_1545299644.4805899_185",
    "signature" : "CompileSwift normal x86_64 \/Users\/<redacted>\/MyApp\/Libraries\/Utilities\/Sources\/Disposables\/Cancelable.swift",
    "type" : "detail",
    "buildStatus" : "succeeded",
    "subSteps" : [

    ],
    "startDate" : "2018-12-18T14:28:56.650000+0000",
    "buildIdentifier" : "095709ba230e4eda80ab43be3b68f99c_1545299644.4805899",
    "machineName" : "095709ba230e4eda80ab43be3b68f99c",
    "duration" : 5.5941859483718872,
    "errors" : "",
    "warnings" : "",
    "errorCount" : 0,
    "warningCount" : 0,
    "errors" : [],
    "warnings" : [],
    "swiftFunctionTimes" : [
      {
        "durationMS" : 0.08,
        "occurrences" : 5,
        "startingColumn" : 36,
        "startingLine" : 48,
        "file" : "file:\/\/\/Users\/<redacted>\/MyApp\/Libraries\/Utilities\/Sources\/Disposables\/Cancelable.swift",
        "signature" : "getter description"
      }
    ],
    "swiftTypeCheckTimes" : [
      {
        "durationMS" : 0.5,
        "occurrences" : 2,
        "startingColumn" : 16,
        "startingLine" : 9,
        "file" : "file:\/\/\/Users\/<redacted>\/MyApp\/Libraries\/Utilities\/Sources\/Disposables\/Cancelable.swift",
      }
    ]
}

For more information regarding each field, check out the JSON format documentation.

FlatJson Reporter

Parses the log as an array of JSON objects, with no nested steps (the field subSteps is always empty). Useful to dump the data into a database so it's easier to analyze.

The format of the JSON objects in the array is the same to the one used in the json reporter.

Example:

xclogparser parse --file path/to/log.xcactivitylog --reporter flatJson

Example Output

[
  {
    "parentIdentifier" : "",
    "title" : "Build MobiusCore",
    "warningCount" : 0,
    "duration" : 0,
    "startTimestamp" : 1558590748,
    "signature" : "Build MobiusCore",
    "endDate" : "2019-05-23T05:52:28.274000Z",
    "errorCount" : 0,
    "domain" : "Xcode.IDEActivityLogDomainType.BuildLog",
    "type" : "main",
    "identifier" : "68a2bbd0048a454d91b3734b5d5dc45e_1558640253_1",
    "buildStatus" : "succeeded",
    "schema" : "MobiusCore",
    "subSteps" : [

    ],
    "endTimestamp" : 1558590748,
    "architecture" : "",
    "machineName" : "68a2bbd0048a454d91b3734b5d5dc45e",
    "buildIdentifier" : "68a2bbd0048a454d91b3734b5d5dc45e_1558640253",
    "startDate" : "2019-05-23T05:52:28.244000Z",
    "documentURL" : "",
    "detailStepType" : "none"
  },
  {
    "parentIdentifier" : "68a2bbd0048a454d91b3734b5d5dc45e_1558640253_1",
    "title" : "Prepare build",
    "warningCount" : 0,
    "duration" : 0,
    "startTimestamp" : 1558590748,
    "signature" : "Prepare build",
    "endDate" : "2019-05-23T05:52:28.261000Z",
    "errorCount" : 0,
    "domain" : "Xcode.IDEActivityLogDomainType.XCBuild.Preparation",
    "type" : "target",
    "identifier" : "68a2bbd0048a454d91b3734b5d5dc45e_1558640253_2",
    "buildStatus" : "succeeded",
    "schema" : "MobiusCore",
    "subSteps" : [

    ],
    "endTimestamp" : 1558590748,
    "architecture" : "",
    "machineName" : "68a2bbd0048a454d91b3734b5d5dc45e",
    "buildIdentifier" : "68a2bbd0048a454d91b3734b5d5dc45e_1558640253",
    "startDate" : "2019-05-23T05:52:28.254000Z",
    "documentURL" : "",
    "detailStepType" : "none"
  },{
    "parentIdentifier" : "68a2bbd0048a454d91b3734b5d5dc45e_1558640253_1",
    "title" : "Build target MobiusCore",
    "warningCount" : 0,
    "duration" : 4,
    "startTimestamp" : 1558590708,
    "signature" : "MobiusCore-fmrwijcuutzbrmbgantlsfqxegcg",
    "endDate" : "2019-05-23T05:51:51.890000Z",
    "errorCount" : 0,
    "domain" : "Xcode.IDEActivityLogDomainType.target.product-type.framework",
    "type" : "target",
    "identifier" : "68a2bbd0048a454d91b3734b5d5dc45e_1558640253_3",
    "buildStatus" : "succeeded",
    "schema" : "MobiusCore",
    "subSteps" : [

    ],
    "endTimestamp" : 1558590712,
    "architecture" : "",
    "machineName" : "68a2bbd0048a454d91b3734b5d5dc45e",
    "buildIdentifier" : "68a2bbd0048a454d91b3734b5d5dc45e_1558640253",
    "startDate" : "2019-05-23T05:51:48.206000Z",
    "documentURL" : "",
    "detailStepType" : "none"
  },
  ...
]

For more information regarding each field, check out the JSON format documentation.

SummaryJson Reporter

Parses the log as a JSON object, with no nested steps (the field subSteps is always empty). Useful to get a high level summary of the build.

Example:

xclogparser parse --file path/to/log.xcactivitylog --reporter summaryJson

Example Output

  {
    "parentIdentifier" : "",
    "title" : "Build MobiusCore",
    "warningCount" : 0,
    "duration" : 0,
    "startTimestamp" : 1558590748,
    "signature" : "Build MobiusCore",
    "endDate" : "2019-05-23T05:52:28.274000Z",
    "errorCount" : 0,
    "domain" : "Xcode.IDEActivityLogDomainType.BuildLog",
    "type" : "main",
    "identifier" : "68a2bbd0048a454d91b3734b5d5dc45e_1558640253_1",
    "buildStatus" : "succeeded",
    "schema" : "MobiusCore",
    "subSteps" : [

    ],
    "endTimestamp" : 1558590748,
    "architecture" : "",
    "machineName" : "68a2bbd0048a454d91b3734b5d5dc45e",
    "buildIdentifier" : "68a2bbd0048a454d91b3734b5d5dc45e_1558640253",
    "startDate" : "2019-05-23T05:52:28.244000Z",
    "documentURL" : "",
    "detailStepType" : "none"
  }

For more information regarding each field, check out the JSON format documentation.

ChromeTracer Reporter

Parses the xcactivitylog as an array of JSON objects in the format used by the Chrome tracer. You can use this JSON to visualize the build times in the Chrome tracing tool inside Chrome: chrome://tracing.

Example:

xclogparser parse --file path/to/log.xcactivitylog --reporter chromeTracer

Example Output

Issues Reporter

Outputs the list of Errors and Warnings found in the log as a JSON document. Useful when you only want to check the issues found while building.

Example:

xclogparser parse --file path/to/log.xcactivitylog --reporter issues

Example Output

```json
{
  "errors" : [
    {
      "characterRangeStart" : 0,
      "startingColumnNumber" : 5,
      "endingColumnNumber" : 30,
      "characterRangeEnd" : 18446744073709551615,
      "title" : "use of undeclared type 'AType'",
      "endingLineNumber" : 10,
      "type" : "swiftError",
      "documentURL" : "file:\/\/\/MyProject\/MyFile.swift",
      "startingLineNumber" : 10,
      "severity" : 1
      "detail": "\/MyProject\/MyFile.swift:10:5: error: use of undeclared type 'AType'\r    func doSomething(completion: @escaping () -> AType) -> void) {\r^~~~\r"
    }
  ],
  "warnings" : [
    {
      "characterRangeStart" : 0,
      "startingColumnNumber" : 5,
      "endingColumnNumber" : 30,
      "characterRangeEnd" : 18446744073709551615,
      "title" : "Warning",
      "endingLineNumber" : 10,
      "type" : "swiftWarning",
      "documentURL" : "file:\/\/\/MyProject\/MyFile.swift",
      "startingLineNumber" : 10,
      "severity" : 1
    }
  ]
}
```

HTML Reporter

Generates an HTML report to visualize build times per module and file, along with warning and error messages.

Example:

xclogparser parse --file path/to/log.xcactivitylog --reporter html --output build/reports

Example Output

Requirements and Compatibility

EnvironmentVersion
🛠 Xcode11.0
🐦 LanguageSwift 5.0

Status

XCLogParser is currently in alpha status. We are using it internally and tested it on various projects, but we need the help from the community to test and improve it with more iOS and Mac applications.

Development and Contributing

MacOS:

  1. Clone the repo with git clone git@github.com:MobileNativeFoundation/XCLogParser.git.
  2. Run rake gen_resources to generate a static resource Swift file that is needed to compile the app.
  3. Run swift package generate-xcodeproj to generate a Xcode project (or use any text editor).
  4. Run tests in Xcode directly (CMD + U) or using rake test.
  5. Create issue and discuss a possible solution or improvement.
  6. Create a PR.

Linux:

  1. A Dockerfile is provided, you can create an image with the tag xlogparser: docker build --tag xclogparser .
  2. To compile the app in Linux, just run the shell script: ./run-in-docker.sh

If you find a bug or you would like to propose an improvement, you're welcome to create an issue.

Release

  1. Make sure version set in Version.swift is updated
  2. Create new release tag in GitHub with a tag format like vx.x.x. Provide release title and description.
  3. Build release artifacts:
    1. for macOS, build an artifact using DEVELOPER_DIR=<path_to_xcode_version> rake archive. Use Xcode version matching with Requirements section.
    2. for Linux, run ./build_release_in_docker.sh
  4. Upload release artifacts to the release version summary:
    1. for macOS, upload zip file placed in releases/XCLogParser-x.x.x.zip
    2. for Linux, update current version in the filename and upload releases/linux/XCLogParser-x.x.x-Linux.zip

Code of Conduct

This project adheres to the Open Code of Conduct. By participating, you are expected to honor this code.

Download Details:

Author: MobileNativeFoundation
Source Code: https://github.com/MobileNativeFoundation/XCLogParser 
License: Apache-2.0 license

#swift #xcode #package 

Tool To Parse Xcode, Xcodebuild Logs Stored in Xcactivitylog format
Rupert  Beatty

Rupert Beatty

1667392740

Tool for Detecting The Current Device and Screen Size Written in Swift

Device

Device detect the current  device model and screen size.

Installation

CocoaPods

Device is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod "Device", '~> 3.3.0'

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.

You can install Carthage with Homebrew using the following command:

$ brew update
$ brew install carthage

To integrate Device into your Xcode project using Carthage, specify it in your Cartfile:

github "Ekhoo/Device" ~> 3.3.0

Run carthage update to build the framework and drag the built Device.framework into your Xcode project.

Swift Package Manager

The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swift compiler.

Once you have your Swift package set up, adding Device as a dependency is as easy as adding it to the dependencies value of your Package.swift.

dependencies: [
    .package(url: "https://github.com/Ekhoo/Device.git", from: "3.3.0")
]

Usage

iOS

Device version

func myFunc() {
        /*** Display the device version ***/
        switch Device.version() {
            /*** iPhone ***/
            case .iPhone4:       print("It's an iPhone 4")
            case .iPhone4S:      print("It's an iPhone 4S")
            case .iPhone5:       print("It's an iPhone 5")
            case .iPhone5C:      print("It's an iPhone 5C")
            case .iPhone5S:      print("It's an iPhone 5S")
            case .iPhone6:       print("It's an iPhone 6")
            case .iPhone6S:      print("It's an iPhone 6S")
            case .iPhone6Plus:   print("It's an iPhone 6 Plus")
            case .iPhone6SPlus:  print("It's an iPhone 6 S Plus")
            case .iPhoneSE:      print("It's an iPhone SE")
            case .iPhone7:       print("It's an iPhone 7")
            case .iPhone7Plus:   print("It's an iPhone 7 Plus")
            case .iPhone8:       print("It's an iPhone 8")
            case .iPhone8Plus:   print("It's an iPhone 8 Plus")
            case .iPhoneX:       print("It's an iPhone X")
            case .iPhoneXS:      print("It's an iPhone Xs")
            case .iPhoneXS_Max:  print("It's an iPhone Xs Max")
            case .iPhoneXR:      print("It's an iPhone Xr")

            /*** iPad ***/
            case .iPad1:           print("It's an iPad 1")
            case .iPad2:           print("It's an iPad 2")
            case .iPad3:           print("It's an iPad 3")
            case .iPad4:           print("It's an iPad 4")
            case .iPad5:           print("It's an iPad 5")
            case .iPad6:           print("It's an iPad 6")
            case .iPadAir:         print("It's an iPad Air")
            case .iPadAir2:        print("It's an iPad Air 2")
            case .iPadMini:        print("It's an iPad Mini")
            case .iPadMini2:       print("It's an iPad Mini 2")
            case .iPadMini3:       print("It's an iPad Mini 3")
            case .iPadMini4:       print("It's an iPad Mini 4")
            case .iPadPro9_7Inch:  print("It's an iPad Pro 9.7 Inch")
            case .iPadPro10_5Inch: print("It's an iPad Pro 10.5 Inch")
            case .iPadPro12_9Inch: print("It's an iPad Pro 12.9 Inch")

            /*** iPod ***/
            case .iPodTouch1Gen: print("It's a iPod touch generation 1")
            case .iPodTouch2Gen: print("It's a iPod touch generation 2")
            case .iPodTouch3Gen: print("It's a iPod touch generation 3")
            case .iPodTouch4Gen: print("It's a iPod touch generation 4")
            case .iPodTouch5Gen: print("It's a iPod touch generation 5")
            case .iPodTouch6Gen: print("It's a iPod touch generation 6")

            /*** Simulator ***/
            case .Simulator:    print("It's a Simulator")

            /*** Unknown ***/
            default:            print("It's an unknown device")
        }
    }

Device screen size

func myFunc() {
        /*** Display the device screen size ***/
        switch Device.size() {
            case .screen3_5Inch:  print("It's a 3.5 inch screen")
            case .screen4Inch:    print("It's a 4 inch screen")
            case .screen4_7Inch:  print("It's a 4.7 inch screen")
            case .screen5_5Inch:  print("It's a 5.5 inch screen")
            case .screen5_8Inch:  print("It's a 5.8 inch screen")
            case .screen6_1Inch:  print("It's a 6.1 inch screen")
            case .screen6_5Inch:  print("It's a 6.8 inch screen")
            case .screen7_9Inch:  print("It's a 7.9 inch screen")
            case .screen9_7Inch:  print("It's a 9.7 inch screen")
            case .screen10_5Inch: print("It's a 10.5 inch screen")
            case .screen12_9Inch: print("It's a 12.9 inch screen")
            default:              print("Unknown size")
        }
}

Device type

func myFunc() {
        /*** Display the device type ***/
        switch Device.type() {
            case .iPod:         print("It's an iPod")
            case .iPhone:       print("It's an iPhone")
            case .iPad:         print("It's an iPad")
            case .Simulator:    print("It's a Simulated device")
            default:            print("Unknown device type")
        }
}

or

func myFunc() {
        /*** Display the device type ***/
        if (Device.isPad()){
            print("It's an iPad")
        }
        else if (Device.isPhone()){
            print("It's an iPhone")
        }
        else if (Device.isPod()){
            print("It's an iPod")
        }
        else if (Device.isSimulator()){
            print("It's a Simulated device")
        }
}

Mac

Mac version

func myFunc() {
        /*** Display the mac version ***/
        switch Device.type() {
            case .iMac:         print("It's an iMac")
            case .macBook:      print("It's a MacBook")
            case .macBookAir:   print("It's a MacBook Air")
            case .macBookPro:   print("It's a MacBook Pro")
            default:            print("Unknown device type")
        }
    }

Mac screen size

func myFunc() {
        /*** Display the mac screen size ***/
        switch Device.size() {
            case .screen11Inch:     print("It's a 11 inch screen")
            case .screen12Inch:     print("It's a 12 inch screen")
            case .screen13Inch:     print("It's a 13 inch screen")
            case .screen15Inch:     print("It's a 15 inch screen")
            case .screen17Inch:     print("It's a 17 inch screen")
            case .screen21_5Inch:   print("It's a 21.5 inch screen")
            case .screen27Inch:     print("It's a 27 inch screen")
            default:                print("Unknown size")
        }
}

Helpers

func myFunc() {
        /*** Helpers ***/
        if Device.size() == Size.screen4Inch {
            print("It's a 4 inch screen")
        }

        if Device.size() > Size.screen4_7Inch {
            print("Your device screen is larger than 4.7 inch")
        }

        if Device.size() < Size.screen4_7Inch {
            print("Your device screen is smaller than 4.7 inch")
        }

        if Device.size() == Size.screen27Inch {
            print("It's a 27 inch screen")
        }
        
        if Device.size() > Size.screen15Inch {
            print("Your mac screen is larger than 15 inch")
        }
        
        if Device.size() < Size.screen15Inch {
            print("Your mac screen is smaller than 15 inch")
        }

        if Device.isRetina() {
            print("It's a retina display")
        }
        
}

Download Details:

Author: Ekhoo
Source Code: https://github.com/Ekhoo/Device 
License: MIT license

#swift #macos #ios #xcode 

Tool for Detecting The Current Device and Screen Size Written in Swift
Rupert  Beatty

Rupert Beatty

1667357520

Swimat: An Xcode formatter Plug-in to Format Your Swift Code

Swimat

Swimat is an Xcode plug-in to format your Swift code.

Preview

preview.gif

Installation

There are three way to install.

Install via homebrew-cask

# Homebrew previous version
brew cask install swimat
# Homebrew latest version
brew install --cask swimat

Download the App directly.
https://github.com/Jintin/Swimat/releases/download/1.7.0/Swimat.zip

Clone and archive to Mac App by yourself.

Usage

After installation, you should open the Swimat.app once to make the functionality works.

In the Xcode menu click [Editor] -> [Swimat] -> [Format] then the current active file will reformat.

You can also create a hot-key in [Xcode] -> [Preferences..] -> [Key Bindings], if you don't have any prefernce you can set as ⌘ + ⇧ + L.

TroubleShooting

Check [System Preferences] -> [Extensions] -> [Xcode Source Editor] -> [Swimat] is checked.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/Jintin/Swimat.

Download Details:

Author: Jintin
Source Code: https://github.com/Jintin/Swimat 
License: MIT license

#swift #xcode #plugin 

Swimat: An Xcode formatter Plug-in to Format Your Swift Code
Rupert  Beatty

Rupert Beatty

1667330160

TestDrive: Quickly Try Out any Swift Pod Or Framework in A Playground

Test Drive 🚘

With Test Drive, you can quickly try out any Swift pod or framework in a playground. Simply run testdrive followed by the name of a pod, or the URL to a Git repository, and you will have a playground generated for you in no time!

TestDrive.gif

Features

  •  Quickly try out a pod/framework without having to modify your project.
  •  Try out multiple pods/frameworks at once - ideal when comparing similar ones.
  •  Supports iOS, macOS & tvOS.

Usage

🚗 Take a pod for a test drive:

$ testdrive Unbox

🚙 Take a framework from a Git URL for a test drive:

$ testdrive git@github.com:johnsundell/files.git

🚕 Take multiple pods at once for a test drive:

$ testdrive Unbox Wrap

🏎 Take a test drive on a specific platform (iOS is the default):

$ testdrive Unbox -p tvOS

🚓 Use a specific version or branch for your test drive (the latest version is used by default):

$ testdrive Unbox -v 2.3.0
$ testdrive Unbox -v swift3
$ testdrive Wrap --master

Installation

The easiest way to install Test Drive is using Marathon:

$ marathon install johnsundell/testdrive

You can also install it using the Swift Package Manager:

$ git clone https://github.com/JohnSundell/TestDrive.git
$ cd TestDrive
$ swift build -c release
$ cp -f .build/release/TestDrive /usr/local/bin/testdrive

Issues + support

I spend almost all of my available time building tools, content and learning materials for the Swift community — all of which are available to everyone, for free. However, since I’m just one person, I do have to prioritize what I spend my time on — and one thing I’m currently not able to offer is 1:1 support for open source projects. That’s why this repository has Issues disabled. It’s not because I don’t want to help, I really do, I’m just simply not able to.

So before you start using this tool, I recommend that you spend a few minutes familiarizing yourself with its internals (it’s all normal Swift code), so that you’ll be able to self-service on any issues or edge cases you might encounter.

Thanks for understanding, and I hope you’ll enjoy TestDrive!

— John

Download Details:

Author: JohnSundell
Source Code: https://github.com/JohnSundell/TestDrive 
License: MIT license

#swift #xcode #prototype 

TestDrive: Quickly Try Out any Swift Pod Or Framework in A Playground
Rupert  Beatty

Rupert Beatty

1667306891

A summary of Apple's Swift language written on Playgrounds

The Swift Summary Book

A summary of Apple's Swift language written on Playgrounds.

Why this summary?

Apple's documentation is great for learning Swift, but who's got the time to read all that? :smile:

This summary cuts to the chase. It is directly written on the Playgrounds platform, which makes it very interactive. You can tinker around with it as much as you like!

Inside the Box

Once you've downloaded or cloned the repository and you open it with Xcode, you'll find most of the chapters from Apple's documentation, plus a Resources folder that contains extra material. The numbering in each chapter is consistent with Apple's. Chapters with a strikethrough have not been added to the book yet as being considered unimportant. More specifically, you'll find:

Chapters

  1. The Basics
  2. Basic Operators
  3. Strings and Characters
  4. Collection Types
  5. Control Flow
  6. Functions
  7. Closures
  8. Enumerations
  9. Classes & Structs
  10. Properties
  11. Methods
  12. Subscripts
  13. Inheritance
  14. Initialization
  15. Deinitialization
  16. ARC
  17. Optional Chaining
  18. Error Handling
  19. Type Casting
  20. Nested Types
  21. Extensions
  22. Protocols
  23. Generics
  24. Access Control

Resources

  • Higher Order Functions

How should I install this?

Getting started with The Swift Summary Book is a piece of 🎂:

  1. Just clone or download the repository.
  2. You need to have Xcode v8.0 or above. You can download it here.
  3. Open the .swift file with Xcode and voilà!

What are the features?

The Swift Summary Book takes advantage of the Playground platform and many of its powerful capabilities:

  • The book is made of a single file that contains all chapters inside, which allows for easy access.
  • Chapters use the Playground Markup Language, which brings rich documentation to the code examples.
  • Every chapter has Page Linking, which allows to go back and forth from one chapter to the next, previous or another that was mentioned with in the chapter.

Keep in mind

The Swift language is still under rapid development, which means that the documentation is changing all the time, and some sections might break at a given time.

You can help too!

  • Help me keep this summary :+1: by creating pull requests and issues!
  • Share this project and make sure you and others give it a ⭐

You can find me on

  • 🐦 twitter: @jkarmy.
  • ☕️ If you like the open-source work I do, consider buying me a coffee so I can stay awake and keep typing away!

Download Details:

Author: jakarmy
Source Code: https://github.com/jakarmy/swift-summary 
License: MIT license

#swift #apple #xcode #language 

A summary of Apple's Swift language written on Playgrounds
Rupert  Beatty

Rupert Beatty

1667303100

Xcode Extension to Paste JSON As Swift, Objective-C, and More

Quicktype

quicktype infers types from sample JSON data, then outputs strongly typed models and serializers for working with that data in Swift, Objective-C, C++, Java and more. This extension adds native quicktype support to Xcode 9.

paste json as code

paste json as code

Development

Install prereqs and bundle quicktype

$ npm install

Try quicktype in your browser.

Download Details:

Author: quicktype
Source Code: https://github.com/quicktype/quicktype-xcode 
License: Apache-2.0 license

#swift #json #objective-c #xcode

Xcode Extension to Paste JSON As Swift, Objective-C, and More
Rupert  Beatty

Rupert Beatty

1667284640

A Circular Progress Bar for IOS Written in Swift

UICircularProgressRing

UICircularProgress ring is a library for rendering circular progress rings and timers.

  • Declarative: Written using SwiftUI (legacy UIKit version available), UICircularProgressRing is declarative making it easy to read, and easy to use.
  • Customizable: Designed to be used in production, all of the views are highly customizable without giving up ease of use. This allows the developer to tailor the look, feel and functionality to fit their needs.
  • Tested: Battle tested in many production applications. UICircularProgressRing is also fully unit tested as well as snapshot tested so developers can feel safe.
  • Documented: UICircularProgressRing's public API is 100% documented and its something that is enforced before any code is ever added. This is a resource that will help any new user understand how to get the most out of this library.

iOS 14+ Note

Since Apple has now added a built in ProgressView the need for this library is about to be over. My recommendation: If you can support iOS 14.0 and use the new system ProgressView then you should use that. This library will be continued to be maintained (critical bugs will be fixed, etc) but no new features are planned as we are reaching EOL for this library.

Installation

UICircularProgressRing is available in two major versions. The latest version v7.0+ or legacy versions. The legacy version is written using UIKit and requires a deployment target of iOS 8.0+ or tvOS 10.0+. The latest version is written in SwiftUI and requires iOS 13.0+, macOS 15.0+, tvOS 13.0+ or WatchOS 2.0+.

For legacy installation, follow these instructions.

Swift Package Manager

Simply add this library to your package manifest or follow instructions on adding a package dependency using Xcode here.

.package(
    url: "https://github.com/luispadron/UICircularProgressRing.git",
    .branch("master")
)

Documentation

This projects public API is 100% documented and it's something we spend a lot of time working on. Please make sure to read the documentation before opening any issues, questions, etc.

Read the documentation 📖

Usage

ProgressRing

ProgressRing is a view designed to display some kind of progress, this can be anything which is represented as a percentage in the range [0, ∞). A percentage is represented in decimal format, i.e. 0.5 is 50%. Progress may be a downloading operation, the grade percentage of a users test score, etc. A short example of using ProgressRing is shown below, for more details read the docs or play with the example app.

struct ProgressRingExample: View {
    @State var progress = RingProgress.percent(0.44)

    var body: some View {
        VStack {
            ProgressRing(
                progress: $progress,
                axis: .top,
                clockwise: true,
                outerRingStyle: .init(
                    color: .color(.gray),
                    strokeStyle: .init(lineWidth: 20)
                ),
                innerRingStyle: .init(
                    color: .color(.green),
                    strokeStyle: .init(lineWidth: 10),
                    padding: 5
                )
            )
                .animation(.easeInOut(duration: 5))
                .padding(32)
        }
    }
}

An example image of a ProgressRing view rendered with a green inner circle, a gray outer circle and at 44 percent completion.

TimerRing

TimerRing is a view designed to display time. You initialize the timer by giving it a unit of time and duration, for example: .seconds(60). This means the TimerRing will run for 60 seconds, filling up the inner ring until finally reaching 100% around the entire outer ring. A short example of using TimerRing is shown below, for more details read the docs or play with the example app.

struct TimerRingExample: View {
    @State var isPaused = false
    @State var isDone = false

    var body: some View {
        TimerRing(
            time: .minutes(1),
            delay: .seconds(0.5),
            innerRingStyle: .init(
                color: .color(.green),
                strokeStyle: .init(lineWidth: 16),
                padding: 8
            ),
            isPaused: $isTimerPaused,
            isDone: $isTimerDone
        ) { currentTime in
            Text(timeFormatter.string(from: currentTime))
                .font(.title)
                .bold()
        }
    }
}

A demo image of a timer ring view with a green inner ring, a gray outer ring and at twenty-seven seconds.

Examples

Apps Using UICircularProgressRing

Download Details:

Author: luispadron
Source Code: https://github.com/luispadron/UICircularProgressRing 
License: MIT license

#swift #ios #xcode #progress 

A Circular Progress Bar for IOS Written in Swift
Rupert  Beatty

Rupert Beatty

1667107080

SwiftPlate: Easily Generate Cross Platform Swift Framework Projects

SwiftPlate

Easily generate cross platform Swift framework projects from the command line.

SwiftPlate will generate Xcode projects for you in seconds, that support:

  •  CocoaPods
  •  Carthage
  •  Swift Package Manager
  •  iOS
  •  macOS
  •  watchOS
  •  tvOS
  •  Linux

Just run swiftplate, and you’ll be presented with a simple step-by-step guide:

Screenshot

Usage

Using Homebrew (recommended)

$ brew install swiftplate
$ swiftplate

Using Make

$ git clone git@github.com:JohnSundell/SwiftPlate.git
$ cd swiftplate
$ make

Using Marathon

$ git clone git@github.com:JohnSundell/SwiftPlate.git
$ marathon run swiftplate/main

Using the Swift interpreter directly

$ git clone git@github.com:JohnSundell/SwiftPlate.git
$ swift swiftplate/main.swift

Using Xcode

$ git clone git@github.com:JohnSundell/SwiftPlate.git
$ open swiftplate/SwiftPlate.xcodeproj

Command line arguments

Besides using the guide to input information, SwiftPlate also supports command line arguments when launched. When a certain piece of information is supplied through an argument, SwiftPlate won't ask for that information when run. These are the arguments currently supported:

NameDescriptionLong parameterShort parameter
DestinationWhere the generated project should be saved--destination-d
Project nameThe name of your project--project-p
Author nameYour name--name-n
Author emailYour email (for Podspec)--email-e
GitHub URLAny URL you'll be hosting the project at (for Podspec)--url-u
Organization nameThe name of your organization--organization-o
RepoAny custom SwiftPlate repository that should be used for templates--repo-r
ForcePrevent user prompt at the end (for CIs etc.)--force-f

Questions or feedback?

Feel free to open an issue, or find me @johnsundell on Twitter.

Download Details:

Author: JohnSundell
Source Code: https://github.com/JohnSundell/SwiftPlate 
License: MIT license

#swift #cli #xcode #script #generate 

 SwiftPlate: Easily Generate Cross Platform Swift Framework Projects