Skip to content

Instantly share code, notes, and snippets.

@csknns
csknns / preprocess-plists.sh
Last active November 19, 2022 08:06
Xcode build phase script to preprocess a plist file
#!/usr/bin/env bash
# Add this to a custom build phase script to enable preprocessing plist files.
#
# This takes as input all the input files from the build phase script
# and runs the preprocessor using the token definitions from the GCC_PREPROCESSOR_DEFINITIONS
# enviroment variable.
#
# This allows you to have the following plist:
#
# <dict>
@csknns
csknns / replacePlistEnvironmentVariables.swift
Last active April 14, 2023 08:35
Replaces referenced environment variables (e.g. $(BUILD_VERSION)) in a plist file
// Usage:
// $/usr/bin/xcrun --sdk macosx swift replacePlistEnvironmentVariables.swift "$inputfile.plist" "$outputfile"
// This will replace all the referenced enviroment variables with their value, for example:
// <string>$(A_VARIABLE)</string>
import Foundation
enum ScriptError: Error {
case invalidPlistArgument(argument: URL)
case sameInputAndOutptFile
}
@csknns
csknns / swiftUI_modifiers_at_begining.swift
Created October 1, 2022 10:20
allow declaring SwiftUI view modifiers at the begining of the view instance
// Example of a convient method to allow declaring
// the view modifiers at the begining of the view instance
// instead at the end.
extension VStack {
static func with<T: View>(modifiers: (Self) -> T, alignment: HorizontalAlignment = .center, spacing: CGFloat? = nil, @ViewBuilder content: () -> Content) -> some View {
modifiers(VStack(alignment: alignment,
spacing: spacing,
content: content))
}
}
// Hold the filter and the closure that updates its value
var filtersAndValueUpdaters: [ (Filter, ((Float, Int) -> Void)) ] = []
// The selected filter has also the closure that updates its value
var selectedfilter: (Filter, (Float, Int) -> Void)
let filterA = FilterA()
filtersAndValueUpdaters.append((filterA, { [weak filterA] value, _ in
filterA?.param = value
}))
// Helper macros to convert a preprocessor token to String
#define xstr(s) str(s)
#define str(s) #s
// Example of compile time assertions to validate that tha macro argument was not empty
// and avoid building a application that will fail at runtime
// Clang and gcc are both able to compute this at compile-time, you can use sizeOf()
// instead of the build-in method here.
_Static_assert(__builtin_strlen(xstr(OAUTH_CLIENT_ID)) > 0,
"The OAUTH_CLIENT_ID is missing");
@csknns
csknns / UIViewControllerTransitionCoordinatorMocked.swift
Created November 21, 2021 11:08
example of UIViewControllerTransitionCoordinator Mocked
class UIViewControllerTransitionCoordinatorMocked: NSObject, UIViewControllerTransitionCoordinator {
var animateWasCalled = false
func animate(alongsideTransition animation: ((UIViewControllerTransitionCoordinatorContext) -> Void)?, completion: ((UIViewControllerTransitionCoordinatorContext) -> Void)? = nil) -> Bool {
animateWasCalled = true
if let completion = completion {
completion(self)
@csknns
csknns / test.swift
Created July 18, 2021 16:28
Example of Future that will crash when it resolves, if handleEvents capture's self and self is de-allocated
import Foundation
import Combine
var dispatchGroup = DispatchGroup()
dispatchGroup.enter()
DispatchQueue.global().asyncAfter(deadline: .now() + 3, execute: {
dispatchGroup.leave()
})
@csknns
csknns / sort_sources.rb
Last active October 18, 2022 12:18
Script to sort the files in the 'Compile Sources', 'Copy Bundle Resources' and 'Copy files' sections under Build Phase in Xcode
#!/usr/bin/env ruby
require 'xcodeproj'
require 'set'
project_file, target_name = ARGV
# open the project
project = Xcodeproj::Project.open(project_file)
# find the target
@csknns
csknns / post_integrate_cocoapods_hook.rb
Last active September 1, 2020 20:06
Post integration Cocoapods hook workaround
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'
use_frameworks!
target 'TargetName' do
end
class Pod::Installer
# The only way to run my custom method after the pod integrates with the project (http://blog.bigbinary.com/2012/01/08/alias-vs-alias-method.html)
# Repace the method implementation integrate_user_project with ours
commit=`git rev-parse --short HEAD`
branch=`git rev-parse --abbrev-ref HEAD`
build=`/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${INFOPLIST_FILE}"`
version=`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${INFOPLIST_FILE}"`
function processIcon() {
export PATH=$PATH:/usr/local/bin
base_file=$1
base_path=`find ${SRCROOT}/DominosOrder -name $base_file`
flag_image=`find ${SRCROOT}/DominosOrder -name top_left_flag.png`