Skip to content

Repository files navigation

CI Platform Release License

BEFoundation

BEFoundation is an Objective-C framework that extends Apple's Foundation with utilities for notifications, runtime manipulation, number and data handling, image processing, data structures, file and path monitoring, security-scoped bookmarks, caching, and more. It is cross-platform (macOS and iOS) and ships as a Universal binary (arm64 + x86_64).


📖 Documentation

For full documentation, see the BEFoundation Documentation or the Documentation Index.


📦 Installation

Swift Package Manager

.package(url: "https://github.com/belisoful/BEFoundation.git", from: "1.1.0")

or add it in Xcode via File ▸ Add Package Dependencies….

CocoaPods

pod 'BEFoundation'

Binary

Download an artifact below and drop it into your target.


📥 Framework Library Downloads

The .xcframework is the recommended download: it carries macOS and iOS (device + simulator) in one binary, so a single artifact drops into any target. The plain .framework builds are macOS-only.


🔧 Features

📣 Notifications

  • mutableUserInfo for NSNotification
  • NSPriorityNotification: Notifications with explicit priority
  • NSPriorityNotificationCenter: Dispatches notifications in priority order linked to NSNotificationCenter

🔤 Character Sets

🖥️ Cross-Platform UI (iOS & macOS)

  • BEPlatformTypes: compile-time aliases — BEColor, BEImage, BEFont, BEView — that resolve to the right AppKit/UIKit class per platform, so the same source builds on both
  • BEColor+BExtension: hex-string colors (#RGB/#RGBA/#RRGGBB/#RRGGBBAA) and appearance-aware dynamic colors
  • BEColor+BEWebColor: the 141 CSS/SVG color keywords as constants, web-prefixed properties, and name lookups
  • BEView+BExtension: Auto Layout helpers — pin to superview/view, center, and size constraints
  • BEImage+BExtension: CGImage/CIImage round-trips, PNG/JPEG export, pixel size, and aspect-aware resize (fit/fill)
  • BEDotView: a status-indicator dot view (3D radial-gradient or flat), a port of Prado's TDot
  • NSPasteboard+BExtension (macOS): one-call typed read/write for strings, URLs, and images

🎞️ Image & Metal Helpers

  • BEMetalHelper: Metal helper utilities for converting MTLTextures to a BEImage (NSImage/UIImage), and grey data to XRGB
  • CIImage+BExtension: overlay images with alpha, render text

🧠 Runtime & Object Management

  • BEMutable: Mutable and Collection classes have their own protocols for distinction
  • NSObject+DynamicMethods: Runtime extensions to add selectors implemented by blocks to specific objects and classes
  • Runtime extensions to add protocols implemented by objects or classes to specific objects and classes
  • NSObject+Macroable: Laravel-inspired macro system for attaching block-based methods to classes and individual instances at runtime, built on top of NSObject+DynamicMethods
  • BEObjectRegistry: Global object registry with weak references to track object lifetimes
  • BESingleton: Singleton pattern macro

📚 Data Structures

  • BEStackExtensions: Array-based Stack and Queue (pushObject:, popObject, shift)
  • BEPriorityExtensions: Priority ordering extensions for NSArray and NSOrderedSet
  • FxTime: Immutable object to encapsulate CMTime and methods; FxMutableTime adds read-write components and in-place arithmetic

📡 File & Path Monitoring

  • BEPathWatcher: Path watcher class to observe file system changes

💾 Networking, Data & Storage

  • NSURL+Data: create and read data:-scheme URLs
  • BEWebData: read a resource through one interface, whether it is a data: URL, an http(s) download, or a local file
  • NSData+URLDownload: download remote data in memory or to a temporary file
  • BEFileCache: a two-tier cache — an NSCache memory tier over a durable on-disk tier indexed for O(1) cold start — with count/cost limits, NSDiscardableContent awareness, crash-safe reconciliation at launch, a score-driven eviction policy (last-access recency, retentionCost, and an evictionBalance dial between age and value density), and caller-defined entry file naming (fileNameBlock)
  • BESecurityScopedURLManager: create, resolve, and manage the access lifecycle of security-scoped bookmarks

🧮 Encoding, Numbers, and Dates

🧪 Predicate Logic

  • BEPredicateRule: Evaluation system that can accept, reject, or remain neutral based on predicate evaluation

🧩 Foundation Extensions

  • NSObject+DynamicMethods: Dynamic protocol conformance implemented by objects and classes
  • NSObject: Block-based selectors for instances and classes
  • Extensions for:
    • NSDictionary+BExtension: numeric subscripts, object conversion, mapping, swapping, adding, and merging
    • NSMutableDictionary: numeric subscripts, filtering, swap, and recursive and nonrecursive adding and merging
    • NSArray+BExtension: mapping, and conversion
    • NSMutableArray: removeFirstElement, insertElementsOfArray:atIndex:, and filtering
    • NSSet+BExtension: conversion, and mapping
    • NSMutableSet: filtering
    • NSOrderedSet+BExtension: conversion, and mapping
    • NSMutableOrderedSet: conversion, removeFirstElement/removeLastElement, and filtering
    • NSString+BExtension: stringValue (to align with NSNumber and other plist data types), is itself
    • NSMutableString: deleteAtIndex

🧪 Unit Testing

BEFoundation ships unit tests for all major components, using XCTest, covering behavior, edge cases, runtime behaviors, and error conditions. The suite runs parallelized across test workers. Continuous integration runs it on macOS (arm64), the macOS x86_64 slice, and the iOS Simulator, plus an AddressSanitizer pass and a DocC catalog build. In v1.1, coverage was extended to NSObject+Macroable (65 tests covering BEMacroMeta, class macros, object macros, invocation, isolation, and subclass inheritance).


📦 Integration

Framework Integration

  1. Download the BEFoundation.framework ZIP file for your project.
  2. Unzip the file.
  3. Include the BEFoundation.framework in your Project Target under the General Tab and "Framework and Libraries" section.
  4. Under the "Embed" dropdown select "Embed & Sign" or "Embed Without Signing".
  5. Import the Headers you'd like to use.

Manual Integration

  1. Clone or download this repository.
  2. Add the BEFoundation source folder to your Xcode project.
  3. Link against required frameworks: Foundation, CoreImage, Metal, etc.
  4. Ensure ARC is enabled (where applicable).

✍️ About the Author

Author

BEFoundation was initially conceived and engineered by belisoful@icloud.com to resolve the lack of [NSString stringValue] and implementing a selector for an object (and instances) with a block. These requirements came about in working with Apple's FxPlug API in developing an advanced framework around it. The FxPlug buttons require an object method be implemented per button which is not directly possible in Objective C. The buttons need to be parameterized for an FxPlug framework.

Other projects


Change Log

New in 1.1

Cross-Platform (iOS & macOS)

  • The framework now builds and is unit-tested on both iOS and macOS. BEPlatformTypes provides compile-time aliases — BEColor, BEImage, BEFont, BEView — that resolve to the right AppKit/UIKit class per platform.
  • Distributed as a multi-platform BEFoundation.xcframework (macOS, iOS device, iOS simulator) alongside the macOS-only .framework builds.
  • Installable through Swift Package Manager and CocoaPods. Public headers moved to Sources/BEFoundation/include/BEFoundation/, so #import <BEFoundation/Foo.h> resolves the same way for SwiftPM, CocoaPods, and the built framework.
  • BEColor+BEWebColor: the 141 CSS/SVG color keywords as BEWebColorName… constants and web-prefixed class properties, with case-insensitive name lookup and exact reverse lookup.
  • BEDotView: a cross-platform status-indicator dot (3D or flat), a Core Graphics port of Prado's TDot.
  • BEColor+BExtension: hex-string colors and appearance-aware dynamic colors.
  • BEView+BExtension: Auto Layout convenience constraints (pin, center, size).
  • BEImage+BExtension: CGImage/CIImage round-trips, PNG/JPEG export, pixel size, and aspect-aware resizing.
  • Behavior change: the BEImage+BExtension round-trip and data members are renamed to representation-style names — CGImageRepresentation, CIImageRepresentation, imageFromCGImage:, imageFromCIImage:, pngRepresentation, jpegRepresentationWithCompressionQuality:. Apple frameworks attach same-named category methods to NSImage at runtime (PencilKit adds a private +[NSImage imageWithCGImage:] and -CGImage), and which duplicate wins is undefined, so the 1.0 UIImage-parity spellings were unsafe. pixelSize and the resizedTo… members keep their names. The round-trip members are also available on iOS now, and the factories return nil for NULL/nil input on both platforms.
  • NSPasteboard+BExtension (macOS): typed read/write for strings, URLs, and images.

Foundation & Networking

  • NSNotification+ExtraProperties adds tag and identifier if the notification object has such properties or are set in the NSNotification
  • NSString (CharacterCounter) category for counting characters of a NSString.
  • NSURL+Data: categories for creating and reading "data" scheme NSURL.
  • BEWebData: for decoding a "data" scheme within NSURL, download "http/s" files, or read file system files.
  • NSData+URLDownload: for easy download of internet data via in-memory or temporary file.
  • BEFileCache: persistent two-tier (memory + disk) caching with count/cost limits, crash-safe reconciliation at launch, a configurable score-driven eviction policy (retentionCost + evictionBalance), and caller-defined entry file naming (fileNameBlock).
  • BESecurityScopedURLManager: security-scoped bookmark lifecycle management.
  • NSDateFormatterRFC2822: fixed-format RFC 2822 (Internet Message Format) date formatter for email-style dates.
  • NSObject+Macroable: Macro system for attaching block-based methods to a class (available on all instances) or to a specific object instance at runtime, built on NSObject+DynamicMethods.
  • FxTime is now immutable and thread-safe. The new FxMutableTime subclass carries the read-write components and in-place arithmetic; code that mutated an FxTime must now use FxMutableTime. -copy returns an immutable FxTime; -mutableCopy returns an FxMutableTime.
  • Behavior change: FxTime -compare:/-compareTime: now follow the Cocoa NSComparisonResult convention. The result sign is inverted versus 1.0; code that compensated for the old inversion must drop the workaround.
  • Behavior change: NSCoder+AtIndex.h no longer imports <simd/simd.h> (it was unused). Clients that relied on the transitive include through the umbrella header must import <simd/simd.h> themselves.

Behavior change: category methods renamed off Apple's private selectors

Apple attaches private categories to Foundation classes at runtime, and when a BEFoundation category defined the same selector the runtime picked a winner by image load order. That surfaced as an intermittent test failure rather than a build error, and it is the cause of the flaky failures seen through 1.0. Every colliding selector is renamed; the behavior is unchanged.

1.0 1.1 Collided with
-[NSMutableArray push:], -pop -pushObject:, -popObject OSAnalytics (its push: returns nil, breaking chaining)
-[NSMutableOrderedSet push:], -pop -pushObject:, -popObject — (renamed with the array pair for symmetry)
-removeFirstObject, -removeLastObject -removeFirstElement, -removeLastElement CoreFoundation
-[NSMutableArray insertObjects:atIndex:] -insertElementsOfArray:atIndex: ScreenReaderCore
setSet:, setOrderedSet:, setArray: setters be_setSet:, be_setOrderedSet:, be_setArray: CoreFoundation
isMutable (class and instance) hasMutability Foundation's private per-instance predicate on every NSCharacterSet

The set, orderedSet, and array properties keep their names — only the setter selectors changed, so dot syntax (array.set = value) is unaffected. Scripts/check-category-collisions.sh now fails the build if any category selector reappears on an Apple class; it runs in CI.

Behavior change: queued priority-notification observers

An observer registered with an NSOperationQueue now receives a plain NSPriorityNotification it may retain indefinitely. Previously it received a pooled object that was recycled the moment the handler returned, so a retained notification's name, object, and userInfo went nil and were later overwritten by an unrelated post. NSPooledPriorityNotification is removed; it was also measurably slower than plain allocation under concurrent posting.

AppKit

  • BEPathControl: an NSPathControl that displays paths relative to a sub-directory.
  • BETabView: a drop-in NSTabView replacement that supports hidden tabs.
  • BEWindowController: a drop-in NSWindowController replacement with parent/child window-controller relationships and a windowDidLoad notification.
  • BEWindowControllerManager: an application singleton that tracks window controllers and closes children when a parent closes.

About

An advanced MacOS/iOS Foundation extension library

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages