The hassle-free way to add Segment analytics to your Swift app (iOS/tvOS/watchOS/macOS/Linux).

Overview

Analytics-Swift

The hassle-free way to add Segment analytics to your Swift app (iOS/tvOS/watchOS/macOS/Linux/iPadOS). Analytics helps you measure your users, product, and business. It unlocks insights into your app's funnel, core business metrics, and whether you have product-market fit.

How to get started

  1. Collect analytics data from your app(s).
  • The top 200 Segment companies collect data from 5+ source types (web, mobile, server, CRM, etc.).
  1. Send the data to analytics tools (for example, Google Analytics, Amplitude, Mixpanel).
  • Over 250+ Segment companies send data to eight categories of destinations such as analytics tools, warehouses, email marketing and remarketing systems, session recording, and more.
  1. Explore your data by creating metrics (for example, new signups, retention cohorts, and revenue generation).
  • The best Segment companies use retention cohorts to measure product market fit. Netflix has 70% paid retention after 12 months, 30% after 7 years.

Segment collects analytics data and allows you to send it to more than 250 apps (such as Google Analytics, Mixpanel, Optimizely, Facebook Ads, Slack, Sentry) just by flipping a switch. You only need one Segment code snippet, and you can turn integrations on and off at will, with no additional code. Sign up with Segment today.

Why?

  1. Power all your analytics apps with the same data. Instead of writing code to integrate all of your tools individually, send data to Segment, once.

  2. Install tracking for the last time. We're the last integration you'll ever need to write. You only need to instrument Segment once. Reduce all of your tracking code and advertising tags into a single set of API calls.

  3. Send data from anywhere. Send Segment data from any device, and we'll transform and send it on to any tool.

  4. Query your data in SQL. Slice, dice, and analyze your data in detail with Segment SQL. We'll transform and load your customer behavioral data directly from your apps into Amazon Redshift, Google BigQuery, or Postgres. Save weeks of engineering time by not having to invent your own data warehouse and ETL pipeline.

    For example, you can capture data on any app:

    struct TrackProperties: Codable {
        let price: Double
    }
    
    // ...
    
    analytics.track(name: "Order Completed", properties: TrackProperties(price: 99.84))

    Then, query the resulting data in SQL:

    select * from app.order_completed
    order by price desc

Supported Device Mode Destinations

Partner Package
Amplitude https://github.com/segment-integrations/analytics-swift-amplitude
AppsFlyer https://github.com/segment-integrations/analytics-swift-appsflyer
Facebook https://github.com/segment-integrations/analytics-swift-facebook-app-events
Firebase https://github.com/segment-integrations/analytics-swift-firebase
Mixpanel https://github.com/segment-integrations/analytics-swift-mixpanel

Documentation

You can find usage documentation at https://segment.com/docs/sources/mobile/swift-ios/.

Explore more via the example projects which showcase analytics instrumentation on different platforms/languages and usage of plugins. These projects contain sample plugins and destination plugins.

Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

Integrating with Segment

Interested in integrating your service with us? Check out our Partners page for more details.

Code of Conduct

Before contributing, please also see our code of conduct.

License

MIT License

Copyright (c) 2021 Segment

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Comments
  • [Segment ERROR - finish(file:):320] Unable to rename to temp warning/error

    [Segment ERROR - finish(file:):320] Unable to rename to temp warning/error

    Describe the bug A clear and concise description of what the bug is.

    Coming across a very weird debug message lately since the last update. The message appears around 20 secs post starting the app. The message says:

    [Segment ERROR - finish(file:):320] Unable to rename to temp: file:///Users/chetanmalhotra/Library/Developer/CoreSimulator/Devices/094C9BEE-0AB5-4345-AB1D-2CA907B66033/data/Containers/Data/Application/1688B1EE-1CCC-44B7-AA72-FB7A9A272B3E/Documents/segment/XVFH4DGT0ufXKfxlMQzNMQDosdD9eKLW/7-segment-events, Error: Error Domain=NSCocoaErrorDomain Code=4 "“7-segment-events” couldn’t be moved to “XVFH4DGT0ufXKfxlMQzNMQDosdD9eKLW” because either the former doesn’t exist, or the folder containing the latter doesn’t exist." UserInfo={NSSourceFilePathErrorKey=/Users/chetanmalhotra/Library/Developer/CoreSimulator/Devices/094C9BEE-0AB5-4345-AB1D-2CA907B66033/data/Containers/Data/Application/1688B1EE-1CCC-44B7-AA72-FB7A9A272B3E/Documents/segment/XVFH4DGT0ufXKfxlMQzNMQDosdD9eKLW/7-segment-events, NSUserStringVariant=( Move ), NSDestinationFilePath=/Users/chetanmalhotra/Library/Developer/CoreSimulator/Devices/094C9BEE-0AB5-4345-AB1D-2CA907B66033/data/Containers/Data/Application/1688B1EE-1CCC-44B7-AA72-FB7A9A272B3E/Documents/segment/XVFH4DGT0ufXKfxlMQzNMQDosdD9eKLW/7-segment-events.temp, NSFilePath=/Users/chetanmalhotra/Library/Developer/CoreSimulator/Devices/094C9BEE-0AB5-4345-AB1D-2CA907B66033/data/Containers/Data/Application/1688B1EE-1CCC-44B7-AA72-FB7A9A272B3E/Documents/segment/XVFH4DGT0ufXKfxlMQzNMQDosdD9eKLW/7-segment-events, NSUnderlyingError=0x600001e34e40 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}

    To Reproduce Steps to reproduce the behavior:

    1. Just run any project that uses identify() and track()
    2. Wait for ~20 secs
    3. See error

    Expected behavior There should be no warnings/werrors

    Screenshots If applicable, add screenshots to help explain your problem. Screenshot 2022-10-15 at 2 54 57 AM

    Platform (please complete the following information):

    • Library Version in use: 1.3.1
    • Platform being tested: Ios 15
    • Integrations in use: Firebase and Amplitude

    Additional context Kinda urgent. Pls help saviours

    triage 
    opened by malhotrachetan 15
  • Setting the apiHost in the configuration has no effect

    Setting the apiHost in the configuration has no effect

    Describe the bug Setting the apiHost in the configuration has no effect, events are still sent to api.segment.io/v1 regardless of the configuration values for apiHost.

    let configuration = Configuration(writeKey: writeKey)
       .trackApplicationLifecycleEvents(true)
       .apiHost("analytics-ingestion.kraftful.com")
       .flushInterval(10)
    
    Analytics.debugLogsEnabled = true
    analytics = Analytics(configuration: configuration)
    

    Steps for repro:

    I have created an example app with repro in a fork: https://github.com/kraftful/analytics-swift/tree/jgable/api-host-repro (specific commit is ce5331dfd60ca82870c27a1a38268d8e9d6c4577)

    • Clone the above branch/commit
    • Load the ExampleApp project in XCode (in the Examples/APIHostConfigurationRepro folder)
    • Put breakpoints in the HTTPClient file in Segment package where the batch uploads happen
    • Run the app on simulator (I have tried iPhone 12 Pro)
    • Login using creds: [email protected], test1234
    • Observe the value of uploadURL in the debugger when the batch is uploaded

    Expected:

    • Should be analytics-ingestion.kraftful.com since that is passed in the configuration in the SegmentAnalytlics.swift file

    Actual:

    • api.segment.io/v1 is used instead.

    Expected behavior

    Event batches should be sent to the configured apiHost.

    Screenshots

    Screen Shot 2022-09-20 at 9 41 05 AM

    Platform (please complete the following information):

    • Library Version in use: latest
    • Platform being tested: iOS (latest)
    • Integrations in use: none
    triage 
    opened by jgable 13
  • Integrations object not populated in SDK 1.2.0

    Integrations object not populated in SDK 1.2.0

    Describe the bug After migrating from analytics-ios v1.1.2 to v1.2.0, the integrations field did not contain any information. When this happens events are shown in the live debugger for a source but do not reach the source destinations.

    To Reproduce

    1. Add an integration like AppsFlyer to the segment client.
    2. On v1.1.2 trigger a track event and notice how the integrations object has a list of integrations.
    3. Update the SDK to v.1.2.0
    4. Trigger the same event. <--- Issue here
    5. The integrations object is empty

    Event v1.1.2

    {
      "context": {
        "library": {
          "name": "analytics-swift",
          "version": "1.1.2"
        },
        "locale": "en-US",
        "network": {
          "bluetooth": false,
          "cellular": true,
          "wifi": false
        }
      },
      "event": "Application Foregrounded",
      "integrations": {
        "AppsFlyer": false,
        "Segment.io": false
      },
      "receivedAt": "2022-04-11T23:21:53.134Z",
      "sentAt": "2022-04-11T23:21:52.706Z",
      "timestamp": "2022-04-11T23:21:44.226Z",
      "type": "track",
    }
    

    Event v1.2.0

    {
      "context": {
    		"library": {
          "name": "analytics-swift",
          "version": "1.2.0"
        },
        "locale": "en-US",
        "network": {
          "bluetooth": false,
          "cellular": true,
          "wifi": false
        }
    	},
      "event": "Application Foregrounded",
      "integrations": {},
      "receivedAt": "2022-04-11T23:20:33.204Z",
      "sentAt": "2022-04-11T23:20:32.773Z",
      "timestamp": "2022-04-11T23:20:32.281Z",
      "type": "track",
    }
    

    Expected behavior The integrations object should remain the same after upgrading from v1.1.X to v1.2.X

    Platform (please complete the following information):

    • Library Version in use: v.1.2.0
    • Platform being tested: iOS
    • Integrations in use: AppsFlyer

    Additional context This regression issue was introduced on v1.2.0.

    triage 
    opened by 215eight 11
  • Background task not cancelling when requested by system

    Background task not cancelling when requested by system

    Describe the bug As mentioned on our call, here's the warning that I'm regularly getting from the system.

    [BackgroundTask] Background task still not ended after expiration handlers were called: <_UIBackgroundTaskInfo: 0x2835fdd40>: taskID = 4, taskName = Called by <AppName>, from $s7Segment0A11DestinationC14UploadTaskInfoV3url4taskAE10Foundation3URLV_So016NSURLSessionDataD0CtcfC, creationTime = 1095354 (elapsed = 27). This app will likely be terminated by the system. Call UIApplication.endBackgroundTask(_:) to avoid this.

    I assume this means the app will have to launch cold each time this occurs.

    To Reproduce It seems to happen intermittently.

    I believe it usually occurs if I run a build on device, and that put aside the phone with the debugger still running. That message appeared almost 12 mins after the app was launched via a build and run in Xcode.

    As mentioned, my current network is a little flakey so it could be related to a low/no network situation, too.

    Expected behavior A clear and concise description of what you expected to happen.

    Screenshots If applicable, add screenshots to help explain your problem.

    Platform (please complete the following information):

    • Library Version in use: [e.g. 0.0.5]
    • Platform being tested: [e.g. iOS]
    • Integrations in use: [e.g. Firebase, Amplitude]

    Additional context Add any other context about the problem here.

    triage 
    opened by tcldr 10
  • Publicly Accessible UploadTask

    Publicly Accessible UploadTask

    Is your feature request related to a problem? Please describe. Currently, on iOS, the only way to run an upload as a well behaved background task seems to be to opt-in to lifecycle events. That's because the current implementation seems to rely on an internal UploadTaskInfo in the SegmentDestination which is only accessible to internal clients.

    AFAICT this means there is no simple way to create your own background task to upload any outstanding events.

    This would be especially useful in low/no network situations. Currently, even if opted-in to iOS lifecycle events, the background task that is created will fail if the network is unavailable.

    Describe the solution you'd like An ideal solution would be one with flexibility and adherence to platform recommendations.

    For example, on iOS it is possible to opt-in to 'background modes' one of which is called 'background processing'. This mode allows a developer to use he system's Background Task Scheduler to do additional processing at some point when the battery and network conditions are favourable. The system scheduler enforces adherence to platform recommendations (i.e cancelling when asked, and letting the system know when it's complete) by docking an app's time on the scheduler for non-compliance.

    With that in mind, I suggest a task API similar to the one for URLSession but with an additional callback for completion with some kind of TaskState to inform of success, cancellation or failure:

    struct SegmentUploadTask {
        func start(_ completion: @escaping (TaskState) -> Void)
        func cancel()
    }
    

    Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.

    Additional context Add any other context or screenshots about the feature request here.

    enhancement 
    opened by tcldr 8
  • Destination plugin calls `update(settings:)` multiple times

    Destination plugin calls `update(settings:)` multiple times

    Describe the bug The included AppsFlyer example currently results in the plugin reaching an indeterminate state.

    I'm not sure whether this is because the example needs to be re-architected, or because the plugin architecture is not behaving as it was designed.

    My expectation is that the set-up for AppsFlyer should always be done prior to AppsFlyerLib.shared().start() being called.

    However, with the current example this isn't guaranteed.

    From my observations on an iPhone X and iPhone 7 Plus, I can see that update(settings:) is often called twice. This is the method that contains the AppsFlyer set-up code.

    The first time it is called is prior to the plugin's applicationDidBecomeActive(application:) method being called. This would be what I expect, but at this point Segment doesn't appear to have loaded the AppsFlyer specific settings and so the majority of this method's execution, and therefore the AppsFlyer set-up, is skipped.

    Shortly after, applicationDidBecomeActive(application:) is then called. This invokes AppsFlyerLib.shared().start(), but as the settings were missing previously, AppsFlyer is started without necessary setup having taken place.

    So when update(settings:) is called a second time, this time with the associated AppsFlyer settings, the plug-in doesn't behave as expected. For example, the AppsFlyerLibDelegate method onConversionDataSuccess(_:) may not get called at all.

    triage 
    opened by tcldr 8
  • Feature Request: Build Facebook App Events Destination plugin

    Feature Request: Build Facebook App Events Destination plugin

    Is your feature request related to a problem? Please describe. We're trying to migrate away from CocoaPods towards Swift Package Manager for our dependency management and the lack of SPM support of FacebookAppEvents is blocking us from completing that goal.

    Describe the solution you'd like We'd like to migrate all of our dependency management to Swift Package Manager, including Segment FacebookAppEvents

    Describe alternatives you've considered Our only option is to continue using CocoaPods for all our Segment, Facebook, and GoogleAnalytics/Firebase needs because Segment FacebookAppEvents pulls all the others in via CocoaPods and trying to import them both via CocoaPods and SPM creates build issues.

    enhancement 
    opened by jfrodden 7
  • Compile error in Release configuration archiving with 1.0.4

    Compile error in Release configuration archiving with 1.0.4

    Describe the bug The following compile-time errors occur in Segment 1.0.4 when archiving a Release configuration app:

    …/SourcePackages/checkouts/analytics-swift/Sources/Segment/Utilities/JSON.swift:305:19: error: thrown expression type 'String' does not conform to 'Error'
                throw "This JSON object is not an array type."
                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    …/SourcePackages/checkouts/analytics-swift/Sources/Segment/Utilities/JSON.swift:328:19: error: thrown expression type 'String' does not conform to 'Error'
                throw "This JSON object is not an array type."
                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    …/SourcePackages/checkouts/analytics-swift/Sources/Segment/Utilities/JSON.swift:350:19: error: thrown expression type 'String' does not conform to 'Error'
                throw "This JSON object is not an array type."
                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    

    I'm not sure why it works in Debug configuration builds, but it seems odd to be throwing a String. I tried searching but couldn't find an Error conformance for String in the package.

    triage 
    opened by JetForMe 7
  • Adding SPM dependency to Xcode with default

    Adding SPM dependency to Xcode with default "up to 1.0.0" results in package resolution error due to sovran URL

    Describe the bug When you add analytics-swift to an Xcode project, the default is to have it fetch "up to next major from ". Unfortunately, tag 1.0.0's Package.swift contains a reference to Sovran [email protected]:segmentio/Sovran-Swift.git, which Xcode fails to pull, getting

    x-swift-package-repository-authentication://?scm=com.apple.dt.Xcode.sourcecontrol.Git&[email protected]:segmentio/Sovran-Swift.git#error=-1005 Authentication failed because the credentials were missing
    

    Your main branch has an updated Package.swift. You should probably make a new tag in git with that change.

    To Reproduce Steps to reproduce the behavior:

    1. Add analytics-swift using default Xcode version selection
    2. Be sad
    triage 
    opened by JetForMe 7
  • Crashes observed in OutputFileStream due to EXC_BAD_ACCESS.

    Crashes observed in OutputFileStream due to EXC_BAD_ACCESS.

    Recently we've noticed crashes coming from the new OutputFileStream code. An example stack trace is included at the end of this issue.

    While digging into this, we noticed the switch from the foundation FileHandle API to the older POSIX API. The rationale presumably is the deprecation of the write(data: Data) function. This left us perplexed and we believe this to be a misunderstanding. The specific write(data: Data) function was deprecated, yes, but it was replaced with the generic write<T>(contentsOf: T) throws where T : DataProtocol function. As well as being more flexible in its input parameter, the new function also properly communicates errors via throws (related: unhandled exceptions at the write(data: Data) call site was previously an issue we saw coming from your code). It is a welcome replacement (:

    If I may, it seems the best course of action would be to remove the OutputFileStream addition, specifically, and simply update the code as it was previously so that it uses the non-deprecated write function from FileHandle. And, the new API forces you to handle the errors I mentioned we had also been encountering, 2 birds...

    But, if you must stick with the POSIX API, which, while fun to use at times, I would strongly discourage, then the implementation needs some work. There are numerous issues (lack of handling for short writes, unnecessary string conversions, generally thread safety, dubious pointer handling, etc.) which I'm happy to help you through if you decide to stick with this route. But, it's super tricky to get all this right when using the POSIX API hence why the first class Apple-supported Foundation APIs are preferred over the POSIX ones.

    Hardware Model:     iPhone14,3
    Process:            Uno
    Identifier:         app.Uno
    Version:            1.0
    Role:               Background
    OS Version:         iOS 16.0
    Exception Type:     EXC_BAD_ACCESS 
    Exception Subtype:  KERN_INVALID_ADDRESS
    
    
    EXC_BAD_ACCESS: Attempted to dereference garbage pointer 0x68.
    
    0  libsystem_c.dylib _flockfile
    1  libsystem_c.dylib _fwrite
    2  Uno               closure #1 in OutputFileStream.write(_:) (OutputFileStream.swift:69:17)
    3  Uno               specialized String.UTF8View.withContiguousStorageIfAvailable<A>(_:) (<compiler-generated>)
    4  Uno               OutputFileStream.write(_:) (OutputFileStream.swift:67:29)
    5  Uno               closure #1 in Storage.write<A>(_:value:) (Storage.swift:42:26)
    6  Uno               thunk for @callee_guaranteed () -> () (<compiler-generated>)
    7  Uno               thunk for @escaping @callee_guaranteed () -> () (<compiler-generated>)
    8  libdispatch.dylib __dispatch_client_callout
    9  libdispatch.dylib __dispatch_lane_barrier_sync_invoke_and_complete
    10 Uno               Storage.write<A>(_:value:) (Storage.swift:37:19)
    11 Uno               SegmentDestination.queueEvent<A>(event:) (SegmentDestination.swift:126:17)
    12 Uno               SegmentDestination.execute<A>(event:) (SegmentDestination.swift:106:13)
    13 Uno               specialized closure #1 in Mediator.execute<A>(event:) (Timeline.swift:78:32)
    14 Uno               specialized Timeline.process<A>(incomingEvent:) (Timeline.swift:37:13)
    15 Uno               closure #1 in StartupQueue.replayEvents() (StartupQueue.swift:60:28)
    16 Uno               thunk for @callee_guaranteed () -> () (<compiler-generated>)
    17 Uno               thunk for @escaping @callee_guaranteed () -> () (<compiler-generated>)
    18 libdispatch.dylib __dispatch_client_callout
    19 libdispatch.dylib __dispatch_lane_barrier_sync_invoke_and_complete
    20 Uno               StartupQueue.replayEvents() (StartupQueue.swift:58:19)
    21 Uno               closure #1 in StartupQueue.analytics.didset (StartupQueue.swift:21:23)
    22 Uno               thunk for @escaping @callee_guaranteed (@in_guaranteed A) -> () (<compiler-generated>)
    23 Uno               thunk for @escaping @callee_guaranteed (@in_guaranteed A) -> (@out ()) (<compiler-generated>)
    24 Uno               closure #1 in Store.notify<A>(subscribers:state:) (Store.swift:250:21)
    25 Uno               thunk for @escaping @callee_guaranteed () -> () (<compiler-generated>)
    26 libdispatch.dylib __dispatch_call_block_and_release
    27 libdispatch.dylib __dispatch_client_callout
    28 libdispatch.dylib __dispatch_main_queue_drain
    29 libdispatch.dylib __dispatch_main_queue_callback_4CF
    30 CoreFoundation    ___CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
    31 CoreFoundation    ___CFRunLoopRun
    32 CoreFoundation    _CFRunLoopRunSpecific
    33 GraphicsServices  _GSEventRunModal
    34 UIKitCore         -[UIApplication _run]
    35 UIKitCore         _UIApplicationMain
    36 SwiftUI           0x18a82fce4 (0x18a82fc40 + 164)
    37 SwiftUI           0x18a78cc20 (0x18a78cb8c + 148)
    38 SwiftUI           0x18a775b40 (0x18a775ac4 + 124)
    39 Uno               static App.$main() (App.swift:74:1)
    40 dyld              start
    
    triage 
    opened by dcow 6
  • Identify call doesn't appear in web debugger with certain userId value

    Identify call doesn't appear in web debugger with certain userId value

    Describe the bug I am calling the identify method with a hashed copy of the user's email address. This never appears in the web debugger, but when I change the userId to something short, such as my first name or "test", it works without issue. Is there a character limit applied? The segment debugger doesn't show any signs of errors.

    To Reproduce Steps to reproduce the behavior:

    1. Do identify(userId: "ee1d83696ded26626ad9fd3f9ad4a28f207cab5a")
    2. Notice no debugging errors in Xcode, but web debugger doesn't receive event.3.
    3. Do identify(userId: "test")
    4. Notice that the event appears in web debugger.

    Expected behavior The event should be sent to Segment, and shown in the web debugger.

    Platform (please complete the following information):

    • Library Version in use: 1.3.1
    • Platform being tested: iOS
    • Integrations in use: Amplitude
    triage 
    opened by nickjf89 5
  • feat: add application foregrounded events to iOS and macOS

    feat: add application foregrounded events to iOS and macOS

    This PR adds an "Application Foreground" event to the iOS and macOS lifecycle handlers which is tracked on every call of applicationDidBecomeActive. This is equivalent to the "Application Backgrounded" event which is tracked on every call of applicationDidResignActive.

    Closes #172.

    opened by seanrucker 0
  • Support for

    Support for "Application Foregrounded" Events

    The SDK automatically tracks lifecycle events, including an "Application Backgrounded" event in the applicationDidResignActive hook. In the corresponding applicationDidBecomeActive hook, the current implementation uses a flag to track an "Application Opened" event the first time it is called (which makes sense) but there is no event tracked on every call of applicationDidBecomeActive.

    I am proposing there should be an equivalent "Application Foregrounded" event that is tracked every time applicationDidBecomeActive is called.

    The pair of these two events would provide accurate "bookends" for session time tracking in various analytics platforms. I am using Mixpanel and from their documentation you can see we need to supply a "Session Start Event" and a "Session End Event".

    https://help.mixpanel.com/hc/en-us/articles/115004695223

    There are other ways to track session time (at least in Mixpanel) using a timeout but this approach is less accurate and event then, without an "Application Foregrounded" event there isn't a guaranteed accurate way to signal the beginning of a session.

    We need this on macOS and iOS which both seem to have a similar implementation in the applicationDidBecomeActive and appears to be a trivial addition. I can't speak for Linux or watchOS.

    triage 
    opened by seanrucker 0
  • Fix issue where cascading network timeouts compound on each other

    Fix issue where cascading network timeouts compound on each other

    Fixes issue #152

    It was observed that when network traffic is blocked that outbound requests are timing out after 60 seconds, however the flush interval has a default of 30 seconds. This would result in a cascading set of outbound network requests that would all fail.

    This change makes it such that in the case where connectivity is unavailable, we pause the flush timer for 5 minutes before attempting again.

    opened by bsneed 10
  • SegmentDestination is causing huge CPU spikes when blocked by LittleSnitch

    SegmentDestination is causing huge CPU spikes when blocked by LittleSnitch

    Describe the bug When using LittleSnitch to block traffic to Segement.io from our application, we are getting huge CPU Spikes really often, and when entering foreground/background - basically every time the flush is called.

    I think there are several problems in SegmentDestination:

    1. Storage can grow without limits - old events that are not sent are never removed.
    2. Storage is keeping files infinitely - which is causing a snowball effect for every sync.
    3. Flush logic is not well prepared for having a lot of data to work with. First of all, it read all the data from the filesystem every time it's called. Then for each of the files, it creates a network request straight away iterating over all of them - which in my case ends up being over 1500 requests created and failing in milliseconds. This is when CPU spikes are kicking in. The whole process is repeated every time the flush() is called and things are getting worse and worse over time when more un-send events are piling up in the storage.

    To Reproduce Steps to reproduce the behavior:

    1. Install LittleSnitch
    2. Block segment.io traffic in LittleSnitch
    3. Create around 100.000 tracked events in Segment
    4. Observe the CPUSpikes when flush logic is called.
    5. Log an enormous amount of network connections created during the flush() call.

    Expected behavior

    1. If the user decides to block segment.io coming from our application using external software there should be no performance drop or CPU spikes coming out of this library.

    2. Storage should not grow infinitely - at some point, older events should be removed when newer events are added - there should be the maximum amount of files that are allowed to be cached for sending.

    3. flush() method should not go so aggressive with creating network events for all un-send files - instead it should either go one by one and read the next files only when the previous one succeeded or it should pre-check if segment batch API is reachable before trying to create a massive amount of requests.

    Platform (please complete the following information):

    • Library Version in use: 1.2.2
    • Platform being tested: macOS
    • Integrations in use: Amplitude

    Workaround As for now, I am using an ugly workaround from this fork that simply deleted all failed events if the error is URLError.networkConnectionLost - which is the case for LittleSnitch.

    triage 
    opened by grzegorzkrukowski 6
Releases(1.3.3)
  • 1.3.3(Nov 3, 2022)

    -e - (Alan Charles) Yml fix (#171)

    • (Alan Charles) feat: add widget extension example (#170)
    • (Brandon Sneed) Fixed Configuration.apiHost not being honored before retrieving /settings (#168)
    • (Alan Charles) feat: add requestFactory to Configuration (#165)
    • (Brandon Sneed) Storage hardening; Add error handling capabilities. (#163)
    • (Brandon Sneed) Fix unnecessary retains to prevent zombie Analytics instances (#164)
    • (VolodymyrHanas) fix: nil value parsing (#161)
    Source code(tar.gz)
    Source code(zip)
  • 1.3.2(Oct 6, 2022)

  • 1.3.1(Jul 11, 2022)

  • 1.3.0(May 6, 2022)

  • 1.2.4(May 3, 2022)

    • (Tasha Alfano) updated readme with missing .
    • (Brandon Sneed) Example plugins for more detailed cellular info (#139)
    • (Cody Garvin) Add macOS Lifecycle Support (#141)
    • (Cody Garvin) Added ability to add xcframework as an artifact (#140)
    • (Cody Garvin) Removes unsupported destinations and adds the ability to build XCFrameworks (#136)
    • (Brandon Sneed) Bump xcode version for CI (#131)
    Source code(tar.gz)
    Source code(zip)
    Segment.xcframework.zip(2.68 MB)
  • 1.2.3(Mar 28, 2022)

  • 1.2.2(Mar 18, 2022)

  • 1.2.1(Mar 17, 2022)

    • (Brandon Sneed) Added supported destinations to Readme. (#127)
    • (Cody Garvin) Fixed applicationDidFinishLaunching issue when using SwiftUI / Scenes (#126)
    • (Alan Charles) fix: fix timing issue in idfa (#125)
    • (Alan Charles) Update Readme.md (#124)
    Source code(tar.gz)
    Source code(zip)
  • 1.2.0(Mar 8, 2022)

  • 1.1.2(Feb 24, 2022)

  • 1.1.1(Feb 16, 2022)

    • (Brandon Sneed) Remove unused taskID. (#119)
    • (Brandon Sneed) Add example plugin for Facebook App Events (#118)
    • (Davis Gossage) Fix cleanup handler not called on background task expiration due to struct being captured before assignment (#115)
    • (Cody Garvin) Fixed lifecycle issue and added tests (#117)
    • (Wenxi Zeng) correct identify doc (#114)
    • (Niall Brennan) Fix Firebase Plugin Import (#112)
    Source code(tar.gz)
    Source code(zip)
  • 1.1.0(Jan 26, 2022)

    • (Brandon Sneed) Fix for app being terminated due to lingering bg tasks. (#111)
    • (Stephan Diederich) on macOS, like on tvOS use the caches folder (#108)
    • (Wenxi Zeng) Shutdown ci for fork (#105)
    • (Brandon Sneed) Use different path for tvOS storage. (#103)
    • (Cody Garvin) Fixed foreground call for iOS (#101)
    • (Cody Garvin) Added alias to objective-c bridge (#99)
    • (Brandon Sneed) Call correct process method in Group. (#96)
    • (Peter Minarik) fix: screen event needs to be setup properly (#93)
    Source code(tar.gz)
    Source code(zip)
  • 1.0.6(Nov 17, 2021)

    • (Brandon Sneed) Cleaned up file storage removal code (#95)
    • (Brandon Sneed) Integration enable/disable refactor (#92)
    • (Brandon Sneed) Storage and Multi-threading fixes (#91)
    Source code(tar.gz)
    Source code(zip)
  • 1.0.5(Nov 2, 2021)

    • (Brandon Sneed) Fixes compile issue w/ throws using String:Error conformance. (#90)
    • (Brandon Sneed) Remove redundant code (#87)
    • (Wenxi Zeng) optimize gha (#84)
    Source code(tar.gz)
    Source code(zip)
  • 1.0.4(Oct 26, 2021)

    • (Cody Garvin) Fixed log toggling (#86)
    • (Tristan) update ISO8601 utility to remove timezone colon (#76)
    • (Brandon Sneed) Made working with and modifying payloads within plugins much simpler. (#83)
    • (Wenxi Zeng) address-pull-request-target-discrepancies (#82)
    • (Wenxi Zeng) replace pull_request with pull_request_target (#79)
    • (Cody Garvin) Updated layout and error states for logging (#77)
    • (Wenxi Zeng) setup github action (#74)
    • (Cody Garvin) Added Intercom Destination Example (#73)
    • (Cody Garvin) Repair CircleCI and linux tests (#72)
    • (Cody Garvin) Fixed crashing unit tests from userAgent update (#71)
    • (Cody Garvin) Merge branch 'main' of github.com:segmentio/analytics-swift
    • (Cody Garvin) Repaired xcode project for testing
    • (Cihat Gündüz) Ensure WKWebView is initialized in main thread (#70)
    • (Prayansh Srivastava) add links to sample plugins (#68)
    • (Cody Garvin) Version 1.0.3
    • (Cody Garvin) Merge branch 'main' of github.com:segmentio/analytics-swift
    • (Cody Garvin) Added Comscore Destination (#67)
    • (Cody Garvin) Updated Amplitude Session key to match new key (#66)
    • (Cody Garvin) Updated Amplitude Session key to match new key
    • (Brandon Sneed) Fixes issue w/ amplitude sessionId not working (#65)
    • (Cody Garvin) Updates to destinations to match ExampleDestination (#64)
    • (Cody Garvin) Added Logger and SegmentLogger plugin. (#46)
    • (Brandon Sneed) Example of auto notification tracking (#63)
    • (Cody Garvin) Migs647/exampledestination2 (#62)
    • (Prayansh Srivastava) update README for beta release (#60)
    • (Brandon Sneed) Reduce file descriptor consumption (#59)
    • (Cody Garvin) Fixed flush test (#57)
    • (Brandon Sneed) Refactor screen fun param from screenTitle to title. (#56)
    • (Brandon Sneed) Added type enum param to update(settings:) (#53)
    • (Brandon Sneed) Renamed mapKeys to mapTransform (#52)
    • (Brandon Sneed) Fixed Appsflyer plugin conformance issues. (#50)
    • (Brandon Sneed) Example App fixups (#49)
    • (Brandon Sneed) Improve startup plugin collection. (#45)
    • (Brandon Sneed) Fix context issue and macOS vendor system miss. (#44)
    • (Brandon Sneed) Merge branch 'main' of github.com:segmentio/analytics-swift
    • (Brandon Sneed) Updated package.resolved.
    • (Brandon Sneed) minor fixes (#43)
    • (Brandon Sneed) Add objective-c compatibility / example (#39)
    • (Alan Charles) add extensions example (#40)
    • (Brandon Sneed) Adds key mapping support for use in destination plugins. (#38)
    • (Brandon Sneed) Fixes issue w/ UIApplication.shared not being supported in iOS App Extensions (#37)
    • (Brandon Sneed) Modify destinations to avoid processing if they don't have settings (#36)
    • (Brandon Sneed) Plugin Interface refactor (#35)
    Source code(tar.gz)
    Source code(zip)
  • 1.0.3(Sep 29, 2021)

    • (Cody Garvin) Merge branch 'main' of github.com:segmentio/analytics-swift
    • (Cody Garvin) Added Comscore Destination (#67)
    • (Cody Garvin) Updated Amplitude Session key to match new key (#66)
    • (Cody Garvin) Updated Amplitude Session key to match new key
    • (Brandon Sneed) Fixes issue w/ amplitude sessionId not working (#65)
    • (Cody Garvin) Updates to destinations to match ExampleDestination (#64)
    • (Cody Garvin) Added Logger and SegmentLogger plugin. (#46)
    • (Brandon Sneed) Example of auto notification tracking (#63)
    • (Cody Garvin) Added ExampleDestination and updated Mixpanel Destination (#62)
    • (Prayansh Srivastava) update README for beta release (#60)
    • (Brandon Sneed) Reduce file descriptor consumption (#59)
    • (Cody Garvin) Fixed flush test (#57)
    • (Brandon Sneed) Refactor screen fun param from screenTitle to title. (#56)
    • (Brandon Sneed) Added type enum param to update(settings:) (#53)
    • (Brandon Sneed) Renamed mapKeys to mapTransform (#52)
    • (Brandon Sneed) Fixed Appsflyer plugin conformance issues. (#50)
    • (Brandon Sneed) Example App fixups (#49)
    • (Brandon Sneed) Improve startup plugin collection. (#45)
    • (Brandon Sneed) Fix context issue and macOS vendor system miss. (#44)
    • (Brandon Sneed) Merge branch 'main' of github.com:segmentio/analytics-swift
    • (Brandon Sneed) Updated package.resolved.
    • (Brandon Sneed) minor fixes (#43)
    • (Brandon Sneed) Add objective-c compatibility / example (#39)
    • (Alan Charles) add extensions example (#40)
    • (Brandon Sneed) Adds key mapping support for use in destination plugins. (#38)
    • (Brandon Sneed) Fixes issue w/ UIApplication.shared not being supported in iOS App Extensions (#37)
    • (Brandon Sneed) Modify destinations to avoid processing if they don't have settings (#36)
    • (Brandon Sneed) Plugin Interface refactor (#35)
    Source code(tar.gz)
    Source code(zip)
  • 1.0.2(Aug 4, 2021)

    • (Brandon Sneed) Add release automation script. (#33)
    • (Cody Garvin) Updated lifecycle events for AmplitudeSession (#31)
    • (Cody Garvin) Added file size storage limits (#30)
    • (Brandon Sneed) watchOS basics + refactors (#29)
    • (Alan Charles) Create README.md (#28)
    • (Cody Garvin) Migs647/mixpanel (#21)
    • (Alan Charles) Add AppsFlyer plugin (#27)
    • (Alan Charles) Update README.md
    • (Brandon Sneed) Add StartupQueue automatically; update tests. (#26)
    • (Cody Garvin) Added Firebase destination (#25)
    • (Brandon Sneed) Bsneed/queueing (#24)
    • (Alan Charles) Update AmplitudeSession.swift
    • (Brandon Sneed) Bsneed/dest cleanup (#22)
    • (Cody Garvin) Added Mixpanel Destination (#18)
    • (Cody Garvin) Removed flurry instances from UIKit Example (#20)
    • (Brandon Sneed) Create RELEASING.md (#19)
    • (Cody Garvin) Added SwiftUI example (#16)
    • (Brandon Sneed) Fixes + Misses corrections (#17)
    • (Brandon Sneed) Add Adjust device mode integration sample & example app (#15)
    • (Brandon Sneed) Adding Examples of Apps, Plugins and Tasks. (#14)
    • (Brandon Sneed) Update circleci for bigsur (#13)
    • (Brandon Sneed) Additional platform testing (#12)
    • (Brandon Sneed) Better handle errors where conversion occurs. (#11)
    • (Brandon Sneed) Removes need for analytics param in Plugin init (#9)
    • (dsjackins) Fix links, touch up docs (#8)
    Source code(tar.gz)
    Source code(zip)
  • 1.0.0(May 5, 2021)

    Analytics-Swift v1.0.0

    We are announcing the pilot of Analytics Swift! Analytics Swift is a library that provide a simple, modern instrumentation experience for mobile apps.

    Why did we launch Analytics Swift?

    The iOS ecosystem has evolved rapidly, and has introduced new frameworks and best practices for building and managing mobile apps. To align with some significant advancements in these ecosystems over the last few years, we are introducing Analytics Swift library.

    What do you need to know about Analytics Swift?

    Analytics Swift library improves performance, data observability, and the overall developer experience. Additionally, the improved app performance unlocks insights into app funnel and business metrics with a modern developer experience. The library opens opportunities to instrument app tracking across platforms, like iPadOS, watchOS, and TV Apps.

    Are there any known limitations to Analytics Swift?

    Analytics Swift does not support mobile device-mode destinations. Destinations may only be configured in cloud mode during pilot.

    Should these library be used in production?

    During the pilot phase, we strongly discourage production use cases. This library is prone to change and we may introduce breaking changes. This library is governed under our First-Access & Beta terms.

    Source code(tar.gz)
    Source code(zip)
Owner
Segment
Segment
Analytics layer abstraction, abstract analytics reporters and collect domain-driven analytic events.

?? Tentacles Current State: Work in Progress Documentation & Tests(100% completed, but needs refactoring and structuring) started but not done yet, im

Patrick 3 Dec 2, 2022
Facebook Analytics In-App Notifications Framework

Facebook In-App Notifications enables you to create rich and customizable in-app notifications and deliver them via push notifications, based on the a

Meta Archive 496 Nov 17, 2022
MySQL driver for Swift 3 (macOS and Linux)

MySQL MySQL Usage // do your magic Installation import PackageDescription let package = Package( dependencies: [ .Package(url: "https://g

Zewo Graveyard 29 Jan 29, 2022
iScheduleYourDay is a watchOS 8.5 app that can help order your daily tasks

Currently developing an App for watchOS 8.5 to help order your tasks daily. The app is a simple approach to the actual Apple App Remainders to become an improved version of it

Marta Granero I Martí 2 Aug 11, 2022
Swift APIs for SQLite: Type-safe down to the schema. Very, very, fast. Dependency free.

Lighter Lighter is a set of technologies applying code generation to access SQLite3 databases from Swift, e.g. in iOS applications or on the server. L

Lighter.swift 330 Dec 26, 2022
Simple, Strongly Typed UserDefaults for iOS, macOS and tvOS

简体中文 DefaultsKit leverages Swift 4's powerful Codable capabilities to provide a Simple and Strongly Typed wrapper on top of UserDefaults. It uses less

Nuno Dias 1.4k Dec 26, 2022
Add Strictly Typed NIO Channel Builders for Swift 5.7

⚠️ Requires Swift 5.7 Omnibus is a set of helpers for SwiftNIO that allow you to leverage Swift's generics type system to create NIO Channels. It depe

Orlandos 6 Jun 10, 2022
❤️ Continuous heart rate measurement during workouts with watchOS 3.

Heart Control Monitor your heart rate on the apple watch - continuously and easy. What is it? Heart Control is a standalone watch app to monitor conti

Thomas Paul Mann 189 Dec 16, 2022
Movies Information DataBase (Add - Delete - Edit - Search)

MoviesInformation Movies Information DataBase (Add - Delete - Edit - Search) This Code Provide Simple Program About Movies Information This Program Ca

Mohammad Jaha 2 Sep 15, 2021
A Generic CoreData Manager to accept any type of objects. Fastest way for adding a Database to your project.

QuickDB FileManager + CoreData ❗️ Save and Retrieve any thing in JUST ONE line of code ❗️ Fast usage dataBase to avoid struggling with dataBase comple

Behrad Kazemi 17 Sep 24, 2022
macOS App for App Store Connect to Improve Processing Efficiency and Enjoy the Party.

Apple Party(苹果派) 一、App 介绍 AppleParty 是三七互娱旗下37手游 iOS 团队研发,实现快速操作 App Store Connect 后台的自动化 macOS 工具。 使用和原理介绍:开源一款苹果 macOS 工具 - AppleParty(苹果派) 支持功能 内购买

37iOSTeam 173 Dec 30, 2022
PJAlertView - This library is to make your own custom alert views to match your apps look and feel

PJAlertView - This library is to make your own custom alert views to match your apps look and feel

prajeet 6 Nov 10, 2017
Check your Valorant store from your phone!

Valorant Store Checker Description VSC (Valorant Store Tracker) is an open source iOS app that allows you to track your store and preview your skins.

Gordon 20 Dec 29, 2022
Easy and beautiful way for a user to pick content, files or images. Written in Objective C

##JVTImageFilePicker Description ImageFilesPicker Is a butifuly designed UICompenent for uploading content Preview from recent camera roll Live Camera

Matan Abravanel 60 Jun 19, 2022
macOS WeChat.app header files version history (automatic updated)

macos-wechat-app-tracker macOS WeChat.app header files version history (automatic updated) Troubleshooting $ class-dump -H /Applications/WeChat.app 20

Wechaty 3 Feb 10, 2022
An iOS app to lift the speed limit of your Cowboy Bike

Legal Notice 1. I am not resposible to anything worse that could happen to your bike because of this app 2. Be careful that lifting the 25km/h limit c

null 74 Dec 15, 2022
Which contacts changed outside your iOS app? Better CNContactStoreDidChange notification: get real changes, without the noise.

ContactsChangeNotifier Which contacts changed outside your iOS app? Better CNContactStoreDidChange notification: Get real changes, without the noise.

Yonat Sharon 5 Oct 31, 2022
A GUI for dynamically creating NSPredicates at runtime to query data in your iOS app.

PredicateEditor PredicateEditor is a visual editor for creating and using NSPredicates for querying data in your app. PredicateEditor was inspired by

Arvindh Sukumar 362 Jul 1, 2022
An efficient, small mobile key-value storage framework developed by WeChat. Works on Android, iOS, macOS, Windows, and POSIX.

中文版本请参看这里 MMKV is an efficient, small, easy-to-use mobile key-value storage framework used in the WeChat application. It's currently available on Andr

Tencent 15.4k Jan 6, 2023