Skip to content

Instantly share code, notes, and snippets.

@briancroom
briancroom / Swift.md
Last active February 6, 2024 18:26
How to create a Swift modular library

I am trying to determine if it is possible to build a Swift dynamic library which is itself composed of one of more private modules, without needing to expose to that fact to outside users. My hope was that I could build the private module as a static library, which would be linked into the primary (dynamic) library. The dylib could then be deployed together with its swiftmodule and swiftdoc and be imported, with the private module and its symbols not being exposed at all.

Unfortunately, what I'm currently observing seems to indicate that the private module's swiftmodule also has to be available for the primary library to be successfully imported.

This can be reproduced as follows. I have the following directory structure:

./Greeter/Logger/Logger.swift:

public func log(_ message: String) {
@briancroom
briancroom / PromiseMatchers.swift
Created February 26, 2016 02:06
Custom Nimble matcher for use with the Promissum library
import Promissum
import Nimble
private func stringifyPromise<T, U>(promise: Promise<T, U>) -> String {
switch promise.result {
case nil: return "<pending>"
case let .Value(value)?: return "<resolved: \(value)>"
case let .Error(error)?: return "<rejected: \(error)>"
}
}
@briancroom
briancroom / MatchError.swift
Created February 26, 2016 01:13
Quick&dirty Nimble matcher for testing ErrorType equality. Requires no casting or Equatable conformance!
@testable import Nimble
public func matchError<T: ErrorType>(expectedValue: T?) -> NonNilMatcherFunc<ErrorType> {
return NonNilMatcherFunc { actualExpression, failureMessage in
defer { failureMessage.postfixMessage = "match <\(T.self).\(stringify(expectedValue))>" }
if try actualExpression.evaluate() is T {
return try equal(expectedValue as? NSError).matches(
actualExpression.cast({ $0 as? NSError }),
failureMessage: failureMessage
@briancroom
briancroom / XCTestCaseProvider.swift
Last active January 19, 2016 20:20
Make XCTest tests fail on OS X unless they have been added to `allTests` for Linux support
import Foundation
import XCTest
// XCTestCaseProvider is defined on Linux as part of swift-corelibs-xctest,
// but is not available on OS X. By defining this protocol and extension
// we ensure that the tests fail on OS X if they haven't been configured properly
// to be run on Linux
#if !os(Linux)
@briancroom
briancroom / xctest_finder.py
Last active April 17, 2016 11:05
Script to assist with conforming to XCTestCaseProvider
#!/usr/bin/python
# Invoke this script with a Swift file containing an XCTestCase and it will
# generate an implementation for the `allTests` variable required for
# XCTestCaseProvider conformance on Linux
import sys
import re
inFile = open(sys.argv[1]) if len(sys.argv) > 1 else sys.stdin
@briancroom
briancroom / Test.swift
Created December 23, 2015 02:45
Test fixture for the assertion failure messages produced by XCTest
import XCTest // import SwiftXCTest
class Test: XCTestCase/*, XCTestCaseProvider*/ {
var allTests : [(String, () -> Void)] {
return [
("testAssert", testAssert),
("testAssertEqualOptionals", testAssertEqualOptionals),
("testAssertEqualArraySlices", testAssertEqualArraySlices),
("testAssertEqualContiguousArrays", testAssertEqualContiguousArrays),
("testAssertEqualArrays", testAssertEqualArrays),
@briancroom
briancroom / ATS-Exception-localhost-Info.plist
Created November 16, 2015 18:34
An example iOS Info.plist disabling ATS for `localhost` connections. Look under the `NSAppTransportSecurity` key
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
@briancroom
briancroom / code-coverage.sh
Last active December 9, 2016 08:34
A pair of scripts to help with basic parsing of LLVM code-coverage output data, as produced by Xcode 7. The `cov-exclusions.txt` file can be used to exclude files and globs from the output
SCHEME=MyApp
PRODUCT_NAME=${SCHEME}
WORKSPACE=${SCHEME}.xcworkspace
SOURCE_ROOT=./
###
ABSOLUTE_SOURCE_ROOT=$(cd $SOURCE_ROOT; pwd)
BUILD_SETTINGS=`xcodebuild -workspace ${WORKSPACE} -scheme ${SCHEME} -sdk iphonesimulator -showBuildSettings`
# Project Temp Root ends up with /Build/Intermediates/
@briancroom
briancroom / ObjectiveC-Generics-Compatibility.h
Last active August 29, 2015 14:25
If you want to begin taking advantage of Xcode 7's generics for Objective-C but need to maintain backwards compatibility, try using something like this.
#if __has_feature(objc_generics)
#define BC_GENERIC(GENERIC_TYPE) <GENERIC_TYPE>
#define BC_GENERIC_TYPE(GENERIC_TYPE) GENERIC_TYPE
#else
#define BC_GENERIC(GENERIC_TYPE)
#define BC_GENERIC_TYPE(GENERIC_TYPE) id
#endif
@briancroom
briancroom / gist:b8a50eed4cff2cbd4abd
Last active August 29, 2015 14:23
Swift Error Assertions
/**
Response to: http://owensd.io/2015/06/22/catching-errors-for-testing-or-enums-suck.html
After seeing the new features introduced in Xcode 7 beta 2, it seemed that it should be
possible to take David's 4th option one step further. This allows writing assertions
that look exactly as David wishes. The only requirement is that any types used as
associated values on an error enum have to adopt the `DefaultConstructible` protocol
to allow for an instance of the enum case to be created.
**/