arm1.ru

Tag: «шпаргалки»

Creating a DMG File from the Terminal

event Apr 11, 2024 at 21:33

Creating a DMG file from Terminal

Have you ever needed to package your application for distribution on macOS? The solution is simpler than you might think, and it's right at your fingertips in the Terminal. I recently stumbled upon a handy bash function that streamlines the creation of a DMG (Disk Image) file. Here's how to set it up:

Step 1: Edit Your Profile

nano ~/.zprofile

Step 2: Add the Bash Function

Next, insert the following function into your .zprofile. This script utilizes the hdiutil command, which is built into macOS, to create an HFS+ filesystem within a DMG file.

dmg(){
    hdiutil create -fs HFS+ -srcfolder "$1" -volname "$2" "$2.dmg"
}

Step 3: Save and Source Your Profile

After adding the code, save the changes and exit `nano`. To make the function available immediately without restarting your terminal, source your profile:

source ~/.zprofile

Step 4: Use the Function

Now, you can easily create a DMG file for any folder or application. For example, to create a DMG for the 'ModulbankInformer.app', simply run:

dmg ModulbankInformer.app ModulbankInformer

This command will generate a ModulbankInformer.dmg file with the contents of the ModulbankInformer.app directory.

And there you have it - a quick and efficient way to create DMG files directly from your Terminal!

A middleware for Vapor 4 routing to trim a slash in url path

event Apr 4, 2024 at 15:08

It’s a common thing for a website or a backend to allow URLs like mySite.com/webpage and mySite.Com/webpage/ for the same page. These pages are different URLs for a search engine. If you want to avoid duplicates, you can add a simple middleware to trim the ending slash and redirect a user.

Here’s an example code for such a middleware class for Vapor 4:

final class TrimSlashInPathMiddleware: Middleware {
    func respond(to request: Request, chainingTo next: Responder) -> EventLoopFuture<Response> {
        if request.url.path.count > 1, request.url.path.hasSuffix("/") {
            let newPath = String(request.url.path.trimmingSuffix(while: { $0 == "/" }))
            let response = request.redirect(to: newPath, redirectType: .permanent)
            return request.eventLoop.makeSucceededFuture(response)
        }
        return next.respond(to: request)
    }
}

Just add it to configure.swift file:

import Vapor

public func configure(_ app: Application) throws {
    app.middleware.use(TrimSlashInPathMiddleware())

    app.http.server.configuration.port = 8081

    try routes(app)
}

Works with Vapor 4.92.5.

Password generation using Security Framework on iOS and macOS

event Jul 2, 2021 at 16:12

Couple lines of code to generate a 15 characters length password (just like in Safari):

import Security

let pass = SecCreateSharedWebCredentialPassword() as String?
print(pass as Any)

Wrapping models in SwiftUI for Identifiable conformance

event Mar 29, 2020 at 17:33

Using an array of models in List view in SwiftUI requires conformance to Identifiable protocol.

Here's an example of a model:

struct MyDataModel {
    let title: String
    let message: String
} 

An example of SwiftUI view that you want to display a list:

struct TestView: View {
    var dataArray: [MyDataModel]
    var body: some View {
        List(dataArray) { data in
            VStack {
                Text(data.title)
                Text(data.message)
            }
        }
    }
} 

Using MyDataModel in List will show an error in Xcode:

Xcode Identifiable conformance error

Sometimes you can't just change a model. It might be a data model from a third party SDK that you're using in your app. But you can create a wrapper for this struct to confirm Identifiable protocol:

struct MyDataModelWrapper: Identifiable {
    var id = UUID()
    var data: MyDataModel
}

let testDataModel = MyDataModel(
    title: "Title 1",
    message: "I wanna be used inside of a List"
)

let wrappedData = MyDataModelWrapper(data: testDataModel)

So the view will look like this:

struct TestView: View {
    var dataArray: [MyDataModelWrapper] 

    some View {
        List(dataArray) { wrappedData in
            VStack {
                Text(wrappedData.data.title)
                Text(wrappedData.data.message)
            }
        }
    }
}

Done.

Using GitHub Actions as a CI for Swift project

event Sep 10, 2019 at 16:57

Github Actions

Here's a config for a GitHub Actions workflow to build a Swift project. This example is for building a Vapor project using Swift 5.0.3 on Ubuntu 18.04:

name: Ubuntu 18.04 Swift 5.0.3

on: [push]

jobs:
  build_on_ubuntu:
    runs-on: ubuntu-18.04

    steps:
    - name: Install dependencies
      run: sudo apt-get update; sudo apt-get install -yq libssl-dev zlib1g-dev

    - name: Checkout
      uses: actions/checkout@master

    - name: Download Swift
      run: curl https://swift.org/builds/swift-5.0.3-release/ubuntu1804/swift-5.0.3-RELEASE/swift-5.0.3-RELEASE-ubuntu18.04.tar.gz --output swift.tar.gz

    - name: Unpack Swift
      run: |
          tar xzf swift.tar.gz
          mv swift-5.0.3-RELEASE-ubuntu18.04 swift

    - name: Swift build
      run: |
          export PATH=$(pwd)/swift/usr/bin:"${PATH}"
          swift build -c release

Shake effect animation for UIView

event Oct 28, 2016 at 15:57
// MARK: - UIView Extension, or NSView
extension UIView {

    /// Shake animation
    func shake() {
        let animation = CAKeyframeAnimation(keyPath: "transform.rotation")
        animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
        animation.duration = 1.0
        animation.values = [-Double.pi / 6, Double.pi / 6, -Double.pi / 6, Double.pi / 6, -Double.pi / 7, Double.pi / 7, -Double.pi / 8, Double.pi / 8, 0.0 ]

        layer.add(animation, forKey: "shake")
    }

}

myView.shake()