Giter Club home page Giter Club logo

push-notifications-swift's Introduction

Pusher Beams iOS & macOS SDK

Build Status codecov Latest Release API Docs Supported Platforms Swift Versions Twitter LICENSE

Example Code

Building and Running

Minimum Requirements

Installation

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:

$ gem install cocoapods

CocoaPods version 1.3.1 or newer is recommended to build Pusher Beams.

To integrate Pusher Beams into your Xcode project using CocoaPods, specify it in your Podfile:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '10.0'
use_frameworks!

# Replace `<Your Target Name>` with your app's target name.
target '<Your Target Name>' do
    pod 'PushNotifications', '~> 4.0.0'
end

Then, run the following command:

$ pod install

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.

Carthage version 0.26.2 or newer is recommended to build Pusher Beams.

You can install Carthage with Homebrew using the following command:

$ brew update
$ brew install carthage

To integrate Pusher Beams into your Xcode project using Carthage, specify it in your Cartfile:

github "pusher/push-notifications-swift"

Continue following the steps below depending on the platform that you're building the dependency for:

  • If you're building for OS X, follow this guide.
  • If you're building for iOS, tvOS, or watchOS, follow this guide.

Swift Package Manager

Swift Package Manager is a tool for managing the distribution of Swift code. It’s integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies.

Manual Xcode integration

To integrate Pusher Beams into your Xcode project using Swift Package Manager, in your Xcode choose File > Swift Packages > Add Package Dependency... and provide the following URL:

https://github.com/pusher/push-notifications-swift

Swift Package Manager dependency

To add Pusher Beams as a dependency of your own package use the follwing code:

dependencies: [
    .package(url: "https://github.com/pusher/push-notifications-swift.git", from: "4.0.0")
]

Migrating from 2.x.x

We now require you to start beams before you can use the library, for example to register any interests. This means the following code would no longer work and log an error to the console:

try! PushNotifications.shared.addDeviceInterest("donuts")
PushNotifications.shared.start("YOUR_INSTANCE_ID")

You now need to replace it with the following:

PushNotifications.shared.start("YOUR_INSTANCE_ID")
try! PushNotifications.shared.addDeviceInterest("donuts")

We recommend start is always called in the application didFinishLaunchingWithOptions callback. Note that you can still control when you show the request for push notification prompt, start does not call this prompt.

Running Tests

Generating Test Coverage Reports

We're using Slather for generating test coverage reports locally and Codecov when pull requests are submitted.

Using Slather

Create a report as static html pages by running:

slather coverage --html --scheme PushNotifications --workspace PushNotifications.xcworkspace/ PushNotifications/PushNotifications.xcodeproj/

Open the html reports:

open 'html/index.html'

Pusher Beams Reference

  • Autogenerated reference docs.
  • Pusher Beams iOS SDK docs.

Communication

  • Found a bug? Please open an issue.
  • Have a feature request. Please open an issue.
  • If you want to contribute, please submit a pull request (preferrably with some tests).

Credits

Pusher Beams is owned and maintained by Pusher.

License

Pusher Beams is released under the MIT license. See LICENSE for details.

push-notifications-swift's People

Contributors

benjamin-tang-pusher avatar daniellevass avatar danielrbrowne avatar grzesiekko avatar lukabratos avatar marcelcorso avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

push-notifications-swift's Issues

This copy of libswiftCore.dylib requires an OS version prior to 12.2.0

I am working on a React Native project with EMBEDDED_CONTENT_CONTAINS_SWIFT set to YES and SWIFT_VERSION set to 5.0 in pod file like below

pod 'PushNotifications', '~> 1.3'

targets = ['PushNotifications']

if targets.include? target.name
  target.build_configurations.each do |config|
    config.build_settings['SWIFT_VERSION'] = '5.0'
  end
end

It works perfect, but does not work with iOS 12.2. Running on iOS 12.2 causes 'This copy of libswiftCore.dylib requires an OS version prior to 12.2.0' and crashes

Does anyone have idea of it?

Cheers

No way to tell if device already registered

In the Android library, when PushNotifications.shared.start is called with an instance ID that is different from the instance ID that was previously registered, an error is raised which can be caught and then displayed to the user. (Eg. uninstall/reinstall the app).

Currently, when .start fails, it does not raise any exceptions, although it does log that the device has already been registered.

EventTypeHandler.swift "UIApplicationState" changes to "UIApplication.State" on update

Running carthage update --platform iOS. In the checked out version of the file EventTypeHandler.swift the function shows applicationState: UIApplication.State while the repository version shows applicationState: UIApplicationState.

This causes an error code 65 with the log showing:

/Users/alexandrecanuto/Projetos/Ever/experimento-myexp/Carthage/Checkouts/push-notifications-swift/Sources/EventTypeHandler.swift:8:104: error: 'State' is not a member type of 'UIApplication'
    static func getNotificationEventType(userInfo: [AnyHashable: Any], applicationState: UIApplication.State) -> ReportEventType? {

Manually changing UIApplication.State to UIApplicationState prevents the error. What am I doing wrong here?

Carthage v0.31.0
push-notifications-swift v1.1.0
Xcode v9.2

Array+CalculateMD5 - Optional string not unwrapped

Good day,

Just installed the Pusher Beams pod via the Pusher website as per the instructions. I am still receiving the Value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'? error in the file Array+CalculateMD5.swft. I see there was a fixed pushed for this 2 months ago though although the problem still persist. I have reinstalled a couple of times, cleaned the project but still no luck.

screen shot 2018-09-11 at 14 27 05

Pusher Beams and iOS , device dont getting push notifications always

Hallo everybody.
I have some problem with push notifications and Pusher Beams on my iOS app. Notifications are working but jot always, sometimes i need to make a few request for notification to be displayed. I imported Notifications Service Extension, se ding mutable content 1. Any Idea why notifications sometimes comes sometime not?

Use the Swift 'Result' type instead of a custom implementation

A custom implementation of a Result type is used currently. The Swift Standard Library implementation should be used instead.

  • Update the Swift language version to 5.0+ (to allow use of the STL Result type).
  • Remove the custom implementation of Result.
  • Refactor the codebase to use the STL Result implementation.

Module 'PushNotifications' not found after installing with CocoaPods, but not with Carthage

Hello,

I used to have

github "pusher/push-notifications-swift"

and @import PushNotifications; in the .m file worked, but I had defined other dependencies in the Podfile already, so I thought I'd only use the Podfile, but the import then no longer works. The pod install went fine and I added PushNotifications.framework to the Linked Frameworks and Libraries (though was that required?). The PushNotifications is also visible in Pods > Pods in the project tree.

Do you have any ideas or suggestions? Thanks.


Podfile

# Uncomment the next line to define a global platform for your project
platform :ios, '10.0'
use_frameworks!

target 'ReactCake' do
  pod 'GoogleSignIn'
  pod 'Intercom', '> 5.2'
  pod 'PushNotifications', '~> 1.2.0'
end

# https://github.com/CocoaPods/CocoaPods/issues/8118
pre_install do |installer|
  installer.analysis_result.specifications.each do |s|
    s.swift_version = '4.2.1' unless s.swift_version
  end
end

Swift 4.2 Support

Its giving me compile error when I am trying to build with new XCode 10

SDK will not start

Unrecoverable error when registering device with Pusher Beams (Reason - Bad Device Token: The device token could not be validated against any known credentials) how solve this problem?

Network error: Device Not Found

After upgrading from 1.x.x to 3.0.4, I am seeing the following error:

[PushNotifications]: Network error: Device Not Found

My setup in the AppDelegate is as follows:

let pushNotifications = PushNotifications.shared
pushNotifications.start(instanceId: "<id retracted>")
try? pushNotifications.addDeviceInterest(interest: "info")
if isInDebugMode {
    try? pushNotifications.addDeviceInterest(interest: "debug")
}
pushNotifications.registerForRemoteNotifications()

Am I missing something?

Can't import PushNotifications into Objective-C

Hi,
I'm using Cordova to compile my web app into mobile app.

I have no problem using this framework before, but now I'm trying to integrate Pusher(Channels/Beams).

Following the Official Docs, I can't "import PushNotifications",
I've tried with #import, @import but xCode says module not found
image

This is my PodFile
image
In my workspace I can fin the pods installed by Carthage
image
And I have Added into "Link Binary..." section
image

What am I missing? Thank you

error: unexpected non-void return value in void function (ServerSyncEventHandler and ServerSyncProcessHandler)

When building an app that uses PushNotifications pod, I get the following compiler error messages:

/Users/vagrant/git/ios/Pods/PushNotifications/Sources/ServerSyncEventHandler.swift:11:24: error: unexpected non-void return value in void function
                return handler
                       ^~~~~~~
/Users/vagrant/git/ios/Pods/PushNotifications/Sources/ServerSyncEventHandler.swift:15:24: error: unexpected non-void return value in void function
                return handler
                       ^~~~~~~
/Users/vagrant/git/ios/Pods/PushNotifications/Sources/Internal/ServerSyncProcessHandler.swift:9:24: error: unexpected non-void return value in void function
                return handler
                       ^~~~~~~
/Users/vagrant/git/ios/Pods/PushNotifications/Sources/Internal/ServerSyncProcessHandler.swift:13:24: error: unexpected non-void return value in void function
                return handler
                       ^~~~~~~

This happens also with the quickstart application for Chatkit

sh -c "$(curl -fsSL https://raw.githubusercontent.com/pusher/chatkit-quickstart-swift/dashboard/chatkit-quickstart-install.sh)" v1:us1:[instance locator]

This prevents from using PushNotifications pods on CI systems like Bitrise. Any hints?

Crash when Registering for Remote Notifications

I've integrated the Beams iOS SDK 0.10.7 into one of my apps and have consistently received a crash when users are registering devices for notifications.

PushNotifications.swift line 116
specialized PushNotifications.(registerDeviceToken(Data, completion : () -> ()) -> ()).(closure #1)

Here are the crash logs from Fabric:

Crashed: NSOperationQueue 0x1c0024ea0 (QOS: UNSPECIFIED)
0  libdispatch.dylib              0x1835b5a40 _dispatch_queue_resume$VARIANT$mp + 504
1  PushNotifications              0x1010b8b74 specialized PushNotifications.(registerDeviceToken(Data, completion : () -> ()) -> ()).(closure #1) (PushNotifications.swift:116)
2  PushNotifications              0x1010bb294 partial apply for PushNotifications.(registerDeviceToken(Data, completion : () -> ()) -> ()).(closure #1) (PushNotifications.swift)
3  PushNotifications              0x1010b1e68 specialized NetworkService.(register(deviceToken : Data, instanceId : String, completion : (String?, Bool) -> ()) -> ()).(closure #1) (NetworkService.swift:24)
4  PushNotifications              0x1010b2898 partial apply for NetworkService.(register(deviceToken : Data, instanceId : String, completion : (String?, Bool) -> ()) -> ()).(closure #1) (NetworkService.swift)
5  PushNotifications              0x1010b2748 specialized NetworkService.(networkRequest(URLRequest, session : URLSession, completion : (NetworkResponse) -> ()) -> ()).(closure #1) (NetworkService.swift:120)
6  PushNotifications              0x1010b27e4 partial apply for NetworkService.(networkRequest(URLRequest, session : URLSession, completion : (NetworkResponse) -> ()) -> ()).(closure #1) (NetworkService.swift)
7  PushNotifications              0x1010b6214 @callee_owned (@owned Data?, @owned URLResponse?, @owned Error?) -> ()NSData?NSData (PushNotifications.swift)
8  Stashe                         0x10047c494 __InstrumentDataTaskWithRequestCompletionHandler_block_invoke.82 + 4310631572
9  CFNetwork                      0x18424de4c __75-[__NSURLSessionLocal taskForClass:request:uploadFile:bodyData:completion:]_block_invoke + 32
10 CFNetwork                      0x184266b6c __49-[__NSCFLocalSessionTask _task_onqueue_didFinish]_block_invoke + 152
11 Foundation                     0x1846e6e88 __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 16
12 Foundation                     0x1846288d0 -[NSBlockOperation main] + 72
13 Foundation                     0x184627cac -[__NSOperationInternal _start:] + 848
14 libdispatch.dylib              0x1835b0a60 _dispatch_client_callout + 16
15 libdispatch.dylib              0x1835b8170 _dispatch_block_invoke_direct$VARIANT$mp + 224
16 libdispatch.dylib              0x1835b0a60 _dispatch_client_callout + 16
17 libdispatch.dylib              0x1835b8170 _dispatch_block_invoke_direct$VARIANT$mp + 224
18 libdispatch.dylib              0x1835b805c dispatch_block_perform$VARIANT$mp + 104
19 Foundation                     0x1846e8750 __NSOQSchedule_f + 376
20 libdispatch.dylib              0x1835b0a60 _dispatch_client_callout + 16
21 libdispatch.dylib              0x1835b8e94 _dispatch_continuation_pop$VARIANT$mp + 424
22 libdispatch.dylib              0x1835b77cc _dispatch_async_redirect_invoke$VARIANT$mp + 604
23 libdispatch.dylib              0x1835bdcac _dispatch_root_queue_drain + 588
24 libdispatch.dylib              0x1835bd9fc _dispatch_worker_thread3 + 120
25 libsystem_pthread.dylib        0x1838e3fac _pthread_wqthread + 1176
26 libsystem_pthread.dylib        0x1838e3b08 start_wqthread + 4

For more context around our specific situation:

(1) Also even our users who have this crash are still successfully registered and can receive notifications.

(2) We implement the SDK documentation almost exactly, with pushNotifications.registerDeviceToken (and subscribing) in the application:didRegisterForRemoteNotificationsWithDeviceToken: handler
and pushNotifications.start in the application:didFinishLaunchingWithOptions: handler.

One notable difference:

While the documentation recommends registering for notifications in the application:didFinishLaunchingWithOptions: handler, we prefer to wait to request notification authorization from the user until a little later in our new user onboarding flow.

Instead we manually request notification authorization later, using the standard UNUserNotificationCenter documentation. From reading through your source code, it seems to parallel what you do in your pushNotifications.registerForRemoteNotifications method implemented, which we do not call.

My initial hunch:

Since the crash is on serialQueue.resume, my hypothesis is that registering for notifications way later in our flow may affect the suspension of the com.pusher.pushnotifications.sdk dispatch queue done in pushNotifications.start. If so, is there a potential workaround for this?

Otherwise, I was hoping to know if you had any more information to provide that could be helpful around debugging this issue. Thank you!

IOS 10 working with UNUserNotificationCenter?

Hi, Pusher Notifications working with new UNUserNotificationCenter? Thx.

I triying to handle DATA when App in Background.


func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        self.pushNotifications.handleNotification(userInfo: userInfo)
        let content = userInfo
        if let aps = content["aps"] as? [String: AnyObject] {
            let requestId = aps["rid"]
            let companyName = aps["cna"]
            let request = ["request_id": requestId, "company_name": companyName]
            NotificationCenter.default.post(name: Notification.Name("RequestForAlwaysTrackingLocation"), object: nil, userInfo: request as [AnyHashable : Any])
        }
    }

It works only when app in foreground....

Suggestion: Increment badge counter

I'm not really sure about this and if it is even possible.

It would be awesome to be able to set incrementBadge: true when publishing notifications and in this code you could use applicationIconBadgeNumber to increment current badge number with 1 for every notification you get with this flag set to true. In that case notifications to increment badge count without starting the app.

We're building with React Native and we could access this in the JS code but we cannot update the badge count from the JS code until the app is started.

[🐜 Bug Report] Xcode 15 fails to locate `PushNotifications.shared`

Problem

After installing the package per instructions, Xcode is unable to access the framework.

Steps to recreate the issue

  1. Added https://github.com/pusher/push-notifications-swift/ package dependency
  2. Added import PushNotifications to App Delegate
  3. Added let pushNotifications = PushNotifications.shared to App Delegate

Environment

Xcode 15.0.1
Swift version 4.2

App Delegate showing error
Screenshot 2023-11-25 at 2 56 09β€―PM

Cartfile versioning?

Shouldn't the cartfile have a version number added to it?

So instead of this:

github "pusher/push-notifications-swift"

It would have something like this:

github "pusher/push-notifications-swift" ~> 1.0

Add Privacy manifest

Hello Team,

I hope this message finds you well. I would like to draw your attention to an important update required by the App Store. Starting May 1, 2024, a privacy manifest will be mandatory for all apps. Given the ongoing development and support for your SDK, integrating this feature would be highly beneficial for ensuring compliance with the new App Store guidelines. This addition would greatly help developers like us in continuing to provide seamless services through our applications. We appreciate your attention to this matter and look forward to any updates you can provide.

Thank you for your continued support.

Avoid multiple calls of registerDeviceToken

Like suggested by the framework, we should avoid multiple calls of registerDeviceToken. However, I cannot find a way to determine whether this device has already been registered.
I could manually save whether I've subscribed this device in user defaults, but 1. this wouldn't work after a reinstall and 2. would be very un-elegant.

I suggest adding a computed property to the framework, that does the whole user defaults thing as a workaround for now:

var isDeviceRegistered: Bool

Then, in AppDelegate, we could do:

pushNotifications.start(instanceId: "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
if !pushNotifications.isDeviceRegistered {
    pushNotifications.registerForRemoteNotifications()
}
try? pushNotifications.subscribe(interest: "xxx")

crash when registering device tokens

Hey Pusher,

I really value your folks products and am using your APNS service.

Recently, in release 1.2.1, I started seeing a crash after registering a device token. It seems to be happening when the preIIS operation queue is resumed after being suspended. Not sure why this would be happening.

Noticed an existing issue:

πŸ“Ž #71

Will that be applied to 1.2.1 other than the beta release?

Thread 38 Queue : com.pusher.pushnotifications.persistence.storage.operation.queue (serial)
#0	0x0000000109a8c0a0 in _dispatch_lane_resume ()
#1	0x0000000108067c00 in thunk for @escaping @callee_guaranteed () -> () ()
#2	0x0000000109a838a0 in _dispatch_call_block_and_release ()
#3	0x0000000109a84e38 in _dispatch_client_callout ()
#4	0x0000000109a8d128 in _dispatch_lane_serial_drain ()
#5	0x0000000109a8de3c in _dispatch_lane_invoke ()
#6	0x0000000109a97b30 in _dispatch_workloop_worker_thread ()
#7	0x00000002092c2b20 in _pthread_wqthread ()
#8	0x00000002092c8dd4 in start_wqthread ()
Enqueued from  (Thread 51) Queue :  (serial)
#0	0x0000000109ab9fe4 in _dispatch_introspection_queue_item_enqueue_hook ()
#1	0x0000000109a89d4c in dispatch_async ()
#2	0x00000001094f3008 in OS_dispatch_queue.async(group:qos:flags:execute:) ()
#3	0x000000010807200c in closure #1 in PushNotifications.registerDeviceToken(_:completion:) at /Pods/PushNotifications/Sources/PushNotifications.swift:236
#4	0x0000000108064d94 in closure #1 in NetworkService.register(url:deviceToken:instanceId:completion:) at /Pods/PushNotifications/Sources/NetworkService.swift:30
#5	0x0000000108067a38 in closure #1 in networkRequestWithExponentialBackoff #1 (numberOfAttempts:) in closure #1 in NetworkService.networkRequest(_:session:completion:) at /Pods/PushNotifications/Sources/NetworkService.swift:185
#6	0x00000001080685c0 in partial apply for closure #1 in networkRequestWithExponentialBackoff #1 (numberOfAttempts:) in closure #1 in NetworkService.networkRequest(_:session:completion:) ()
#7	0x000000010804e064 in thunk for @escaping @callee_guaranteed (@guaranteed Data?, @guaranteed NSURLResponse?, @guaranteed Error?) -> () ()
#8	0x0000000209ca107c in __75-[__NSURLSessionLocal taskForClass:request:uploadFile:bodyData:completion:]_block_invoke ()
#9	0x0000000209cb6528 in __49-[__NSCFLocalSessionTask _task_onqueue_didFinish]_block_invoke ()
#10	0x000000020a160da4 in __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ ()
#11	0x000000020a062158 in -[NSBlockOperation main] ()
#12	0x000000020a0615d8 in -[__NSOperationInternal _start:] ()
#13	0x000000020a162cdc in __NSOQSchedule_f ()
#14	0x0000000109a838a0 in _dispatch_call_block_and_release ()
#15	0x0000000109a84e38 in _dispatch_client_callout ()
#16	0x0000000109a8838c in _dispatch_continuation_pop ()
#17	0x0000000109a87758 in _dispatch_async_redirect_invoke ()
#18	0x0000000109a96110 in _dispatch_root_queue_drain ()
#19	0x0000000109a96b04 in _dispatch_worker_thread2 ()
#20	0x00000002092c2bc0 in _pthread_wqthread ()
#21	0x00000002092c8dd4 in start_wqthread ()
Enqueued from com.apple.NSURLSession-work (Thread 38) Queue : com.apple.NSURLSession-work (serial)
#0	0x0000000109ab9fe4 in _dispatch_introspection_queue_item_enqueue_hook ()
#1	0x0000000109a89d4c in dispatch_async ()
#2	0x000000020a160484 in __NSOQSchedule ()
#3	0x000000020a1619f4 in __addOperations ()
#4	0x0000000209c76b7c in -[__NSCFLocalSessionTask _task_onqueue_didFinish] ()
#5	0x0000000209c7ed00 in -[__NSCFLocalSessionTask _onqueue_submitConnectionWork:] ()
#6	0x0000000209c767b8 in -[__NSCFLocalSessionTask connection:didFinishLoadingWithError:] ()
#7	0x0000000209d3237c in __51-[__NSCFURLLocalSessionConnection _task_sendFinish]_block_invoke ()
#8	0x0000000209c825ac in -[__NSCFURLLocalSessionConnection withDelegateAndPendingCompletion:] ()
#9	0x0000000209c75c28 in -[__NSCFURLLocalSessionConnection _task_sendFinish] ()
#10	0x0000000109a93068 in _dispatch_block_async_invoke2 ()
#11	0x0000000109a84e38 in _dispatch_client_callout ()
#12	0x0000000109a8d128 in _dispatch_lane_serial_drain ()
#13	0x0000000109a8de3c in _dispatch_lane_invoke ()
#14	0x0000000109a97b30 in _dispatch_workloop_worker_thread ()
#15	0x00000002092c2b20 in _pthread_wqthread ()
#16	0x00000002092c8dd4 in start_wqthread ()
Enqueued from com.apple.NSURLSession-work (Thread 38) Queue : com.apple.NSURLSession-work (serial)
#0	0x0000000109ab9fe4 in _dispatch_introspection_queue_item_enqueue_hook ()
#1	0x0000000109a89d4c in dispatch_async ()
#2	0x0000000209c71dd4 in -[__NSCFURLSessionConnection withWorkQueueAsync:] ()
#3	0x0000000209c727f8 in -[__NSCFURLLocalSessionConnection afterDelegateWithTick:] ()
#4	0x0000000209d32520 in __50-[__NSCFURLLocalSessionConnection _tick_finishing]_block_invoke_2 ()
#5	0x0000000209c87314 in -[__NSCFLocalSessionTask _onqueue_willCacheResponse:withCompletion:] ()
#6	0x0000000209c7ed00 in -[__NSCFLocalSessionTask _onqueue_submitConnectionWork:] ()
#7	0x0000000209c81ff4 in -[__NSCFLocalSessionTask connection:willCacheResponse:responseCallback:] ()
#8	0x0000000209d324a4 in __50-[__NSCFURLLocalSessionConnection _tick_finishing]_block_invoke ()
#9	0x0000000209c825ac in -[__NSCFURLLocalSessionConnection withDelegateAndPendingCompletion:] ()
#10	0x0000000209c77ea8 in -[__NSCFURLLocalSessionConnection _tick_finishing] ()
#11	0x0000000109a93068 in _dispatch_block_async_invoke2 ()
#12	0x0000000109a84e38 in _dispatch_client_callout ()
#13	0x0000000109a8d128 in _dispatch_lane_serial_drain ()
#14	0x0000000109a8de3c in _dispatch_lane_invoke ()
#15	0x0000000109a97b30 in _dispatch_workloop_worker_thread ()
#16	0x00000002092c2b20 in _pthread_wqthread ()
#17	0x00000002092c8dd4 in start_wqthread ()
Enqueued from com.apple.NSURLSession-work (Thread 38) Queue : com.apple.NSURLSession-work (serial)
#0	0x0000000109ab9fe4 in _dispatch_introspection_queue_item_enqueue_hook ()
#1	0x0000000109a89d4c in dispatch_async ()
#2	0x0000000209c71dd4 in -[__NSCFURLSessionConnection withWorkQueueAsync:] ()
#3	0x0000000209c727f8 in -[__NSCFURLLocalSessionConnection afterDelegateWithTick:] ()
#4	0x0000000209d3211c in __48-[__NSCFURLLocalSessionConnection _tick_running]_block_invoke_2 ()
#5	0x0000000209c71a58 in -[__NSCFLocalSessionTask _task_onqueue_didReceiveDispatchData:completionHandler:] ()
#6	0x0000000209c7ed00 in -[__NSCFLocalSessionTask _onqueue_submitConnectionWork:] ()
#7	0x0000000209c716c8 in -[__NSCFLocalSessionTask connection:didReceiveData:completion:] ()
#8	0x0000000209d32054 in __48-[__NSCFURLLocalSessionConnection _tick_running]_block_invoke ()
#9	0x0000000209c825ac in -[__NSCFURLLocalSessionConnection withDelegateAndPendingCompletion:] ()
#10	0x0000000209c71424 in -[__NSCFURLLocalSessionConnection _tick_running] ()
#11	0x0000000109a93068 in _dispatch_block_async_invoke2 ()
#12	0x0000000109a84e38 in _dispatch_client_callout ()
#13	0x0000000109a8d128 in _dispatch_lane_serial_drain ()
#14	0x0000000109a8de3c in _dispatch_lane_invoke ()
#15	0x0000000109a97b30 in _dispatch_workloop_worker_thread ()
#16	0x00000002092c2b20 in _pthread_wqthread ()
#17	0x00000002092c8dd4 in start_wqthread ()
Enqueued from com.apple.NSURLSession-work (Thread 38) Queue : com.apple.NSURLSession-work (serial)
#0	0x0000000109ab9fe4 in _dispatch_introspection_queue_item_enqueue_hook ()
#1	0x0000000109a89d4c in dispatch_async ()
#2	0x0000000209c71dd4 in -[__NSCFURLSessionConnection withWorkQueueAsync:] ()
#3	0x0000000209c727f8 in -[__NSCFURLLocalSessionConnection afterDelegateWithTick:] ()
#4	0x0000000209d328c4 in __61-[__NSCFURLLocalSessionConnection _didReceiveResponse:sniff:]_block_invoke_2 ()
#5	0x0000000209cb784c in __67-[__NSCFLocalSessionTask connection:didReceiveResponse:completion:]_block_invoke_2 ()
#6	0x0000000209c75a18 in -[__NSCFLocalDataTask _onqueue_didReceiveResponse:completion:] ()
#7	0x0000000209cb77ec in __67-[__NSCFLocalSessionTask connection:didReceiveResponse:completion:]_block_invoke ()
#8	0x0000000209c7ed00 in -[__NSCFLocalSessionTask _onqueue_submitConnectionWork:] ()
#9	0x0000000209c755a8 in -[__NSCFLocalSessionTask connection:didReceiveResponse:completion:] ()
#10	0x0000000209d32800 in __61-[__NSCFURLLocalSessionConnection _didReceiveResponse:sniff:]_block_invoke ()
#11	0x0000000209c825ac in -[__NSCFURLLocalSessionConnection withDelegateAndPendingCompletion:] ()
#12	0x0000000209c74c34 in -[__NSCFURLLocalSessionConnection _didReceiveResponse:sniff:] ()
#13	0x0000000209c79ff0 in -[__NSCFURLLocalSessionConnection _tick_sniffNow] ()
#14	0x0000000209c825ac in -[__NSCFURLLocalSessionConnection withDelegateAndPendingCompletion:] ()
#15	0x0000000209c77604 in -[__NSCFURLLocalSessionConnection _didFinishWithError:] ()
#16	0x0000000209e0d718 in ___ZN19URLConnectionLoader24protocolDidFinishLoadingEv_block_invoke_5 ()
#17	0x0000000209d35a18 in ___ZN25SessionConnectionLoadable21withLoaderClientAsyncEU13block_pointerFvP21LoaderClientInterfaceE_block_invoke ()
#18	0x0000000109a93068 in _dispatch_block_async_invoke2 ()
#19	0x0000000109a84e38 in _dispatch_client_callout ()
#20	0x0000000109a8d128 in _dispatch_lane_serial_drain ()
#21	0x0000000109a8de3c in _dispatch_lane_invoke ()
#22	0x0000000109a97b30 in _dispatch_workloop_worker_thread ()
#23	0x00000002092c2b20 in _pthread_wqthread ()
#24	0x00000002092c8dd4 in start_wqthread ()
Enqueued from com.apple.NSURLSession-work (Thread 38) Queue : com.apple.NSURLSession-work (serial)
#0	0x0000000109ab9fe4 in _dispatch_introspection_queue_item_enqueue_hook ()
#1	0x0000000109a89d4c in dispatch_async ()
#2	0x0000000209c71dd4 in -[__NSCFURLSessionConnection withWorkQueueAsync:] ()
#3	0x0000000209d35044 in SessionConnectionLoadable::withLoaderClientAsync(void (LoaderClientInterface*) block_pointer) ()
#4	0x0000000209e0d424 in URLConnectionLoader::protocolDidFinishLoading() ()
#5	0x0000000209dfd078 in ___ZNK25URLConnectionInstanceData18withWorkQueueAsyncEU13block_pointerFvvE_block_invoke ()
#6	0x0000000109a838a0 in _dispatch_call_block_and_release ()
#7	0x0000000109a84e38 in _dispatch_client_callout ()
#8	0x0000000109a8d128 in _dispatch_lane_serial_drain ()
#9	0x0000000109a8de3c in _dispatch_lane_invoke ()
#10	0x0000000109a97b30 in _dispatch_workloop_worker_thread ()
#11	0x00000002092c2b20 in _pthread_wqthread ()
#12	0x00000002092c8dd4 in start_wqthread ()
Enqueued from com.apple.CFNetwork.Connection (Thread 51) Queue : com.apple.CFNetwork.Connection (serial)
#0	0x0000000109ab9fe4 in _dispatch_introspection_queue_item_enqueue_hook ()
#1	0x0000000109a89d4c in dispatch_async ()
#2	0x0000000209dfd040 in URLConnectionInstanceData::withWorkQueueAsync(void () block_pointer) const ()
#3	0x0000000209e115ec in non-virtual thunk to URLConnectionLoader_Classic::protocolDidFinishLoading() ()
#4	0x0000000209cf6494 in ___ZN11URLProtocol20sendDidFinishLoadingEv_block_invoke_2 ()
#5	0x0000000209cf5dac in URLProtocol::sendDidFinishLoading() ()
#6	0x0000000209db4ff8 in HTTPProtocol::endEncountered() ()
#7	0x0000000209db4680 in HTTPProtocol::handleStreamEvent(__CFHTTPMessage*, dispatch_data_s*, CFStreamError const*) ()
#8	0x0000000209ec5b30 in HTTPTransaction::_onqueue_invokeHandler() ()
#9	0x0000000209e54f64 in HTTPConnection::_onqueue_responseDataArrived(dispatch_data_s*, CFStreamError, bool) ()
#10	0x0000000209ebc380 in HTTPEngine::_readBodyFinish(dispatch_data_s*, CFStreamError, bool) ()
#11	0x0000000209ebcaf4 in HTTPEngine::_deliverBodyBytes(dispatch_data_s*, CFStreamError, bool) ()
#12	0x0000000209ebc740 in HTTPEngine::_getBodyIntelligently(void (dispatch_data_s*, CFStreamError, bool) block_pointer) ()
#13	0x0000000209eba478 in HTTPEngine::_readBodyStartNextRead() ()
#14	0x0000000209ebcb8c in HTTPEngine::_deliverBodyBytes(dispatch_data_s*, CFStreamError, bool) ()
#15	0x0000000209ebd454 in ___ZN10HTTPEngine21_getBodyIntelligentlyEU13block_pointerFvP15dispatch_data_s13CFStreamErrorbE_block_invoke ()
#16	0x0000000209ebd550 in ___ZN10HTTPEngine21_getBodyIntelligentlyEU13block_pointerFvP15dispatch_data_s13CFStreamErrorbE_block_invoke.56 ()
#17	0x0000000109a838a0 in _dispatch_call_block_and_release ()
#18	0x0000000109a84e38 in _dispatch_client_callout ()
#19	0x0000000109a8d128 in _dispatch_lane_serial_drain ()
#20	0x0000000109a8de78 in _dispatch_lane_invoke ()
#21	0x0000000109a8f304 in _dispatch_workloop_invoke2 ()
#22	0x0000000109a8ec84 in _dispatch_workloop_invoke ()
#23	0x0000000109a97b30 in _dispatch_workloop_worker_thread ()
#24	0x00000002092c2b20 in _pthread_wqthread ()
#25	0x00000002092c8dd4 in start_wqthread ()
Enqueued from com.apple.network.connections (Thread 51) Queue : com.apple.network.connections (serial)
#0	0x0000000109ab9fe4 in _dispatch_introspection_queue_item_enqueue_hook ()
#1	0x0000000109a89d4c in dispatch_async ()
#2	0x0000000209ebc990 in HTTPEngine::_getBodyIntelligently(void (dispatch_data_s*, CFStreamError, bool) block_pointer) ()
#3	0x0000000209eba478 in HTTPEngine::_readBodyStartNextRead() ()
#4	0x0000000209eb9f00 in HTTPEngine::_readHeadersFinish(CFStreamError) ()
#5	0x0000000209ebbad8 in HTTPEngine::_readHeadersDoParse(CFStreamError) ()
#6	0x0000000209ebd294 in ___ZN10HTTPEngine9_readBlobEmU13block_pointerFv13CFStreamErrorE_block_invoke ()
#7	0x0000000209e369a0 in TCPIOConnection::readCompleted(unsigned long, unsigned long, dispatch_data_s*, int, void (dispatch_data_s*, CFStreamError) block_pointer) ()
#8	0x0000000209ed2a9c in ConnectionProtocolReadInner(nw_protocol*, unsigned int, unsigned int, bool, long long, void (dispatch_data_s*, CFStreamError) block_pointer, void (nw_frame_array_s*, CFStreamError) block_pointer) ()
#9	0x0000000209ed25ec in ConnectionProtocolServiceReads(nw_protocol*) ()
#10	0x0000000209ed3510 in ConnectionProtocolInputAvailable(nw_protocol*, nw_protocol*) ()
#11	0x000000020a5683e8 in nw_boringssl_read ()
#12	0x000000020a569bfc in nw_protocol_boringssl_input_available ()
#13	0x000000020aa1470c in nw_protocol_tcp_wake_read ()
#14	0x000000020aa1a510 in nw_protocol_tcp_input_flush ()
#15	0x000000020a717f60 in nw_protocol_default_input_flush ()
#16	0x000000020a79da30 in nw_channel_add_input_frames ()
#17	0x000000020a79c970 in nw_channel_update_input_source ()
#18	0x000000020a79c1e8 in __nw_channel_create_block_invoke.21 ()
#19	0x0000000109a84e38 in _dispatch_client_callout ()
#20	0x0000000109a8838c in _dispatch_continuation_pop ()
#21	0x0000000109a9aeec in _dispatch_source_invoke2 ()
#22	0x0000000109a9a69c in _dispatch_source_invoke ()
#23	0x0000000109a8f304 in _dispatch_workloop_invoke2 ()
#24	0x0000000109a8ec84 in _dispatch_workloop_invoke ()
#25	0x0000000109a97b30 in _dispatch_workloop_worker_thread ()
#26	0x00000002092c2b20 in _pthread_wqthread ()
#27	0x00000002092c8dd4 in start_wqthread ()

Notifications not arriving

I've set up everything on my backend and my iOS app and was able to send notifications to both users and interest groups.
In my iOS app, I run .start, .addDeviceInterest, .registerForRemoteNotifications and .registerDeviceToken.

However, today, it stopped working on my iPad. It is still working on my iPhone – with the exact same build. (And yes, I have allowed notifications for the app on my iPad.)

When sending a test notification from the dashboard (or through my backend), I see the log for the notification (w/ publish-id) confirming it was sent successfully. The logs also show my device being authenticated. Still, no notification arrives.

Bildschirmfoto 2020-02-17 um 14 21 51

I have:

  • created & added development & production certificates for my app for push notifications
  • restarted Xcode and my iDevice
  • deleted & reinstalled the iOS app
  • updated push-notifications-swift to 3.0.4

What can I do?

Cannot change `content-available` to 0/false

I would like to change the value of content-available in the notification payload. When I try to do so by simply adding "content-available" => 0 inside the "aps" dict, right next to "alert" in my PHP backend, I get the following error:

Unprocessable Entity: apns.aps.content-available: apns.aps.content-available must be one of the following: 1

How can I set it to 0 / false?

Swift 5 compatability

I am getting a Command CompileSwift failed with a non zero exit code on version 2.0.1 when attempting to compile on Swift 5. The StarScream dependency is also failing with the same error. It looks like PushNotifications is pulling in version Starscream (3.0.6). It looks like Swift 5 compatibility was introduced in Starscream 3.1.0.

iOS10 minimum deployment target

Hey, I have a project that supports back to iOS9.

How can I use pusher push notifications with this project without updating my projects minimum deployment target?

Swift Package Manager integration improvements

There are some improvements that can be made to Package.swift for users integrating using SPM.

  • Add a test target for PushNotificationsTests (to mirror the .xcodeproj file set up).
    • Update Nimble dependency from 8.0.1 -> 8.1.2 (I.e. the latest v8.x release).
    • Update OHHTTPStubs dependency from 7.0.0 -> 9.0.0 (Upgrade needed in order to integrate via SPM).
    • Update Cartfile.resolved to match updated dependency versions.

Use of unresolved identifier 'Instance'

I just installed it as in the README but I get this Use of unresolved identifier 'Instance'
in the @objc public final class PushNotifications: NSObject

I use latest xcode 9 with swift 4 for and iOs app

Completion handler never called in `clearAllState(completion:)`

I'm calling clearAllState upon user logging out, as recommended in the docs. I've noticed that the completion handler is not being called, which at least in my current implementation results in the log-out process hanging, since it never continues past the step where I clear all Pusher state.

Is it expected that the clearAllState completion handler will sometimes (or every time in my case) not get called?

If so it would be great to call that out in the documentation so that folks don't get tripped up on this in the future like I did.

How to unregisterForRemoteNotifications ?

Hi pusher team,

In the user guide, it describes the procedure of setup Pusher, and use the client API to register to receive remote notifications via APN.

PushNotifications.shared.registerForRemoteNotifications()

But, how do I unregister the service? Is there a way to do this via the Pusher API?
My case is that a few devices failed to receive notifications after restoring a backup image to another phone. I think the solution is to unregister the service and register again.

Crash on addDeviceInterest

We are getting a decent amount of crashes on calling addDeviceInterest.

I see in PushNotificationsStatic on line 196 you have this code:
fatalError("PushNotifications.shared.start must have been called first")

Why must you use fatalError? It looks like there is an edge case where we accidentally call addDeviceInterest without calling start. Couldn't this just be ignored if start isn't called?

Device could not be created

Hi,

We released an iOS app recently and are facing some issues to log in with Pusher Beams authenticated users.

Here is the process we apply when a user log into our application successfully:

  • call the 'stop()' method on the SDK to potentially un subscribe a paste user that was logged in
  • call our backend to get an authentication token. At this time, our backend is also deleting any Pusher user that has used the same device just to make sure that only the last logged user register on Pusher for that device.
  • call the 'start()' method to start the pusher beams sdk
  • call the 'setUserId()' method to register this device with the current logged user

When a user explicitely log out our application, we don't do anything since we want that user to be able to receive notification on the mobile application.
That's also the reason why we do this 'stop()' call first after a login, to clear the pusher SDK local state if the new logged user is different than the previous one.

Time to time, some users get errors while doing the 'setUserId()' operation with the following message:

Device could not be created

I believe this is an error returned by the Pusher backend itself, not the SDK.

For one of these users, i have checked on our backend the devices it get, and try to send notifications to his device with the Pusher debug console, but not user nor device were found on Pusher for the given Pusher User ID.

What does this error message means ? What could be the potential reasons ?

Note: please confirm here whether this is more a server side pusher issue than an SDK one.

ThreadSanitizer error during start on Mac Catalyst

I'm getting the following when trying to run my app using Mac Catalyst. That should be a supported platform, right? Let me know if/how I can help you reproduce this on your end. Thanks!

WARNING: ThreadSanitizer: Swift access race (pid=59308)
  Modifying access of Swift variable at 0x000119e14878 by thread T13:
    #0 PushNotifications.ServerSyncProcessHandler.jobQueue.modify : PushNotifications.ServerSyncJobStore <null> (PushNotifications:arm64+0x65394)
    #1 PushNotifications.ServerSyncProcessHandler.handleMessage(serverSyncJob: PushNotifications.ServerSyncJob) -> () <null> (PushNotifications:arm64+0x6e010)
    #2 closure #1 () -> () in closure #1 () -> () in PushNotifications.ServerSyncProcessHandler.sendMessage(serverSyncJob: PushNotifications.ServerSyncJob) -> () <null> (PushNotifications:arm64+0x66b04)
    #3 partial apply forwarder for closure #1 () -> () in closure #1 () -> () in PushNotifications.ServerSyncProcessHandler.sendMessage(serverSyncJob: PushNotifications.ServerSyncJob) -> () <null> (PushNotifications:arm64+0x6e9d0)
    #4 reabstraction thunk helper from @escaping @callee_guaranteed () -> () to @escaping @callee_unowned @convention(block) () -> () <null> (PushNotifications:arm64+0x410b8)
    #5 __tsan::invoke_and_release_block(void*) <null> (libclang_rt.tsan_osx_dynamic.dylib:arm64e+0x83c88)
    #6 _dispatch_client_callout <null> (libdispatch.dylib:arm64e+0x63a4)

  Previous modifying access of Swift variable at 0x000119e14878 by thread T1:
    #0 closure #1 () -> () in PushNotifications.ServerSyncJobStore.append(PushNotifications.ServerSyncJob) -> () <null> (PushNotifications:arm64+0x61d48)
    #1 partial apply forwarder for closure #1 () -> () in PushNotifications.ServerSyncJobStore.append(PushNotifications.ServerSyncJob) -> () <null> (PushNotifications:arm64+0x61f78)
    #2 reabstraction thunk helper from @callee_guaranteed () -> () to @escaping @callee_guaranteed () -> () <null> (PushNotifications:arm64+0xd430)
    #3 partial apply forwarder for reabstraction thunk helper from @callee_guaranteed () -> () to @escaping @callee_guaranteed () -> () <null> (PushNotifications:arm64+0x61ffc)
    #4 reabstraction thunk helper from @escaping @callee_guaranteed () -> () to @callee_unowned @convention(block) () -> () <null> (PushNotifications:arm64+0xd530)
    #5 __tsan::dispatch_callback_wrap(void*) <null> (libclang_rt.tsan_osx_dynamic.dylib:arm64e+0x83ac8)
    #6 _dispatch_client_callout <null> (libdispatch.dylib:arm64e+0x63a4)
    #7 PushNotifications.ServerSyncJobStore.append(PushNotifications.ServerSyncJob) -> () <null> (PushNotifications:arm64+0x61c4c)
    #8 closure #1 () -> () in PushNotifications.ServerSyncProcessHandler.sendMessage(serverSyncJob: PushNotifications.ServerSyncJob) -> () <null> (PushNotifications:arm64+0x66658)
    #9 partial apply forwarder for closure #1 () -> () in PushNotifications.ServerSyncProcessHandler.sendMessage(serverSyncJob: PushNotifications.ServerSyncJob) -> () <null> (PushNotifications:arm64+0x669bc)
    #10 reabstraction thunk helper from @escaping @callee_guaranteed () -> () to @escaping @callee_unowned @convention(block) () -> () <null> (PushNotifications:arm64+0x410b8)
    #11 __tsan::invoke_and_release_block(void*) <null> (libclang_rt.tsan_osx_dynamic.dylib:arm64e+0x83c88)
    #12 _dispatch_client_callout <null> (libdispatch.dylib:arm64e+0x63a4)

  Location is heap block of size 152 at 0x000119e14820 allocated by main thread:
    #0 __sanitizer_mz_malloc <null> (libclang_rt.tsan_osx_dynamic.dylib:arm64e+0x5c29c)
    #1 _malloc_zone_malloc <null> (libsystem_malloc.dylib:arm64e+0x1e744)
    #2 closure #1 () -> PushNotifications.ServerSyncProcessHandler in static PushNotifications.ServerSyncProcessHandler.obtain(instanceId: Swift.String, getTokenProvider: () -> Swift.Optional<PushNotifications.TokenProvider>, handleServerSyncEvent: (PushNotifications.ServerSyncEvent) -> ()) -> PushNotifications.ServerSyncProcessHandler <null> (PushNotifications:arm64+0x6479c)
    #3 partial apply forwarder for closure #1 () -> PushNotifications.ServerSyncProcessHandler in static PushNotifications.ServerSyncProcessHandler.obtain(instanceId: Swift.String, getTokenProvider: () -> Swift.Optional<PushNotifications.TokenProvider>, handleServerSyncEvent: (PushNotifications.ServerSyncEvent) -> ()) -> PushNotifications.ServerSyncProcessHandler <null> (PushNotifications:arm64+0x64920)
    #4 partial apply forwarder for reabstraction thunk helper <A> from @callee_guaranteed () -> (@out A, @error @owned Swift.Error) to @escaping @callee_guaranteed () -> (@out A, @error @owned Swift.Error) <null> (libswiftDispatch.dylib:arm64e+0x87d8)
    #5 _dispatch_client_callout <null> (libdispatch.dylib:arm64e+0x63a4)
    #6 merged implicit closure #2 (() -> ()) -> () in implicit closure #1 (__C.OS_dispatch_queue) -> (() -> ()) -> () in (extension in Dispatch):__C.OS_dispatch_queue.sync<A>(execute: () throws -> A) throws -> A <null> (libswiftDispatch.dylib:arm64e+0x7718)
    #7 PushNotifications.PushNotifications.(serverSyncHandler in _CB215BC71E849523257B7B88AB6306E9).getter : PushNotifications.ServerSyncProcessHandler <null> (PushNotifications:arm64+0x370e4)
    #8 PushNotifications.PushNotifications.start() -> () <null> (PushNotifications:arm64+0x37b84)
    #9 static PushNotifications.PushNotificationsStatic.start(instanceId: Swift.String) -> () <null> (PushNotifications:arm64+0x403f8)
    #10 MyApp.Notifications.configure() -> () <null> (MyApp:arm64+0x1005d4914)
    #11 MyApp.AppDelegate.application(_: __C.UIApplication, didFinishLaunchingWithOptions: Swift.Optional<Swift.Dictionary<__C.UIApplicationLaunchOptionsKey, Any>>) -> Swift.Bool <null> (MyApp:arm64+0x1004ebe0c)
    #12 @objc MyApp.AppDelegate.application(_: __C.UIApplication, didFinishLaunchingWithOptions: Swift.Optional<Swift.Dictionary<__C.UIApplicationLaunchOptionsKey, Any>>) -> Swift.Bool <null> (MyApp:arm64+0x1004ecc38)
    #13 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] <null> (UIKitCore:arm64e+0x35084)
    #14 <null> <null> (dyld:arm64e+0x5088)

  Thread T13 (tid=26893343, running) is a GCD worker thread

  Thread T1 (tid=26893287, running) is a GCD worker thread

SUMMARY: ThreadSanitizer: Swift access race (/Users/[...]/Library/Developer/Xcode/DerivedData/[...]/Build/Products/Debug-maccatalyst/MyApp.app/Contents/Frameworks/PushNotifications.framework/Versions/A/PushNotifications:arm64+0x65394) in PushNotifications.ServerSyncProcessHandler.jobQueue.modify : PushNotifications.ServerSyncJobStore+0x50

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.