NTP library for Swift and Objective-C. Get the true time impervious to device clock changes.

Overview

TrueTime for Swift Carthage compatible Travis CI

TrueTime

Make sure to check out our counterpart too: TrueTime, an NTP library for Android.

NTP client for Swift. Calculate the time "now" impervious to manual changes to device clock time.

In certain applications it becomes important to get the real or "true" date and time. On most devices, if the clock has been changed manually, then an NSDate() instance gives you a time impacted by local settings.

Users may do this for a variety of reasons, like being in different timezones, trying to be punctual and setting their clocks 5 – 10 minutes early, etc. Your application or service may want a date that is unaffected by these changes and reliable as a source of truth. TrueTime gives you that.

How is TrueTime calculated?

It's pretty simple actually. We make a request to an NTP server that gives us the actual time. We then establish the delta between device uptime and uptime at the time of the network response. Each time now() is requested subsequently, we account for that offset and return a corrected NSDate value.

Usage

Swift

import TrueTime

// At an opportune time (e.g. app start):
let client = TrueTimeClient.sharedInstance
client.start()

// You can now use this instead of NSDate():
let now = client.referenceTime?.now()

// To block waiting for fetch, use the following:
client.fetchIfNeeded { result in
    switch result {
        case let .success(referenceTime):
            let now = referenceTime.now()
        case let .failure(error):
            print("Error! \(error)")
    }
}

Objective-C

@import TrueTime;

// At an opportune time (e.g. app start):
TrueTimeClient *client = [TrueTimeClient sharedInstance];
[client startWithPool:@[@"time.apple.com"] port:123];

// You can now use this instead of [NSDate date]:
NSDate *now = [[client referenceTime] now];

// To block waiting for fetch, use the following:
[client fetchIfNeededWithSuccess:^(NTPReferenceTime *referenceTime) {
    NSLog(@"True time: %@", [referenceTime now]);
} failure:^(NSError *error) {
    NSLog(@"Error! %@", error);
}];

Notifications

You can also listen to the TrueTimeUpdated notification to detect when a reference time has been fetched:

let client = TrueTimeClient.sharedInstance
let _ = NSNotificationCenter.default.addObserver(forName: .TrueTimeUpdated, object: client) { _ in
    // Now guaranteed to be non-nil.
    print("Got time: \(client.referenceTime?.now()")
}

Installation Options

TrueTime is currently compatible with iOS 8 and up, macOS 10.10 and tvOS 9.

Carthage (recommended)

Add this to your Cartfile:

github "instacart/TrueTime.swift"

Then run:

$ carthage update

CocoaPods

Add this to your Podfile:

pod 'TrueTime'

Then run:

$ pod install

Manually

  • Run git submodule update --init.
  • Run carthage bootstrap.
  • Run brew install swiftlint if not already installed.
  • Open TrueTime.xcodeproj, choose TrueTimeExample and hit run. This will build everything and run the sample app.

Manually using git submodules

  • Add TrueTime as a submodule:
$ git submodule add https://github.com/instacart/TrueTime.swift.git
  • Follow the above instructions for bootstrapping manually.
  • Drag TrueTime.xcodeproj into the Project Navigator.
  • Go to Project > Targets > Build Phases > Link Binary With Libraries, click + and select the TrueTime target.

Notes / Tips

  • Since NSDates are just Unix timestamps, it's safe to hold onto values returned by ReferenceTime.now() or persist them to disk without having to adjust them later.
  • Reachability events are automatically accounted for to pause/start requests.
  • UDP requests are executed in parallel, with a default limit of 5 parallel calls. If one fails, we'll retry up to 3 times by default.
  • TrueTime is also available for Android.

Contributing

This project adheres to the Contributor Covenant code of conduct. By participating (including but not limited to; reporting issues, commenting on issues and contributing code) you are expected to uphold this code. Please report unacceptable behavior to [email protected].

Setup

Development depends on some Carthage dependencies and a xcconfig git submodule.

Clone the repo and setup dependencies with:

git submodule update --init --recursive
carthage bootstrap

License

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Learn more

NTP

Comments
  • Fix manual installation instructions

    Fix manual installation instructions

    After many hours and the help of some friends I discovered the missing steps necessary to compile this library. Hopefully adding these can help save future devs some time and clarify how to use the library alongside Cocoapods :)

    opened by warpling 8
  • Swift 4.1 compile errors

    Swift 4.1 compile errors

    Tried to use the latest version with cocoapods and this what I get: NTPExtensions.swift:50:22: 'toIntMax()' is unavailable NTPExtensions.swift:55:25: 'toIntMax()' is unavailable NTPExtensions.swift:67:23: 'toIntMax()' is unavailable TrueTime.swift:54:50: Let 'defaultTimeout' is private and cannot be referenced from a default argument value TrueTime.swift:55:44: Let 'defaultMaxRetries' is private and cannot be referenced from a default argument value TrueTime.swift:56:48: Let 'defaultMaxConnections' is private and cannot be referenced from a default argument value TrueTime.swift:57:44: Let 'defaultMaxServers' is private and cannot be referenced from a default argument value TrueTime.swift:58:49: Let 'defaultNumberOfSamples' is private and cannot be referenced from a default argument value TrueTime.swift:59:55: Let 'defaultPollInterval' is private and cannot be referenced from a default argument value

    Any ideas what's wrong?

    opened by YuriiTrach 7
  • [Xcode 9 - 32bit devices] fatal error: Not enough bits to represent a signed value

    [Xcode 9 - 32bit devices] fatal error: Not enough bits to represent a signed value

    this line crashes:

    self.init(whole: ValueType(UInt64(time.tv_sec + secondsFrom1900To1970)),

    in

    extension NTPTimevalConvertible {
        init(timeSince1970 time: timeval) {
            precondition(time.tv_sec >= 0 && time.tv_usec >= 0, "Time must be positive \(time)")
            self.init(whole: ValueType(UInt64(time.tv_sec + secondsFrom1900To1970)),
                      fraction: ValueType(UInt64(time.tv_usec) * UInt64(1<<32 / USEC_PER_SEC)))
        }
    
        ...
    }
    

    note: private let secondsFrom1900To1970: Int64 = ((365 * 70) + 17) * 24 * 60 * 60

    bug 
    opened by tedgonzalez 5
  • Is TrueTime suppose to update the ReferenceTime automatically about every 8 minutes?

    Is TrueTime suppose to update the ReferenceTime automatically about every 8 minutes?

    In a previous post you had mentioned that TrueTime should be addressing the issue of drifting. From my understanding about every 8 minutes the code automatically invalidates the old NTP time reference and fetches a new NTP time reference. In the tests I have ran I still get the original time reference when I print referenceTime. The only time the NTP time is updated is when network becomes unreachable then becomes reachable again. Other than implementing the base code found in your readme file: let client = TrueTimeClient.sharedInstance client.start()

    Then calling: let now = client.referenceTime?.now()

    Is there something else I have missed that should start and execute the 8 minute timer to force a new NTP update?

    opened by dsrspro 5
  • Notification never being called.

    Notification never being called.

    Hi there.

    I am trying to get notified when TrueTime updates its reference date. I am using following code:

            let trueTime = TrueTimeClient.sharedInstance
            trueTime.start()
            _ = NotificationCenter.default.addObserver(forName: .TrueTimeUpdated,
                                                       object: trueTime,
                                                       queue: OperationQueue.main,
                                                       using: { _ in
                                                        print("requested")
            })
    

    As result print("requested") never being called. Also I sure that referenced date was updated by calling trueTime.referenceTime?.now() and getting non-nil value.

    Am I doing something wrong or there is some bug around this feature?

    I am on version 4.1.0 (the latest version available via CocoaPods)

    opened by Visput 5
  • Can't build with Carthage on M1 Mac

    Can't build with Carthage on M1 Mac

    Hi there. Is this project still supported? I'm trying to update an old project of mine that uses this, and trying to build this with Carthage on macOS/Xcode 13 results in:

    $ carthage update --platform ios
    *** Cloning TrueTime.swift
    *** Checking out TrueTime.swift at "5.1.0"
    *** xcodebuild output can be found in /var/folders/16/jfb809_s2fz01ql7k494f6pc0000gn/T/carthage-xcodebuild.OaZvQU.log
    *** Building scheme "TrueTime-iOS" in TrueTime.xcodeproj
    A shell task (/usr/bin/xcrun lipo -create /PathToBuild/Intermediates.noindex/ArchiveIntermediates/TrueTime-iOS/IntermediateBuildFilesPath/UninstalledProducts/iphoneos/TrueTime.framework/TrueTime /PathToBuild/Products/Release-iphonesimulator/TrueTime.framework/TrueTime -output /Users/rmann/Projects/ZOld/LZRepo/SatTrack/MissonClock/branches/v1.1/MissionClock/Carthage/Build/iOS/TrueTime.framework/TrueTime) failed with exit code 1:
    fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: /PathToBuild/Intermediates.noindex/ArchiveIntermediates/TrueTime-iOS/IntermediateBuildFilesPath/UninstalledProducts/iphoneos/TrueTime.framework/TrueTime and /PathToBuild/Products/Release-iphonesimulator/TrueTime.framework/TrueTime have the same architectures (arm64) and can't be in the same fat output file
    
    Building universal frameworks with common architectures is not possible. The device and simulator slices for "TrueTime" both build for: arm64
    Rebuild with --use-xcframeworks to create an xcframework bundle instead.
    

    I also don't see any support for the Swift Package Manager.

    opened by JetForMe 4
  • Fix race condition crash by removing unnecessary retain/release

    Fix race condition crash by removing unnecessary retain/release

    What did you change and why?

    • Remove unnecessary retain/release logic in NTPConnection that was crashing after being released too many times in some race conditions.
    • Retaining here is not necessary. It was originally implemented here as part of fixing an issue where HostResolver didn’t retain itself for resolving connections when the initial attempt timed out. From what I can tell, it was just added here to be safe. @msanders if you’re still active and somehow remember, feel free to correct me if I’m wrong!

    Potential risks introduced?

    • If I'm missing something, or if NTPConnection is used elsewhere in your app, since the socket isn't retaining it it's possible that a socket callback could cause a crash.
    • If query(addresses: [SocketAddress], host: String) is called when connections is not cleared, that could cause the same crash as above. I cannot find a case where this happens, and it's in a private extension.

    What tests were performed (include steps)?

    • See steps to reproduce below. I've performed those, and additionally I will deploy my own fork in my codebase and will report back the stability results.

    Checklist

    • [ ] Unit/UI tests have been written (if necessary)
    • [x] Manually tested

    Additional Information

    Why don’t we need to increment the retain count of NTPConnection for the socket’s callback?

    NTPConnections are used by NTPClient, and NTPClient is used by the singleton TrueTimeClient. TrueTimeClient maintains a strong reference to NTPClient. NTPClient maintains a strong reference to [NTPConnection]. When removing the connections, each connection is synchronously closed (which removes itself from the socket callback), then the array is cleared. At no point is it necessary to increment the retain count from the sockets as long we’re guaranteed that close will be called before release our strong reference, which it is.

    History of this bug

    How do you reproduce the new crash?

    • Create a sample project where you start the TrueTimeClient instance and call fetchIfNeeded
    • Edit the timeout of the NTPConnection objects to be really small (ex: 0.0001) NTPConnection.swift line 28. If you felt more ambitious, you could fire up the Network Link Conditioner and set it to be 8 seconds or more.
    • Lock the thread for the length of time it’ll take the network response to come back in NTPConnection complete after the release() is called. I just added Thread.sleep(forTimeInterval: 0.5) on line 207.
    • Run the code. It will crash, assuming the timeoutError is hit.
    • Sample NTPConnection.swift if you want to try for yourself.

    Okay but why does this happen?

    There are actually two stack traces: one in NTPClient, and one in NTPConnection. The latter is the more prevalent one by about 10x. We’ll start with that one. Note: this is probably pretty hard to follow, and I'm not 100% sure about the correctness. All of the logic below is moot by this PR though, and these race conditions no longer exist.

    Assume that we are running on a slow internet where the roundtrip time of the requests is about 8 seconds, conveniently the same as the default timeout :P

    • NTPConnections are created.
    • When they are started, the reference count of each is incremented by 1 with passRetained. The socket completion callback (dataCallback) is then enqueued to be executed on the main thread.
    • The timeout of 8 seconds hits (timeoutError), and complete(.failure(error)) is called. This timer callback happens on the lock queue (instacart npt connection queue).
    • complete(), calls close(), but notice in that implementation of close all of the code is executed asynchronously on the lockQueue. Calling lockQueue.async if you’re already on lockQueue will append that code to the end of the current runloop. This is important because it means that the socket callback isn't actually removed yet.
    • Back in complete(), we’re specifically a timeout error, so onComplete is called on the callbackQueue (instacart ntp client queue, this is a different thread).
    • Finally, release() is called if callbackPending is true (which it is here).
    • While the above is happening, the NTPConnection completion handler is still active, because it’s been appended to the end of the current run loop.
    • The socket success completion comes in at some point during this time and is run on the main thread (dataCallback). release() is then called again. Not good. We’ve now accidentally released this twice.
    • The next connection in the queue will eventually then call onComplete.
    • Our ref count for the original connection is one less than what it’s supposed to be. Go look at the definition for onComplete on line 35. Since there’s both the reference to connections in NTPClient and the connection here, the ref count for the NTPConnection is still one. We can call progress(connection, result) without any issue.
    • However, once throttleConnections is called, and the above extra reference in the closure is released, $0.canRetry now causes a crash because the reference count is 0.

    I’m less sure about the NTPClient crash. I think it might be the same as above, except in that race condition the NTPConnection has managed to be released twice (maybe if it was also cancelled?) and the reference count is 0 for the progress callback. We’d expect it to crash then on line 186 of NTPClient.

    tl;dr: we have several different threads with several connections happening at the same time that enqueue differing things, with logic that retains, then releases at different times depending on state (and potentially in different threads). This is both hard to follow and leads to potential race conditions. I do not see a reason for an extra retain and release here at all, since connections are retained by NTPClient and only released after synchronously closing each connection and removing the callback.

    opened by miketsprague 4
  • App crashing due to TrueTime connection

    App crashing due to TrueTime connection

    Hi, I'm recently starting using your library. Now this kind of crash logs are coming from Crashlytics:

    Crashed: com.instacart.ntp.connection 0 TrueTime 0x100a30e08 TFFC8TrueTime13NTPConnectionP33_2A79C9048389EB5D5F57E571231D0EE311requestTimeFT_T_U_FT_T + 34 1 libswiftFoundation.dylib 0x10122ea08 _TFV10Foundation4Data15withUnsafeBytesu0_rfzFzGSPq__xx + 176 2 TrueTime 0x100a34c5c TTSf4g_g_n___TFFC8TrueTime13NTPConnectionP33_2A79C9048389EB5D5F57E571231D0EE314handleResponseFV10Foundation4DataT_U_FT_T + 228 3 TrueTime 0x100a3473c TPA__TFFC8TrueTime13NTPConnectionP33_2A79C9048389EB5D5F57E571231D0EE314handleResponseFV10Foundation4DataT_U_FT_T + 80 4 libdispatch.dylib 0x1878661fc _dispatch_call_block_and_release + 24 5 libdispatch.dylib 0x1878661bc _dispatch_client_callout + 16 6 libdispatch.dylib 0x1878743dc _dispatch_queue_serial_drain + 928 7 libdispatch.dylib 0x1878699a4 _dispatch_queue_invoke + 652 8 libdispatch.dylib 0x1878748d8 _dispatch_queue_override_invoke + 360 9 libdispatch.dylib 0x18787634c _dispatch_root_queue_drain + 572 10 libdispatch.dylib 0x1878760ac _dispatch_worker_thread3 + 124 11 libsystem_pthread.dylib 0x187a6f2a0 _pthread_wqthread + 1288 12 libsystem_pthread.dylib 0x187a6ed8c start_wqthread + 4

    App tries to fetch NTP time from this URLs: let hostUrls: [URL] = [URL(string: "pool.ntp.org")!, URL(string: "time.apple.com")!]

    I couldn't find out the reason of the crash. Could you help me, please?

    bug 
    opened by NurLight19 4
  • [minor] Fixing some warnings

    [minor] Fixing some warnings

    What did you change and why?

    Fixing some Xcode warnings.

    Potential risks introduced?

    None

    What tests were performed (include steps)?

    Compile and tests.

    Checklist

    • [ ] Unit/UI tests have been written (if necessary)
    • [x] Manually tested
    opened by dhavalshreyas 3
  • Update dependency versions

    Update dependency versions

    This module currently declares a dependency on Result version 4.0 in the podspec. However, this is out-of-sync with the Cartfile, which doesn't pin a specific version. Result has since been updated to 4.1, and Result 4.0 doesn't compile with Xcode 10.2 and Swift 5. Other modules can't depend on this project via CocoaPods and use Swift 5 until the podspec is updated to either not depend on a specific version, or to specifically depend on Result 4.1. Likewise, some dependencies declared in Cartfile.private have older versions pinned in Cartfile.resolved, causing them to fail to compile in Xcode 10.2

    opened by raysarebest 3
  • When using carthage, the generated framework has an external dependency: Sources/CTrueTime/*.h

    When using carthage, the generated framework has an external dependency: Sources/CTrueTime/*.h

    I added TrueTime to my project, using Carthage.

    I did not add the folder "Checkouts" to source control.

    Steps to reproduce:

    • Remove the "Checkouts" folder.
    • Build your project.

    Expected:

    • My project builds correctly, using the TrueTime carthage generated framework.

    Reality:

    • Xcode drops the error: Missing required module 'CTrueTime'.

    Troubleshooting: if the file Sources/CTrueTime/*.h stays in the "Checkouts" folder, everything is fine. If it is not, the CTrueTime module can not build.

    opened by acecilia 3
  • Kotlin Multiplatform CocoaPods dependency support

    Kotlin Multiplatform CocoaPods dependency support

    What did you change and why?

    @import declaration breaks using TrueTime as CocoaPods dependency in Kotlin Multiplatform because modules are disabled. #import declaration fixes this issue

    Potential risks introduced?

    Nothing risks see

    What tests were performed (include steps)?

    Work on real iOS app inside Kotlin Multiplatform library

    Checklist

    • [ ] Unit/UI tests have been written (if necessary)
    • [ ] Manually tested
    opened by Pschsch 0
  • Xcode 14.0.1 (M1 Mac) carthage update --platform ios --use-xcframeworks

    Xcode 14.0.1 (M1 Mac) carthage update --platform ios --use-xcframeworks" not working

    tried but below output not downloaded anything

    "carthage update --platform ios --use-xcframeworks"

    *** Downloading binary-only framework GoogleMaps at "https://dl.google.com/geosdk/GoogleMaps.json" *** xcodebuild output can be found in /var/folders/k6/ms2_zrl956z_8vvmj6bw13ph0000gp/T/carthage-xcodebuild.GLoOY1.log *** Downloading binary-only framework GoogleMaps at "https://dl.google.com/geosdk/GoogleMaps.json"

    opened by rajeshm20 0
  • Crash on retain cycle

    Crash on retain cycle

    Using 5.0.3 version

    Thread 27 name:
    Thread 27 Crashed:
    0   libobjc.A.dylib               	0x00000001998669c8 objc_retain + 8 (objc-os.h:223)
    1   libswiftCore.dylib            	0x000000018595d6fc swift_bridgeObjectRetain + 48 (SwiftObject.mm:589)
    2   TrueTime                      	0x0000000103c7a088 initializeWithCopy for FrozenNetworkTime + 164 (<compiler-generated>:0)
    3   TrueTime                      	0x0000000103c6fe2c outlined init with copy of FrozenNetworkTime + 52 (<compiler-generated>:0)
    4   TrueTime                      	0x0000000103c775cc min + 52 (<compiler-generated>:0)
    5   TrueTime                      	0x0000000103c775cc map + 216 (NTPResponse.swift:42)
    6   TrueTime                      	0x0000000103c775cc bestTime(fromResponses:) + 660 (NTPResponse.swift:41)
    7   TrueTime                      	0x0000000103c6de10 closure #1 in NTPClient.query(addresses:host:) + 2112 (NTPClient.swift:198)
    8   TrueTime                      	0x0000000103c70638 closure #2 in static NTPConnection.query(addresses:config:logger:callbackQueue:progress:) + 36 (NTPConnection.swift:36)
    9   TrueTime                      	0x0000000103c73800 partial apply for closure #1 in NTPConnection.complete(_:) + 60 (NTPConnection.swift:196)
    10  TrueTime                      	0x0000000103c6b23c thunk for @escaping @callee_guaranteed () -> () + 28 (<compiler-generated>:0)
    11  libdispatch.dylib             	0x00000001807afe6c _dispatch_call_block_and_release + 32 (init.c:1517)
    12  libdispatch.dylib             	0x00000001807b1a30 _dispatch_client_callout + 20 (object.m:560)
    13  libdispatch.dylib             	0x00000001807b9124 _dispatch_lane_serial_drain + 668 (inline_internal.h:2622)
    14  libdispatch.dylib             	0x00000001807b9c80 _dispatch_lane_invoke + 392 (queue.c:3944)
    15  libdispatch.dylib             	0x00000001807c4500 _dispatch_workloop_worker_thread + 648 (queue.c:6732)
    16  libsystem_pthread.dylib       	0x00000001f12650bc _pthread_wqthread + 288 (pthread.c:2599)
    17  libsystem_pthread.dylib       	0x00000001f1264e5c start_wqthread + 8 (:-1)
    
    opened by Ankish 0
  • Connection Timed out Error

    Connection Timed out Error

    "Error! Error Domain=com.instacart.TrueTimeErrorDomain Code=2 "The connection timed out." UserInfo={NSLocalizedDescription=The connection timed out.}"

    Version : TrueTime (5.0.3)

    My code:

    let client = TrueTimeClient.sharedInstance
    client.start()
    let now = client.referenceTime?.now()
    client.fetchIfNeeded { result in
        switch result {
            case let .success(referenceTime):
                let now = referenceTime.now()
            case let .failure(error):
                print("Error! \(error)")
        }
    }
    

    It was working before. When i check this yesterday, I came with this error. Kindly check this

    opened by MohamedJaffer-24 0
  • Crashed: com.instacart.ntp.connection

    Crashed: com.instacart.ntp.connection

    Crashed: com.instacart.ntp.connection 0 libsystem_platform.dylib 0x1aa0 platform_memmove + 208 1 libswiftCore.dylib 0x2a981c swift_allocateGenericClassMetadata + 456 2 libswiftCore.dylib 0x2a981c swift_allocateGenericClassMetadata + 456 3 libswiftCore.dylib 0x2aa268 swift_getGenericMetadata + 1312 4 libswiftCore.dylib 0x226720 swift_stdlib_getDescription + 729236 5 libswiftCore.dylib 0x2bda7c swift_disableDynamicReplacementScope + 7848 6 libswiftCore.dylib 0x2bd250 swift_disableDynamicReplacementScope + 5756 7 libswiftCore.dylib 0x2bc888 swift_disableDynamicReplacementScope + 3252 8 libswiftCore.dylib 0x2bc0e8 swift_disableDynamicReplacementScope + 1300 9 libswiftCore.dylib 0x2bbea8 swift_disableDynamicReplacementScope + 724 10 libswiftCore.dylib 0x2bc55c swift_disableDynamicReplacementScope + 2440 11 libswiftCore.dylib 0x2ba8a8 swift_getTypeByMangledNameInEnvironment + 832 12 libswiftCore.dylib 0x2ba9ec swift_getTypeByMangledNameInContext + 208 13 TrueTime 0x6d24 __swift_instantiateConcreteTypeFromMangledName + 4323552548 (:4323552548) 14 TrueTime 0x15ae0 NTPResponse.isValidResponse.getter + 54 (NTPResponse.swift:54) 15 TrueTime 0x105dc closure #1 in NTPConnection.handleResponse(:) + 20 (NTPResponse.swift:20) 16 TrueTime 0x91a0 thunk for @escaping @callee_guaranteed () -> () + 4323561888 (:4323561888) 17 libdispatch.dylib 0x1aa0 _dispatch_call_block_and_release + 24 18 libdispatch.dylib 0x1a60 _dispatch_client_callout + 16 19 libdispatch.dylib 0xb9b4 _dispatch_queue_serial_drain$VARIANT$mp + 608 20 libdispatch.dylib 0xc2fc _dispatch_queue_invoke$VARIANT$mp + 336 21 libdispatch.dylib 0xccc8 _dispatch_root_queue_drain_deferred_wlh$VARIANT$mp + 340 22 libdispatch.dylib 0x15098 _dispatch_workloop_worker_thread$VARIANT$mp + 668 23 libsystem_pthread.dylib 0xe70 _pthread_wqthread + 860 24 libsystem_pthread.dylib 0xb08 start_wqthread + 4

    opened by gulshan-arya 3
Owner
Instacart
Same-day Grocery Delivery
Instacart
Elegant NTP date library in Swift

Kronos is an NTP client library written in Swift. It supports sub-seconds precision and provides a stable monotonic clock that won't be affected by ch

Mobile Native Foundation 575 Dec 23, 2022
Simple clock app for the different time zones.

DunyaSaatleri The clock app provide the user adding clocks of cities from different timezones. The times showed by analog clock. The added clocks can

Ozan Barış GÜNAYDIN 1 Nov 27, 2021
The goal is a simple iOS app that draws an analog clock of the current time

Qrono This is a work-in-progress. The goal is a simple iOS app that draws an analog clock of the current time (as well as displaying a digital readout

Justin Reusch 2 Jan 29, 2022
A "time ago", "time since", "relative date", or "fuzzy date" category for NSDate and iOS, Objective-C, Cocoa Touch, iPhone, iPad

Migration 2014.04.12 NSDate+TimeAgo has merged with DateTools. DateTools is the parent project and Matthew York is the project head. This project is n

Kevin Lawler 1.8k Dec 2, 2022
Population Clock is an iOS tool for learning about geography and demographics.

PopulationClock Population Clock is an iOS tool for learning about geography and demographics. Download app on iTunes The project uses the most recent

Netfilter 12 Feb 8, 2022
A clock for iOS based off of the famous fibonacci sequence

Fibonacc iClock Fibonacc iClock is a fibonacci clock implementation for iOS. This project is based off of Thiago Sá's implementation of Philippe Chrét

null 10 Dec 16, 2022
A minimal hexadecimal clock for the Apple TV.

Hex Color Clock A simple, minimal hexadecimal clock for the Apple TV. Download it on the App Store! Dependencies Fastlane is used to manage the build

Colin Drake 17 Jul 19, 2022
Get the current frequency of your Apple M1 GPU.

M1-gpufreq Get the current frequency of your Apple M1 GPU. What It Does and How It Works This project is designed to get the current frequency (or clo

BitesPotatoBacks 3 Nov 2, 2022
SwiftMoment - A time and calendar manipulation library for iOS 9+, macOS 10.11+, tvOS 9+, watchOS 2+ written in Swift 4.

SwiftMoment This framework is inspired by Moment.js. Its objectives are the following: Simplify the manipulation and readability of date and interval

Adrian Kosmaczewski 1.6k Dec 31, 2022
Timekeeper is an easy-to-use time measurement library written in Swift, with support for iOS, tvOS, watchOS and macOS.

Timekeeper is an easy-to-use time measurement library written in Swift, with support for iOS, tvOS, watchOS and macOS. Installation Timekee

Andreas Pfurtscheller 1 Oct 18, 2021
Building a better date/time library for Swift

Time Time is a Swift package that makes dealing with calendar values a natural and straight-forward process. Working with calendars can be extremely c

Dave DeLong 2k Dec 31, 2022
A TimeZonePicker UIViewController similar to the iOS Settings app. Search and select from a range of cities and countries to find your most suitable time zone.

TimeZonePicker A TimeZonePicker UIViewController similar to the iOS Settings app. Search and select from a range of cities and countries to find your

Gligor Kotushevski 125 Dec 13, 2022
A basic countdown app that allows the user to create, edit, and delete events. Each event contains a live countdown timer to a specified date and time.

Event Countdown App (iOS) Created by Lucas Ausberger About This Project Created: January 4, 2021 Last Updated: January 8, 2021 Current Verison: 1.1.1

Lucas Ausberger 1 Jan 8, 2022
Time is a Swift package that makes dealing with calendar values a natural and straight-forward process.

Time Time is a Swift package that makes dealing with calendar values a natural and straight-forward process. Working with calendars can be extremely c

Dave DeLong 2k Dec 31, 2022
SwiftDate 🐔 Toolkit to parse, validate, manipulate, compare and display dates, time & timezones in Swift.

Toolkit to parse, validate, manipulate, compare and display dates, time & timezones in Swift. What's This? SwiftDate is the definitive toolchain to ma

Daniele Margutti 7.2k Jan 4, 2023
Custom Time Picker ViewController with Selection of start and end times in Swift 🔶

LFTimePicker Custom Time Picker ViewController with Selection of start and end times in Swift ?? . Based on Adey Salyard's design @ Dribbble One to tw

Awesome Labs 65 Nov 11, 2022
Date and time manager for iOS/OSX written in Swift

Tempo was designed to work both in OSX and in iOS (7.0+). Work with the time or dates can be cumbersome, iOS development. Tempo allows you to deal easly with date and time. Basics manipulations are already implemented in Tempo.

Remi ROBERT 153 Jun 3, 2021
NVDate is an extension of NSDate class (Swift4), created to make date and time manipulation easier.

NVDate is an extension of NSDate class (Swift4), created to make date and time manipulation easier. NVDate is testable and robust, we wrote intensive test to make sure everything is safe.

Noval Agung Prayogo 177 Oct 5, 2022
Time Lines - Know when all your friends, colleagues, and family are

Time Lines Know when all your friends, colleagues, and family are. Time Lines is a practical app to know when all your friends, colleagues and family

Mathieu Dutour 50 Dec 14, 2022