├── .github
├── ISSUE_TEMPLATE
│ ├── ask-question.yml
│ ├── bug-report.yml
│ └── general-feedback.yml
├── os_probot_metadata.js
├── pull_request_template.md
├── release-drafter.yml
├── set_response_times.js
└── workflows
│ ├── Zapier.yml
│ ├── ci.yml
│ ├── project.yml
│ ├── release-drafter.yml
│ └── set_response_time.yml
├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── MIGRATION_GUIDE.md
├── README.md
├── android
├── .gitignore
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── com
│ └── onesignal
│ └── flutter
│ ├── FlutterMessengerResponder.java
│ ├── OneSignalDebug.java
│ ├── OneSignalInAppMessages.java
│ ├── OneSignalLocation.java
│ ├── OneSignalNotifications.java
│ ├── OneSignalPlugin.java
│ ├── OneSignalPushSubscription.java
│ ├── OneSignalSerializer.java
│ ├── OneSignalSession.java
│ └── OneSignalUser.java
├── example
├── .gitignore
├── .metadata
├── README.md
├── android
│ ├── .gitignore
│ ├── app
│ │ ├── build.gradle
│ │ └── src
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── onesignal
│ │ │ │ └── onesignalexample
│ │ │ │ └── MainActivity.java
│ │ │ └── res
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ └── values
│ │ │ └── styles.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── ios
│ ├── .gitignore
│ ├── ExampleWidget
│ │ ├── Assets.xcassets
│ │ │ ├── AccentColor.colorset
│ │ │ │ └── Contents.json
│ │ │ ├── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ │ ├── Contents.json
│ │ │ ├── WidgetBackground.colorset
│ │ │ │ └── Contents.json
│ │ │ └── onesignaldemo.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ └── onesignal-logo.png
│ │ ├── ExampleWidgetBundle.swift
│ │ ├── ExampleWidgetLiveActivity.swift
│ │ └── Info.plist
│ ├── Flutter
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ ├── Flutter.podspec
│ │ └── Release.xcconfig
│ ├── OneSignalNotificationServiceExtension
│ │ ├── Info.plist
│ │ ├── NotificationService.h
│ │ ├── NotificationService.m
│ │ └── OneSignalNotificationServiceExtension.entitlements
│ ├── Podfile
│ ├── Podfile.lock
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── Runner
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ └── Icon-App-83.5x83.5@2x.png
│ │ └── LaunchImage.imageset
│ │ │ ├── Contents.json
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ └── README.md
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ ├── Runner.entitlements
│ │ └── main.m
├── lib
│ └── main.dart
└── pubspec.yaml
├── ios
├── .gitignore
├── Assets
│ └── .gitkeep
├── Classes
│ ├── OSFlutterCategories.h
│ ├── OSFlutterCategories.m
│ ├── OSFlutterDebug.h
│ ├── OSFlutterDebug.m
│ ├── OSFlutterInAppMessages.h
│ ├── OSFlutterInAppMessages.m
│ ├── OSFlutterLiveActivities.h
│ ├── OSFlutterLiveActivities.m
│ ├── OSFlutterLocation.h
│ ├── OSFlutterLocation.m
│ ├── OSFlutterNotifications.h
│ ├── OSFlutterNotifications.m
│ ├── OSFlutterPushSubscription.h
│ ├── OSFlutterPushSubscription.m
│ ├── OSFlutterSession.h
│ ├── OSFlutterSession.m
│ ├── OSFlutterUser.h
│ ├── OSFlutterUser.m
│ ├── OneSignalPlugin.h
│ └── OneSignalPlugin.m
└── onesignal_flutter.podspec
├── lib
├── onesignal_flutter.dart
└── src
│ ├── debug.dart
│ ├── defines.dart
│ ├── inappmessage.dart
│ ├── inappmessages.dart
│ ├── liveactivities.dart
│ ├── location.dart
│ ├── notification.dart
│ ├── notifications.dart
│ ├── permission.dart
│ ├── pushsubscription.dart
│ ├── session.dart
│ ├── subscription.dart
│ ├── user.dart
│ └── utils.dart
├── pubspec.yaml
├── test.json
└── test
├── mock_channel.dart
└── onesignalflutter_test.dart
/.github/ISSUE_TEMPLATE/ask-question.yml:
--------------------------------------------------------------------------------
1 | name: 🙋♂️ Ask a question
2 | description: Tell us what's on your mind
3 | title: "[question]: "
4 | labels: ["Question"]
5 |
6 | body:
7 | - type: markdown
8 | attributes:
9 | value: |
10 | Having issues integrating this SDK?
11 | - type: textarea
12 | id: question
13 | attributes:
14 | label: How can we help?
15 | description: Specific question regarding integrating this SDK.
16 | placeholder: How do I...?
17 | validations:
18 | required: true
19 | - type: checkboxes
20 | id: terms
21 | attributes:
22 | label: Code of Conduct
23 | description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/OneSignal/OneSignal-Flutter-SDK/blob/main/CONTRIBUTING.md)
24 | options:
25 | - label: I agree to follow this project's Code of Conduct
26 | required: true
27 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug-report.yml:
--------------------------------------------------------------------------------
1 | name: 🪳 Bug report
2 | description: File a bug report
3 | title: "[Bug]: "
4 | labels: ["Bug"]
5 |
6 | body:
7 | - type: markdown
8 | attributes:
9 | value: |
10 | Thanks for taking the time to fill out this bug report!
11 | - type: textarea
12 | id: what-happened
13 | attributes:
14 | label: What happened?
15 | description: Provide a thorough description of whats going on.
16 | placeholder: e.g. The latest version of the SDK causes my screen to go blank when I tap on the screen three times.
17 | validations:
18 | required: true
19 | - type: textarea
20 | id: reproduction-steps
21 | attributes:
22 | label: Steps to reproduce?
23 | description: Provide as much detail as posible to reproduce the issue.
24 | placeholder: |
25 | 1. Install vX.Y.Z of dependency
26 | 2. Launch the app on iOS device
27 | 3. Tap the screen three times
28 | 4. Note that the app crashes
29 | render: Markdown
30 | validations:
31 | required: true
32 | - type: textarea
33 | id: what-are-expectations
34 | attributes:
35 | label: What did you expect to happen?
36 | description: Also tell us, what did you expect to happen?
37 | placeholder: I expected the app to continue running no matter how many times I tap the screen.
38 | validations:
39 | required: true
40 | - type: input
41 | id: flutter-sdk-version
42 | attributes:
43 | label: OneSignal Flutter SDK version
44 | description: What version of the OneSignal Flutter SDK are you using?
45 | placeholder: Release 3.4.1
46 | validations:
47 | required: true
48 | - type: checkboxes
49 | id: platforms
50 | attributes:
51 | label: Which platform(s) are affected?
52 | description: Indicate which mobile platforms this issue is affecting
53 | options:
54 | - label: iOS
55 | required: false
56 | - label: Android
57 | required: false
58 | - type: textarea
59 | id: logs
60 | attributes:
61 | label: Relevant log output
62 | description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
63 | render: Shell
64 | - type: checkboxes
65 | id: terms
66 | attributes:
67 | label: Code of Conduct
68 | description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/OneSignal/OneSignal-Flutter-SDK/blob/main/CONTRIBUTING.md)
69 | options:
70 | - label: I agree to follow this project's Code of Conduct
71 | required: true
72 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/general-feedback.yml:
--------------------------------------------------------------------------------
1 | name: 📣 General feedback
2 | description: Tell us what's on your mind
3 | title: "[Feedback]: "
4 | labels: ["Feedback"]
5 |
6 | body:
7 | - type: markdown
8 | attributes:
9 | value: |
10 | Thanks for sharing your valuable feedback!
11 | - type: textarea
12 | id: feedback
13 | attributes:
14 | label: What's on your mind?
15 | description: Feedback regarding this SDK.
16 | placeholder: Share your feedback...
17 | validations:
18 | required: true
19 | - type: checkboxes
20 | id: terms
21 | attributes:
22 | label: Code of Conduct
23 | description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/OneSignal/OneSignal-Flutter-SDK/blob/main/CONTRIBUTING.md)
24 | options:
25 | - label: I agree to follow this project's Code of Conduct
26 | required: true
27 |
--------------------------------------------------------------------------------
/.github/os_probot_metadata.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Based on probot-metadata - https://github.com/probot/metadata
3 | */
4 | const regex = /\n\n/
5 |
6 | const { Octokit } = require("@octokit/action")
7 |
8 | const octokit = new Octokit()
9 |
10 | module.exports = (context, issue = null) => {
11 | console.log(context)
12 | const prefix = "onesignal-probot"
13 |
14 | if (!issue) issue = context.payload.issue
15 |
16 | return {
17 | async get (key = null) {
18 | let body = issue.body
19 |
20 | if (!body) {
21 | body = (await octokit.issues.get(issue)).data.body || ''
22 | }
23 |
24 | const match = body.match(regex)
25 |
26 | if (match) {
27 | const data = JSON.parse(match[1])[prefix]
28 | return key ? data && data[key] : data
29 | }
30 | },
31 |
32 | async set (key, value) {
33 | let body = issue.body
34 | let data = {}
35 |
36 | if (!body) body = (await octokit.issues.get(issue)).data.body || ''
37 |
38 | body = body.replace(regex, (_, json) => {
39 | data = JSON.parse(json)
40 | return ''
41 | })
42 |
43 | if (!data[prefix]) data[prefix] = {}
44 |
45 | if (typeof key === 'object') {
46 | Object.assign(data[prefix], key)
47 | } else {
48 | data[prefix][key] = value
49 | }
50 |
51 | body = `${body}\n\n`
52 |
53 | const [owner, repo] = process.env.GITHUB_REPOSITORY.split("/")
54 | const issue_number = context.payload.issue.number
55 | return octokit.issues.update({ owner, repo, issue_number, body })
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 |
2 | # READ AND DELETE THIS SECTION BEFORE SUBMITTING PR
3 | * **Fill out each _REQUIRED_ section**
4 | * **Fill out _OPTIONAL_ sections, remove section if it doesn't apply to your PR**
5 | * **Read and fill out each of the checklists below**
6 | * **Remove this section after reading**
7 |
8 |
9 | # Description
10 | ## One Line Summary
11 | **REQUIRED** - Very short description that summaries the changes in this PR.
12 |
13 | ## Details
14 |
15 | ### Motivation
16 | **REQUIRED -** Why is this code change being made? Or what is the goal of this PR? Examples: Fixes a specific bug, provides additional logging to debug future issues, feature to allow X.
17 |
18 | ### Scope
19 | **RECOMMEND - OPTIONAL -** What is intended to be effected. What is known not to change. Example: Notifications are grouped when parameter X is set, not enabled by default.
20 |
21 | ### OPTIONAL - Other
22 | **OPTIONAL -** Feel free to add any other sections or sub-sections that can explain your PR better.
23 |
24 | # Testing
25 | ## Unit testing
26 | **OPTIONAL -** Explain unit tests added, if not clear in the code.
27 |
28 | ## Manual testing
29 | **RECOMMEND - OPTIONAL -** Explain what scenarios were tested and the environment.
30 | Example: Tested opening a notification while the app was foregrounded, app build with Android Studio 2020.3 with a fresh install of the OneSignal example app on a Pixel 6 with Android 12.
31 |
32 | # Affected code checklist
33 | - [ ] Notifications
34 | - [ ] Display
35 | - [ ] Open
36 | - [ ] Push Processing
37 | - [ ] Confirm Deliveries
38 | - [ ] Outcomes
39 | - [ ] Sessions
40 | - [ ] In-App Messaging
41 | - [ ] REST API requests
42 | - [ ] Public API changes
43 |
44 | # Checklist
45 | ## Overview
46 | - [ ] I have filled out all **REQUIRED** sections above
47 | - [ ] PR does one thing
48 | - If it is hard to explain how any codes changes are related to each other then it most likely needs to be more than one PR
49 | - [ ] Any Public API changes are explained in the PR details and conform to existing APIs
50 |
51 | ## Testing
52 | - [ ] I have included test coverage for these changes, or explained why they are not needed
53 | - [ ] All automated tests pass, or I explained why that is not possible
54 | - [ ] I have personally tested this on my device, or explained why that is not possible
55 |
56 | ## Final pass
57 | - [ ] Code is as readable as possible.
58 | - Simplify with less code, followed by splitting up code into well named functions and variables, followed by adding comments to the code.
59 | - [ ] I have reviewed this PR myself, ensuring it meets each checklist item
60 | - WIP (Work In Progress) is ok, but explain what is still in progress and what you would like feedback on. Start the PR title with "WIP" to indicate this.
--------------------------------------------------------------------------------
/.github/release-drafter.yml:
--------------------------------------------------------------------------------
1 | name-template: $RESOLVED_VERSION
2 | tag-template: $RESOLVED_VERSION
3 | categories:
4 | - title: 🚀 Features
5 | label: Enhancement / Feature
6 | - title: 🐛 Bug Fixes
7 | label: Bug
8 | - title: 🧰 Improvements
9 | label: Improvement
10 | - title: down arrow Dependency Updates
11 | label: Dependencies
12 | change-template: '- $TITLE (#$NUMBER)'
13 | version-resolver:
14 | major:
15 | labels:
16 | - 'major'
17 | minor:
18 | labels:
19 | - 'minor'
20 | patch:
21 | labels:
22 | - 'patch'
23 | default: patch
24 | template: |
25 | ## Other Changes
26 |
27 | $CHANGES
28 |
--------------------------------------------------------------------------------
/.github/set_response_times.js:
--------------------------------------------------------------------------------
1 | function calcResponseTimeForIssueCreatedAt(createdAt) {
2 | const issueOpenedDate = new Date(createdAt);
3 | const issueTriagedDate = new Date();
4 | const businessDaysResponseTime = calcBusinessDaysBetweenDates(issueOpenedDate, issueTriagedDate);
5 | return businessDaysResponseTime;
6 | }
7 |
8 | function calcBusinessDaysBetweenDates(openedDate, triagedDate) {
9 | let differenceInWeeks, responseTime;
10 | if (triagedDate < openedDate)
11 | return -1; // error code if dates transposed
12 | let openedDay = openedDate.getDay(); // day of week
13 | let triagedDay = triagedDate.getDay();
14 | openedDay = (openedDay == 0) ? 7 : openedDay; // change Sunday from 0 to 7
15 | triagedDay = (triagedDay == 0) ? 7 : triagedDay;
16 | openedDay = (openedDay > 5) ? 5 : openedDay; // only count weekdays
17 | triagedDay = (triagedDay > 5) ? 5 : triagedDay;
18 | // calculate differnece in weeks (1000mS * 60sec * 60min * 24hrs * 7 days = 604800000)
19 | differenceInWeeks = Math.floor((triagedDate.getTime() - openedDate.getTime()) / 604800000);
20 | if (openedDay < triagedDay) { //Equal to makes it reduce 5 days
21 | responseTime = (differenceInWeeks * 5) + (triagedDay - openedDay);
22 | }
23 | else if (openedDay == triagedDay) {
24 | responseTime = differenceInWeeks * 5;
25 | }
26 | else {
27 | responseTime = ((differenceInWeeks + 1) * 5) - (openedDay - triagedDay);
28 | }
29 | return (responseTime);
30 | }
31 |
32 | module.exports = async(context, osmetadata) => {
33 | const foundResponseTime = await osmetadata(context).get('response_time_in_business_days');
34 | if (foundResponseTime) {
35 | const foundString = "already found response time in business days: " + foundResponseTime
36 | console.log(foundString);
37 | return foundString;
38 | }
39 | if (context.payload.comment && context.payload.comment.author_association != "MEMBER" && context.payload.comment.author_association != "OWNER" && context.payload.comment.author_association != "CONTRIBUTOR") {
40 | return;
41 | }
42 | const businessDaysResponseTime = calcResponseTimeForIssueCreatedAt(context.payload.issue.created_at);
43 | console.log("response time in business days: " + businessDaysResponseTime);
44 | const result = osmetadata(context, context.payload.issue).set('response_time_in_business_days', businessDaysResponseTime)
45 | console.log("osmetadata update result: " + result);
46 | return "set response time in business days: " + businessDaysResponseTime;
47 | }
48 |
--------------------------------------------------------------------------------
/.github/workflows/Zapier.yml:
--------------------------------------------------------------------------------
1 | # This is an action to close asana tasks that were generated by Github issues
2 |
3 | name: Zapier web hook
4 |
5 | # Controls when the workflow will run
6 | on:
7 | # Triggers the workflow on push or pull request events but only for the "main" branch
8 | issues:
9 | types: [closed]
10 |
11 | permissions:
12 | issues: read
13 |
14 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel
15 | jobs:
16 | # This workflow contains a single job called "build"
17 | build:
18 | # The type of runner that the job will run on
19 | runs-on: ubuntu-latest
20 |
21 | # Steps represent a sequence of tasks that will be executed as part of the job
22 | steps:
23 | # Runs a set of commands using the runners shell
24 | - name: Call Zapier web hook to close Asana task
25 | if: ${{ !github.event.issue.pull_request }}
26 | env:
27 | ISSUE_TITLE: ${{ github.event.issue.title }}
28 | run: |
29 | curl --location --request POST 'https://hooks.zapier.com/hooks/catch/12728683/b7009qc/' \
30 | --header 'Content-Type: application/json' \
31 | --header 'Accept: application/json' \
32 | --data-raw '{
33 | "task_name" : "$ISSUE_TITLE"
34 | }'
35 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on:
3 | pull_request:
4 | branches:
5 | - '**'
6 | paths-ignore:
7 | - '.github/**'
8 | - '.vscode/**'
9 | - 'README.md'
10 | workflow_dispatch:
11 |
12 | jobs:
13 | build:
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - name: Setup Flutter
18 | uses: subosito/flutter-action@v2
19 | with:
20 | flutter-version: '3.3.2'
21 | channel: 'stable'
22 |
23 | - name: Checkout OneSignal-Flutter-SDK
24 | uses: actions/checkout@v3
25 |
26 | - name: Install Dependencies 🔗⛓📦
27 | run: flutter pub get
28 |
29 | - name: Static Analysis
30 | run: flutter analyze
31 |
32 | - name: Ensure the Dart code is formatted correctly
33 | run: flutter format --set-exit-if-changed --dry-run .
34 |
35 | - name: Run Flutter unit tests
36 | run: flutter test
37 |
--------------------------------------------------------------------------------
/.github/workflows/project.yml:
--------------------------------------------------------------------------------
1 | name: Add issues to project
2 |
3 | on:
4 | issues:
5 | types:
6 | - opened
7 |
8 | jobs:
9 | add-to-project:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Add issue to project
13 | uses: actions/add-to-project@v1.0.2
14 | with:
15 | # SDK Cross-Platform Project
16 | project-url: https://github.com/orgs/OneSignal/projects/10
17 | github-token: ${{ secrets.GH_PROJECTS_TOKEN }}
18 |
--------------------------------------------------------------------------------
/.github/workflows/release-drafter.yml:
--------------------------------------------------------------------------------
1 |
2 | name: Release Drafter
3 |
4 | on:
5 | push:
6 | # branches to consider in the event; optional, defaults to all
7 | branches:
8 | - main
9 | # pull_request event is required only for autolabeler
10 | pull_request:
11 | # Only following types are handled by the action, but one can default to all as well
12 | types: [opened, reopened, synchronize]
13 | # pull_request_target event is required for autolabeler to support PRs from forks
14 | # pull_request_target:
15 | # types: [opened, reopened, synchronize]
16 |
17 | permissions:
18 | contents: read
19 |
20 | jobs:
21 | update_release_draft:
22 | permissions:
23 | # write permission is required to create a github release
24 | contents: write
25 | # write permission is required for autolabeler
26 | # otherwise, read permission is required at least
27 | pull-requests: write
28 | runs-on: ubuntu-latest
29 | steps:
30 | # (Optional) GitHub Enterprise requires GHE_HOST variable set
31 | #- name: Set GHE_HOST
32 | # run: |
33 | # echo "GHE_HOST=${GITHUB_SERVER_URL##https:\/\/}" >> $GITHUB_ENV
34 |
35 | # Drafts your next Release notes as Pull Requests are merged into "master"
36 | - uses: release-drafter/release-drafter@v5
37 | # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml
38 | # with:
39 | # config-name: my-config.yml
40 | # disable-autolabeler: true
41 | env:
42 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43 |
--------------------------------------------------------------------------------
/.github/workflows/set_response_time.yml:
--------------------------------------------------------------------------------
1 | name: Set Response Time
2 | on:
3 | issue_comment:
4 | types:
5 | - created
6 | issues:
7 | types:
8 | - closed
9 | jobs:
10 | calculate:
11 | name: set reponse time for the issue
12 | if: github.event.issue.pull_request == null
13 | runs-on: ubuntu-latest
14 | permissions:
15 | issues: write
16 | steps:
17 | - uses: actions/checkout@v3
18 | with:
19 | token: ${{ secrets.GITHUB_TOKEN }}
20 | - run: npm install @octokit/action@6.0.6
21 | - uses: actions/github-script@v6
22 | id: set-time
23 | with:
24 | result-encoding: string
25 | script: |
26 | const os_probot_metadata = require('./.github/os_probot_metadata.js')
27 | const set_response_time = require('./.github/set_response_times.js')
28 | return await set_response_time(context, os_probot_metadata)
29 | env:
30 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
31 | - name: Get result
32 | run: echo "${{steps.set-time.outputs.result}}" >> $GITHUB_STEP_SUMMARY
33 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .dart_tool/
3 |
4 | .packages
5 | .pub/
6 | pubspec.lock
7 |
8 | build/
9 | android/.idea
10 | .flutter-plugins-dependencies
11 | flutter_export_environment.sh
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | os:
2 | - linux
3 | sudo: false
4 | dist: trusty
5 | addons:
6 | apt:
7 | # Flutter depends on /usr/lib/x86_64-linux-gnu/libstdc++.so.6 version GLIBCXX_3.4.18
8 | sources:
9 | - ubuntu-toolchain-r-test # if we don't specify this, the libstdc++6 we get is the wrong version
10 | packages:
11 | - libstdc++6
12 | - fonts-droid
13 | before_script:
14 | - git clone https://github.com/flutter/flutter.git
15 | - ./flutter/bin/flutter doctor
16 | script:
17 | - ./flutter/bin/flutter test
18 | cache:
19 | directories:
20 | - $HOME/.pub-cache
21 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | Please see the release notes page for the full change log
2 | https://github.com/OneSignal/OneSignal-Flutter-SDK/releases
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to the OneSignal Flutter SDK
2 |
3 | :+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
4 |
5 | ### How to Contribute
6 | We love the open source community and enjoy the support and contributions of many of our users. We ask that any potential contributors to the SDK Follow the following guidelines:
7 |
8 | If your proposed contribution is a small bug fix, please feel free to create your own fork of the repository and create a pull request.
9 |
10 | If your contribution would _break_ or _change_ the functionality of the SDK, please reach out to us on (contact) before you put in a lot of effort into a change we may not be able to use. We try our best to make sure that the SDK remains stable so that developers do not have to continually change their code, however some breaking changes _are_ desirable, so please get in touch to discuss your idea before you put in a lot of effort.
11 |
12 | #### Before Submitting A Bug Report
13 | Before creating bug reports, please check this list of steps to follow.
14 |
15 | 1. Make sure that you are actually encountering an _issue_ and not a _question_. If you simply have a question about the SDK, we would be more than happy to assist you in our Support section on the web (https://www.onesignal.com - click the Message button at the bottom right)
16 | 2. Please make sure to [include as many details as possible](#how-do-i-submit-a-good-bug-report)
17 |
18 | > **Note:** If you find a **Closed** issue that seems like it is the same thing that you're experiencing, open a new issue and include a link to the original issue in the body of your new one.
19 |
20 |
21 | #### How Do I Submit a Good Bug Report
22 | * **Use a clear and descriptive title** for the issue to identify the problem.
23 | * **Include Reproducibility** It is nearly always a good idea to include steps to reproduct the issue. If you cannot reliably reproduce the issue yourself, that's ok, but reproducible steps help best.
24 | * **Describe your environment**, tell us what version of the Flutter SDK you are using, how you added it to your project, how your initialized the SDK, and so on.
25 | * **Include a Stack Trace** If your issue involves a crash/exception, ***PLEASE*** post the stack trace to help us identify the root issue.
26 | * **Include an Example Project** This isn't required, but if you want your issue fixed quickly, it's often a good idea to include an example project as a zip and include it with the issue. You can also download the Demo project (included in the `/example` folder of this repo) and set up an example project with this code as a starting point.
27 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Modified MIT License
2 |
3 | Copyright 2018 OneSignal
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | 1. The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | 2. All copies of substantial portions of the Software may only be used in connection
16 | with services provided by OneSignal.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | THE SOFTWARE.
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ### OneSignal Flutter SDK [](https://travis-ci.org/OneSignal/OneSignal-Flutter-SDK)
6 |
7 | ---
8 |
9 | #### ⚠️ Migration Advisory for current OneSignal customers
10 |
11 | Our new [user-centric APIs and v5.x.x SDKs](https://onesignal.com/blog/unify-your-users-across-channels-and-devices/) offer an improved user and data management experience. However, they may not be at 1:1 feature parity with our previous versions yet.
12 |
13 | If you are migrating an existing app, we suggest using iOS and Android’s Phased Rollout capabilities to ensure that there are no unexpected issues or edge cases. Here is the documentation for each:
14 |
15 | - [iOS Phased Rollout](https://developer.apple.com/help/app-store-connect/update-your-app/release-a-version-update-in-phases/)
16 | - [Google Play Staged Rollouts](https://support.google.com/googleplay/android-developer/answer/6346149?hl=en)
17 |
18 | If you run into any challenges or have concerns, please contact our support team at support@onesignal.com
19 |
20 | ---
21 |
22 | [OneSignal](https://onesignal.com/) is a free email, sms, push notification, and in-app message service for mobile apps. This SDK makes it easy to integrate your Flutter iOS and/or Android apps with OneSignal.
23 |
24 | 
25 |
26 | #### Installation
27 | See the [Setup Guide](https://documentation.onesignal.com/docs/flutter-sdk-setup) for setup instructions.
28 |
29 | #### Change Log
30 | See this repository's [release tags](https://github.com/onesignal/onesignal-flutter-sdk/releases) for a complete change log of every released version.
31 |
32 | #### Support
33 | Please visit this repository's [Github issue tracker](https://github.com/onesignal/onesignal-flutter-sdk/issues) for feature requests and bug reports related specificly to the SDK.
34 | For account issues and support please contact OneSignal support from the [OneSignal.com](https://onesignal.com) dashboard.
35 |
36 | #### Demo Project
37 | To make things easier, we have published a demo project in the `/example` folder of this repository.
38 |
39 | #### Supports:
40 | * Tested from iOS 8 to iOS 15
41 | * Tested from Android 4.0.3 (API level 15) to Android 12.0 (31)
42 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | group 'com.onesignal.flutter'
2 | version '5.3.3'
3 |
4 | buildscript {
5 | repositories {
6 | google()
7 | mavenCentral()
8 | }
9 |
10 | dependencies {
11 | classpath 'com.android.tools.build:gradle:7.0.0'
12 | }
13 | }
14 |
15 | rootProject.allprojects {
16 | repositories {
17 | google()
18 | mavenCentral()
19 | }
20 | }
21 |
22 | apply plugin: 'com.android.library'
23 |
24 | android {
25 | compileSdkVersion 34
26 | // Condition for namespace compatibility in AGP <4.2
27 | if (project.android.hasProperty("namespace")) {
28 | namespace 'com.onesignal.flutter'
29 | }
30 |
31 | defaultConfig {
32 | minSdkVersion 16
33 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
34 | }
35 | lintOptions {
36 | disable 'InvalidPackage'
37 | }
38 | }
39 |
40 | dependencies {
41 | implementation 'com.onesignal:OneSignal:5.1.34'
42 | }
43 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Oct 17 14:56:12 PDT 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
--------------------------------------------------------------------------------
/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'onesignal'
2 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/android/src/main/java/com/onesignal/flutter/FlutterMessengerResponder.java:
--------------------------------------------------------------------------------
1 | package com.onesignal.flutter;
2 |
3 | import android.content.Context;
4 | import android.os.Handler;
5 | import android.os.Looper;
6 |
7 | import java.util.HashMap;
8 |
9 | import io.flutter.plugin.common.BinaryMessenger;
10 | import io.flutter.plugin.common.MethodChannel;
11 |
12 | abstract class FlutterMessengerResponder {
13 | Context context;
14 | protected MethodChannel channel;
15 | BinaryMessenger messenger;
16 |
17 | /**
18 | * MethodChannel class is home to success() method used by Result class
19 | * It has the @UiThread annotation and must be run on UI thread, otherwise a RuntimeException will be thrown
20 | * This will communicate success back to Dart
21 | */
22 | void replySuccess(final MethodChannel.Result reply, final Object response) {
23 | runOnMainThread(new Runnable() {
24 | @Override
25 | public void run() {
26 | reply.success(response);
27 | }
28 | });
29 | }
30 |
31 | /**
32 | * MethodChannel class is home to error() method used by Result class
33 | * It has the @UiThread annotation and must be run on UI thread, otherwise a RuntimeException will be thrown
34 | * This will communicate error back to Dart
35 | */
36 | void replyError(final MethodChannel.Result reply, final String tag, final String message, final Object response) {
37 | runOnMainThread(new Runnable() {
38 | @Override
39 | public void run() {
40 | reply.error(tag, message, response);
41 | }
42 | });
43 | }
44 |
45 | /**
46 | * MethodChannel class is home to notImplemented() method used by Result class
47 | * It has the @UiThread annotation and must be run on UI thread, otherwise a RuntimeException will be thrown
48 | * This will communicate not implemented back to Dart
49 | */
50 | void replyNotImplemented(final MethodChannel.Result reply) {
51 | runOnMainThread(new Runnable() {
52 | @Override
53 | public void run() {
54 | reply.notImplemented();
55 | }
56 | });
57 | }
58 |
59 | private void runOnMainThread(final Runnable runnable) {
60 | if (Looper.getMainLooper().getThread() == Thread.currentThread())
61 | runnable.run();
62 | else {
63 | Handler handler = new Handler(Looper.getMainLooper());
64 | handler.post(runnable);
65 | }
66 | }
67 |
68 | void invokeMethodOnUiThread(final String methodName, final HashMap map) {
69 | //final MethodChannel channel = this.channel;
70 | runOnMainThread(new Runnable() {
71 | @Override
72 | public void run() {
73 | channel.invokeMethod(methodName, map);
74 | }
75 | });
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/android/src/main/java/com/onesignal/flutter/OneSignalDebug.java:
--------------------------------------------------------------------------------
1 | package com.onesignal.flutter;
2 |
3 | import com.onesignal.OneSignal;
4 | import com.onesignal.debug.LogLevel;
5 |
6 | import io.flutter.plugin.common.BinaryMessenger;
7 | import io.flutter.plugin.common.MethodCall;
8 | import io.flutter.plugin.common.MethodChannel;
9 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
10 | import io.flutter.plugin.common.MethodChannel.Result;
11 |
12 | public class OneSignalDebug extends FlutterMessengerResponder implements MethodCallHandler {
13 |
14 | static void registerWith(BinaryMessenger messenger) {
15 | OneSignalDebug controller = new OneSignalDebug();
16 | controller.messenger = messenger;
17 | controller.channel = new MethodChannel(messenger, "OneSignal#debug");
18 | controller.channel.setMethodCallHandler(controller);
19 | }
20 |
21 | @Override
22 | public void onMethodCall(MethodCall call, Result result) {
23 | if (call.method.contentEquals("OneSignal#setLogLevel"))
24 | this.setLogLevel(call, result);
25 | else if (call.method.contentEquals("OneSignal#setAlertLevel"))
26 | this.setAlertLevel(call, result);
27 | else
28 | replyNotImplemented(result);
29 | }
30 |
31 | private void setLogLevel(MethodCall call, Result reply) {
32 | try {
33 | int console = call.argument("logLevel");
34 | LogLevel consoleLogLevel = LogLevel.fromInt(console);
35 | OneSignal.getDebug().setLogLevel(consoleLogLevel);
36 | replySuccess(reply, null);
37 | }
38 | catch(ClassCastException e) {
39 | replyError(reply, "OneSignal", "failed with error: " + e.getMessage() + "\n" + e.getStackTrace(), null);
40 | }
41 | }
42 |
43 | private void setAlertLevel(MethodCall call, Result reply) {
44 | try {
45 | int visual = call.argument("visualLevel");
46 | LogLevel visualLogLevel = LogLevel.fromInt(visual);
47 | OneSignal.getDebug().setAlertLevel(visualLogLevel);
48 | replySuccess(reply, null);
49 | }
50 | catch(ClassCastException e) {
51 | replyError(reply, "OneSignal", "failed with error: " + e.getMessage() + "\n" + e.getStackTrace(), null);
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/android/src/main/java/com/onesignal/flutter/OneSignalLocation.java:
--------------------------------------------------------------------------------
1 | package com.onesignal.flutter;
2 |
3 | import com.onesignal.OneSignal;
4 | import com.onesignal.Continue;
5 |
6 | import io.flutter.plugin.common.BinaryMessenger;
7 | import io.flutter.plugin.common.MethodCall;
8 | import io.flutter.plugin.common.MethodChannel;
9 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
10 | import io.flutter.plugin.common.MethodChannel.Result;
11 |
12 | public class OneSignalLocation extends FlutterMessengerResponder implements MethodCallHandler {
13 |
14 | static void registerWith(BinaryMessenger messenger) {
15 | OneSignalLocation controller = new OneSignalLocation();
16 | controller.messenger = messenger;
17 | controller.channel = new MethodChannel(messenger, "OneSignal#location");
18 | controller.channel.setMethodCallHandler(controller);
19 | }
20 |
21 | @Override
22 | public void onMethodCall(MethodCall call, Result result) {
23 | if (call.method.contentEquals("OneSignal#requestPermission"))
24 | this.requestPermission(result);
25 | else if (call.method.contentEquals("OneSignal#setShared"))
26 | this.setShared(call, result);
27 | else if (call.method.contentEquals("OneSignal#isShared"))
28 | replySuccess(result, OneSignal.getLocation().isShared());
29 | else
30 | replyNotImplemented(result);
31 | }
32 |
33 | private void requestPermission(Result reply) {
34 | OneSignal.getLocation().requestPermission(Continue.none());
35 | replySuccess(reply, null);
36 | }
37 |
38 | private void setShared(MethodCall call, Result result) {
39 | OneSignal.getLocation().setShared((boolean) call.arguments);
40 | replySuccess(result, null);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/android/src/main/java/com/onesignal/flutter/OneSignalPlugin.java:
--------------------------------------------------------------------------------
1 | package com.onesignal.flutter;
2 |
3 | import android.content.Context;
4 |
5 | import io.flutter.embedding.engine.plugins.activity.ActivityAware;
6 | import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
7 |
8 | import com.onesignal.OneSignal;
9 | import com.onesignal.common.OneSignalWrapper;
10 |
11 | import androidx.annotation.NonNull;
12 | import io.flutter.embedding.engine.plugins.FlutterPlugin;
13 | import io.flutter.plugin.common.BinaryMessenger;
14 | import io.flutter.plugin.common.MethodCall;
15 | import io.flutter.plugin.common.MethodChannel;
16 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
17 | import io.flutter.plugin.common.MethodChannel.Result;
18 |
19 | /** OnesignalPlugin */
20 | public class OneSignalPlugin extends FlutterMessengerResponder implements FlutterPlugin, MethodCallHandler, ActivityAware {
21 |
22 | public OneSignalPlugin() {
23 | }
24 |
25 | private void init(Context context, BinaryMessenger messenger)
26 | {
27 | this.context = context;
28 | this.messenger = messenger;
29 | OneSignalWrapper.setSdkType("flutter");
30 | // For 5.0.0, hard code to reflect SDK version
31 | OneSignalWrapper.setSdkVersion("050303");
32 |
33 | channel = new MethodChannel(messenger, "OneSignal");
34 | channel.setMethodCallHandler(this);
35 |
36 | OneSignalDebug.registerWith(messenger);
37 | OneSignalLocation.registerWith(messenger);
38 | OneSignalSession.registerWith(messenger);
39 | OneSignalInAppMessages.registerWith(messenger);
40 | OneSignalUser.registerWith(messenger);
41 | OneSignalPushSubscription.registerWith(messenger);
42 | OneSignalNotifications.registerWith(messenger);
43 | }
44 |
45 | @Override
46 | public void onAttachedToEngine(@NonNull FlutterPlugin.FlutterPluginBinding flutterPluginBinding) {
47 | init(
48 | flutterPluginBinding.getApplicationContext(),
49 | flutterPluginBinding.getBinaryMessenger()
50 | );
51 | }
52 |
53 | @Override
54 | public void onDetachedFromEngine(@NonNull FlutterPlugin.FlutterPluginBinding binding) {
55 | onDetachedFromEngine();
56 | }
57 |
58 | private void onDetachedFromEngine() {
59 | }
60 |
61 | @Override
62 | public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
63 | this.context = binding.getActivity();
64 | }
65 |
66 | @Override
67 | public void onDetachedFromActivity() {
68 | }
69 |
70 | @Override
71 | public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
72 | }
73 |
74 | @Override
75 | public void onDetachedFromActivityForConfigChanges() {
76 | }
77 |
78 | @Override
79 | public void onMethodCall(MethodCall call, Result result) {
80 | if (call.method.contentEquals("OneSignal#initialize"))
81 | this.initWithContext(call, result);
82 | else if (call.method.contentEquals("OneSignal#consentRequired"))
83 | this.setConsentRequired(call, result);
84 | else if (call.method.contentEquals("OneSignal#consentGiven"))
85 | this.setConsentGiven(call, result);
86 | else if (call.method.contentEquals("OneSignal#login"))
87 | this.login(call, result);
88 | else if (call.method.contentEquals("OneSignal#loginWithJWT"))
89 | this.loginWithJWT(call, result);
90 | else if (call.method.contentEquals("OneSignal#logout"))
91 | this.logout(call, result);
92 | else
93 | replyNotImplemented(result);
94 | }
95 |
96 | private void initWithContext(MethodCall call, Result reply) {
97 | String appId = call.argument("appId");
98 | OneSignal.initWithContext(context, appId);
99 | replySuccess(reply, null);
100 | }
101 |
102 | private void setConsentRequired(MethodCall call, Result reply) {
103 | boolean required = call.argument("required");
104 | OneSignal.setConsentRequired(required);
105 | replySuccess(reply, null);
106 | }
107 |
108 | private void setConsentGiven(MethodCall call, Result reply) {
109 | boolean granted = call.argument("granted");
110 | OneSignal.setConsentGiven(granted);
111 | replySuccess(reply, null);
112 | }
113 |
114 | private void login(MethodCall call, Result result) {
115 | OneSignal.login((String) call.argument("externalId"));
116 | replySuccess(result, null);
117 | }
118 |
119 | private void loginWithJWT(MethodCall call, Result result) {
120 | OneSignal.login((String) call.argument("externalId"), (String) call.argument("jwt"));
121 | replySuccess(result, null);
122 | }
123 |
124 | private void logout(MethodCall call, Result result) {
125 | OneSignal.logout();
126 | replySuccess(result, null);
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/android/src/main/java/com/onesignal/flutter/OneSignalPushSubscription.java:
--------------------------------------------------------------------------------
1 | package com.onesignal.flutter;
2 |
3 | import com.onesignal.OneSignal;
4 |
5 | import com.onesignal.user.subscriptions.IPushSubscriptionObserver;
6 | import com.onesignal.user.subscriptions.PushSubscriptionChangedState;
7 | import com.onesignal.debug.internal.logging.Logging;
8 |
9 | import org.json.JSONException;
10 |
11 | import io.flutter.plugin.common.BinaryMessenger;
12 | import io.flutter.plugin.common.MethodCall;
13 | import io.flutter.plugin.common.MethodChannel;
14 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
15 | import io.flutter.plugin.common.MethodChannel.Result;
16 |
17 | public class OneSignalPushSubscription extends FlutterMessengerResponder implements MethodCallHandler, IPushSubscriptionObserver {
18 |
19 | static void registerWith(BinaryMessenger messenger) {
20 | OneSignalPushSubscription controller = new OneSignalPushSubscription();
21 | controller.messenger = messenger;
22 | controller.channel = new MethodChannel(messenger, "OneSignal#pushsubscription");
23 | controller.channel.setMethodCallHandler(controller);
24 | }
25 |
26 | @Override
27 | public void onMethodCall(MethodCall call, Result result) {
28 | if (call.method.contentEquals("OneSignal#optIn"))
29 | this.optIn(call, result);
30 | else if (call.method.contentEquals("OneSignal#optOut"))
31 | this.optOut(call, result);
32 | else if (call.method.contentEquals("OneSignal#pushSubscriptionId"))
33 | replySuccess(result, OneSignal.getUser().getPushSubscription().getId());
34 | else if (call.method.contentEquals("OneSignal#pushSubscriptionToken"))
35 | replySuccess(result, OneSignal.getUser().getPushSubscription().getToken());
36 | else if (call.method.contentEquals("OneSignal#pushSubscriptionOptedIn"))
37 | replySuccess(result, OneSignal.getUser().getPushSubscription().getOptedIn());
38 | else if (call.method.contentEquals("OneSignal#lifecycleInit"))
39 | this.lifecycleInit();
40 | else
41 | replyNotImplemented(result);
42 | }
43 |
44 | private void optIn(MethodCall call, Result reply) {
45 | OneSignal.getUser().getPushSubscription().optIn();
46 | replySuccess(reply, null);
47 | }
48 | private void optOut(MethodCall call, Result reply) {
49 | OneSignal.getUser().getPushSubscription().optOut();
50 | replySuccess(reply, null);
51 | }
52 |
53 | private void lifecycleInit() {
54 | OneSignal.getUser().getPushSubscription().addObserver(this);
55 | }
56 |
57 | @Override
58 | public void onPushSubscriptionChange(PushSubscriptionChangedState changeState) {
59 | try {
60 | invokeMethodOnUiThread("OneSignal#onPushSubscriptionChange", OneSignalSerializer.convertOnPushSubscriptionChange(changeState));
61 | } catch (JSONException e) {
62 | e.getStackTrace();
63 | Logging.error("Encountered an error attempting to convert PushSubscriptionChangedState object to hash map:" + e.toString(), null);
64 | }
65 | }
66 |
67 | }
--------------------------------------------------------------------------------
/android/src/main/java/com/onesignal/flutter/OneSignalSession.java:
--------------------------------------------------------------------------------
1 | package com.onesignal.flutter;
2 |
3 | import com.onesignal.OneSignal;
4 |
5 | import io.flutter.plugin.common.BinaryMessenger;
6 | import io.flutter.plugin.common.MethodCall;
7 | import io.flutter.plugin.common.MethodChannel;
8 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
9 | import io.flutter.plugin.common.MethodChannel.Result;
10 |
11 | public class OneSignalSession extends FlutterMessengerResponder implements MethodCallHandler {
12 |
13 | static void registerWith(BinaryMessenger messenger) {
14 | OneSignalSession controller = new OneSignalSession();
15 | controller.messenger = messenger;
16 | controller.channel = new MethodChannel(messenger, "OneSignal#session");
17 | controller.channel.setMethodCallHandler(controller);
18 | }
19 |
20 | @Override
21 | public void onMethodCall(MethodCall call, Result result) {
22 | if (call.method.contentEquals("OneSignal#addOutcome"))
23 | this.addOutcome(call, result);
24 | else if (call.method.contentEquals("OneSignal#addUniqueOutcome"))
25 | this.addUniqueOutcome(call, result);
26 | else if (call.method.contentEquals("OneSignal#addOutcomeWithValue"))
27 | this.addOutcomeWithValue(call, result);
28 | else
29 | replyNotImplemented(result);
30 | }
31 |
32 | private void addOutcome(MethodCall call, Result result) {
33 | String name = (String) call.arguments;
34 |
35 | if (name == null || name.isEmpty()) {
36 | replyError(result, "OneSignal", "addOutcome() name must not be null or empty", null);
37 | return;
38 | }
39 |
40 | OneSignal.getSession().addOutcome(name);
41 | replySuccess(result, null);
42 | }
43 |
44 | private void addUniqueOutcome(MethodCall call, Result result) {
45 | String name = (String) call.arguments;
46 |
47 | if (name == null || name.isEmpty()) {
48 | replyError(result, "OneSignal", "sendUniqueOutcome() name must not be null or empty", null);
49 | return;
50 | }
51 |
52 | OneSignal.getSession().addUniqueOutcome(name);
53 | replySuccess(result, null);
54 | }
55 |
56 | private void addOutcomeWithValue(MethodCall call, Result result) {
57 | String name = call.argument("outcome_name");
58 | Double value = call.argument("outcome_value");
59 |
60 | if (name == null || name.isEmpty()) {
61 | replyError(result, "OneSignal", "sendOutcomeWithValue() name must not be null or empty", null);
62 | return;
63 | }
64 |
65 | if (value == null) {
66 | replyError(result, "OneSignal", "sendOutcomeWithValue() value must not be null", null);
67 | return;
68 | }
69 |
70 | OneSignal.getSession().addOutcomeWithValue(name, value.floatValue());
71 | replySuccess(result, null);
72 | }
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .dart_tool/
3 |
4 | .packages
5 | .pub/
6 |
7 | build/
8 |
9 | .flutter-plugins
10 | .flutter-plugins-dependencies
11 | flutter_export_environment.sh
--------------------------------------------------------------------------------
/example/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: c7ea3ca377e909469c68f2ab878a5bc53d3cf66b
8 | channel: beta
9 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # onesignal_example
2 |
3 | Demonstrates how to use the onesignal plugin.
4 |
5 | ## Getting Started
6 |
7 | For help getting started with Flutter, view our online
8 | [documentation](https://flutter.io/).
9 |
--------------------------------------------------------------------------------
/example/android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | *.class
3 | .gradle
4 | /local.properties
5 | /.idea/workspace.xml
6 | /.idea/libraries
7 | .DS_Store
8 | /build
9 | /captures
10 | GeneratedPluginRegistrant.java
11 |
--------------------------------------------------------------------------------
/example/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | apply plugin: 'com.android.application'
15 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
16 |
17 | android {
18 | compileSdkVersion 34
19 |
20 | lintOptions {
21 | disable 'InvalidPackage'
22 | }
23 |
24 | defaultConfig {
25 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
26 | applicationId "com.onesignal.onesignalexample"
27 | minSdkVersion 19
28 | targetSdkVersion 33
29 | versionCode 1
30 | versionName "1.0"
31 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
32 | }
33 |
34 | buildTypes {
35 | release {
36 | // TODO: Add your own signing config for the release build.
37 | // Signing with the debug keys for now, so `flutter run --release` works.
38 | signingConfig signingConfigs.debug
39 | }
40 | }
41 | }
42 |
43 | flutter {
44 | source '../..'
45 | }
46 |
47 | dependencies {
48 | testImplementation 'junit:junit:4.12'
49 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
50 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
51 | }
52 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
21 |
24 |
32 |
36 |
40 |
45 |
49 |
50 |
51 |
52 |
53 |
54 |
56 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/onesignal/onesignalexample/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.onesignal.onesignalexample;
2 |
3 | import io.flutter.embedding.android.FlutterActivity;
4 |
5 | public class MainActivity extends FlutterActivity {
6 | }
7 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | }
6 |
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:7.0.0'
9 | }
10 | }
11 |
12 | allprojects {
13 | repositories {
14 | google()
15 | mavenCentral()
16 | }
17 | }
18 |
19 | rootProject.buildDir = '../build'
20 | subprojects {
21 | project.buildDir = "${rootProject.buildDir}/${project.name}"
22 | }
23 | subprojects {
24 | project.evaluationDependsOn(':app')
25 | }
26 |
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
30 |
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 |
3 | android.enableR8=true
4 | android.enableD8=true
5 |
6 | android.useAndroidX=true
7 | android.enableJetifier=true
8 |
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Oct 17 15:00:44 PDT 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
--------------------------------------------------------------------------------
/example/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/example/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
4 |
5 | def plugins = new Properties()
6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
7 | if (pluginsFile.exists()) {
8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
9 | }
10 |
11 | plugins.each { name, path ->
12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
13 | include ":$name"
14 | project(":$name").projectDir = pluginDirectory
15 | }
16 |
--------------------------------------------------------------------------------
/example/ios/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .vagrant/
3 | .sconsign.dblite
4 | .svn/
5 |
6 | .DS_Store
7 | *.swp
8 | profile
9 |
10 | DerivedData/
11 | build/
12 | GeneratedPluginRegistrant.h
13 | GeneratedPluginRegistrant.m
14 |
15 | .generated/
16 |
17 | *.pbxuser
18 | *.mode1v3
19 | *.mode2v3
20 | *.perspectivev3
21 |
22 | !default.pbxuser
23 | !default.mode1v3
24 | !default.mode2v3
25 | !default.perspectivev3
26 |
27 | xcuserdata
28 |
29 | *.moved-aside
30 |
31 | *.pyc
32 | *sync/
33 | Icon?
34 | .tags*
35 |
36 | /Flutter/app.flx
37 | /Flutter/app.zip
38 | /Flutter/flutter_assets/
39 | /Flutter/App.framework
40 | /Flutter/Flutter.framework
41 | /Flutter/Generated.xcconfig
42 | /ServiceDefinitions.json
43 |
44 | Pods/
45 | .symlinks/
46 |
--------------------------------------------------------------------------------
/example/ios/ExampleWidget/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/example/ios/ExampleWidget/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/example/ios/ExampleWidget/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/example/ios/ExampleWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/example/ios/ExampleWidget/Assets.xcassets/onesignaldemo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "filename" : "onesignal-logo.png",
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/example/ios/ExampleWidget/Assets.xcassets/onesignaldemo.imageset/onesignal-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/ios/ExampleWidget/Assets.xcassets/onesignaldemo.imageset/onesignal-logo.png
--------------------------------------------------------------------------------
/example/ios/ExampleWidget/ExampleWidgetBundle.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ExampleWidgetBundle.swift
3 | // ExampleWidget
4 | //
5 | // Created by Brian Smith on 4/30/24.
6 | // Copyright © 2024 The Chromium Authors. All rights reserved.
7 | //
8 |
9 | import WidgetKit
10 | import SwiftUI
11 |
12 | @main
13 | struct ExampleWidgetBundle: WidgetBundle {
14 | var body: some Widget {
15 | ExampleWidgetLiveActivity()
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/example/ios/ExampleWidget/ExampleWidgetLiveActivity.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ExampleWidgetLiveActivity.swift
3 | // ExampleWidget
4 | //
5 | // Created by Brian Smith on 4/30/24.
6 | // Copyright © 2024 The Chromium Authors. All rights reserved.
7 | //
8 |
9 | import ActivityKit
10 | import WidgetKit
11 | import SwiftUI
12 | import OneSignalLiveActivities
13 |
14 | struct ExampleWidgetLiveActivity: Widget {
15 | var body: some WidgetConfiguration {
16 | ActivityConfiguration(for: DefaultLiveActivityAttributes.self) { context in
17 | // Lock screen/banner UI goes here\VStack(alignment: .leading) {
18 | VStack {
19 | Spacer()
20 | Text("FLUTTER: " + (context.attributes.data["title"]?.asString() ?? "")).font(.headline)
21 | Spacer()
22 | HStack {
23 | Spacer()
24 | Label {
25 | Text(context.state.data["message"]?.asDict()?["en"]?.asString() ?? "")
26 | } icon: {
27 | Image("onesignaldemo")
28 | .resizable()
29 | .scaledToFit()
30 | .frame(width: 40.0, height: 40.0)
31 | }
32 | Spacer()
33 | }
34 | Text("INT: " + String(context.state.data["intValue"]?.asInt() ?? 0))
35 | Text("DBL: " + String(context.state.data["doubleValue"]?.asDouble() ?? 0.0))
36 | Text("BOL: " + String(context.state.data["boolValue"]?.asBool() ?? false))
37 | Spacer()
38 | }
39 | .activitySystemActionForegroundColor(.black)
40 | .activityBackgroundTint(.white)
41 | } dynamicIsland: { _ in
42 | DynamicIsland {
43 | // Expanded UI goes here. Compose the expanded UI through
44 | // various regions, like leading/trailing/center/bottom
45 | DynamicIslandExpandedRegion(.leading) {
46 | Text("Leading")
47 | }
48 | DynamicIslandExpandedRegion(.trailing) {
49 | Text("Trailing")
50 | }
51 | DynamicIslandExpandedRegion(.bottom) {
52 | Text("Bottom")
53 | // more content
54 | }
55 | } compactLeading: {
56 | Text("L")
57 | } compactTrailing: {
58 | Text("T")
59 | } minimal: {
60 | Text("Min")
61 | }
62 | .widgetURL(URL(string: "http://www.apple.com"))
63 | .keylineTint(Color.red)
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/example/ios/ExampleWidget/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSExtension
6 |
7 | NSExtensionPointIdentifier
8 | com.apple.widgetkit-extension
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/example/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 12.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Flutter.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # This podspec is NOT to be published. It is only used as a local source!
3 | # This is a generated file; do not edit or check into version control.
4 | #
5 |
6 | Pod::Spec.new do |s|
7 | s.name = 'Flutter'
8 | s.version = '1.0.0'
9 | s.summary = 'A UI toolkit for beautiful and fast apps.'
10 | s.homepage = 'https://flutter.dev'
11 | s.license = { :type => 'BSD' }
12 | s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
13 | s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s }
14 | s.ios.deployment_target = '12.0'
15 | # Framework linking is handled by Flutter tooling, not CocoaPods.
16 | # Add a placeholder to satisfy `s.dependency 'Flutter'` plugin podspecs.
17 | s.vendored_frameworks = 'path/to/nothing'
18 | end
19 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/ios/OneSignalNotificationServiceExtension/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | OneSignalNotificationServiceExtension
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | XPC!
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | NSAppTransportSecurity
24 |
25 | NSAllowsArbitraryLoads
26 |
27 |
28 | NSExtension
29 |
30 | NSExtensionPointIdentifier
31 | com.apple.usernotifications.service
32 | NSExtensionPrincipalClass
33 | NotificationService
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/example/ios/OneSignalNotificationServiceExtension/NotificationService.h:
--------------------------------------------------------------------------------
1 | //
2 | // NotificationService.h
3 | // OneSignalNotificationServiceExtension
4 | //
5 | // Created by Brad Hesse on 7/13/18.
6 | // Copyright © 2018 The Chromium Authors. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NotificationService : UNNotificationServiceExtension
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/example/ios/OneSignalNotificationServiceExtension/NotificationService.m:
--------------------------------------------------------------------------------
1 | //
2 | // NotificationService.m
3 | // OneSignalNotificationServiceExtension
4 | //
5 | // Created by Brad Hesse on 7/13/18.
6 | // Copyright © 2018 The Chromium Authors. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "NotificationService.h"
12 |
13 | @interface NotificationService ()
14 |
15 | @property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
16 | @property (nonatomic, strong) UNNotificationRequest *receivedRequest;
17 | @property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
18 |
19 | @end
20 |
21 | @implementation NotificationService
22 |
23 | - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
24 | self.receivedRequest = request;
25 | self.contentHandler = contentHandler;
26 | self.bestAttemptContent = [request.content mutableCopy];
27 |
28 | [OneSignal didReceiveNotificationExtensionRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent withContentHandler:self.contentHandler];
29 | }
30 |
31 | - (void)serviceExtensionTimeWillExpire {
32 | // Called just before the extension will be terminated by the system.
33 | // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
34 |
35 | [OneSignal serviceExtensionTimeWillExpireRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent];
36 |
37 | self.contentHandler(self.bestAttemptContent);
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/example/ios/OneSignalNotificationServiceExtension/OneSignalNotificationServiceExtension.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.application-groups
6 |
7 | group.com.onesignal.example.onesignal
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/example/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | platform :ios, '12.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def flutter_root
14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15 | unless File.exist?(generated_xcode_build_settings_path)
16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17 | end
18 |
19 | File.foreach(generated_xcode_build_settings_path) do |line|
20 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
21 | return matches[1].strip if matches
22 | end
23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24 | end
25 |
26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27 |
28 | flutter_ios_podfile_setup
29 |
30 | target 'Runner' do
31 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
32 | end
33 |
34 | target 'OneSignalNotificationServiceExtension' do
35 | pod 'OneSignalXCFramework', '>= 5.0.2', '< 6.0.0'
36 | end
37 |
38 | target 'ExampleWidgetExtension' do
39 | pod 'OneSignalXCFramework', '>= 5.0.2', '< 6.0.0'
40 | end
41 |
42 | post_install do |installer|
43 | installer.pods_project.targets.each do |target|
44 | flutter_additional_ios_build_settings(target)
45 | end
46 | end
47 |
--------------------------------------------------------------------------------
/example/ios/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Flutter (1.0.0)
3 | - onesignal_flutter (5.1.5):
4 | - Flutter
5 | - OneSignalXCFramework (= 5.2.0)
6 | - OneSignalXCFramework (5.2.0):
7 | - OneSignalXCFramework/OneSignalComplete (= 5.2.0)
8 | - OneSignalXCFramework/OneSignal (5.2.0):
9 | - OneSignalXCFramework/OneSignalCore
10 | - OneSignalXCFramework/OneSignalExtension
11 | - OneSignalXCFramework/OneSignalLiveActivities
12 | - OneSignalXCFramework/OneSignalNotifications
13 | - OneSignalXCFramework/OneSignalOSCore
14 | - OneSignalXCFramework/OneSignalOutcomes
15 | - OneSignalXCFramework/OneSignalUser
16 | - OneSignalXCFramework/OneSignalComplete (5.2.0):
17 | - OneSignalXCFramework/OneSignal
18 | - OneSignalXCFramework/OneSignalInAppMessages
19 | - OneSignalXCFramework/OneSignalLocation
20 | - OneSignalXCFramework/OneSignalCore (5.2.0)
21 | - OneSignalXCFramework/OneSignalExtension (5.2.0):
22 | - OneSignalXCFramework/OneSignalCore
23 | - OneSignalXCFramework/OneSignalOutcomes
24 | - OneSignalXCFramework/OneSignalInAppMessages (5.2.0):
25 | - OneSignalXCFramework/OneSignalCore
26 | - OneSignalXCFramework/OneSignalNotifications
27 | - OneSignalXCFramework/OneSignalOSCore
28 | - OneSignalXCFramework/OneSignalOutcomes
29 | - OneSignalXCFramework/OneSignalUser
30 | - OneSignalXCFramework/OneSignalLiveActivities (5.2.0):
31 | - OneSignalXCFramework/OneSignalCore
32 | - OneSignalXCFramework/OneSignalOSCore
33 | - OneSignalXCFramework/OneSignalUser
34 | - OneSignalXCFramework/OneSignalLocation (5.2.0):
35 | - OneSignalXCFramework/OneSignalCore
36 | - OneSignalXCFramework/OneSignalNotifications
37 | - OneSignalXCFramework/OneSignalOSCore
38 | - OneSignalXCFramework/OneSignalUser
39 | - OneSignalXCFramework/OneSignalNotifications (5.2.0):
40 | - OneSignalXCFramework/OneSignalCore
41 | - OneSignalXCFramework/OneSignalExtension
42 | - OneSignalXCFramework/OneSignalOutcomes
43 | - OneSignalXCFramework/OneSignalOSCore (5.2.0):
44 | - OneSignalXCFramework/OneSignalCore
45 | - OneSignalXCFramework/OneSignalOutcomes (5.2.0):
46 | - OneSignalXCFramework/OneSignalCore
47 | - OneSignalXCFramework/OneSignalUser (5.2.0):
48 | - OneSignalXCFramework/OneSignalCore
49 | - OneSignalXCFramework/OneSignalNotifications
50 | - OneSignalXCFramework/OneSignalOSCore
51 | - OneSignalXCFramework/OneSignalOutcomes
52 |
53 | DEPENDENCIES:
54 | - Flutter (from `Flutter`)
55 | - onesignal_flutter (from `.symlinks/plugins/onesignal_flutter/ios`)
56 | - OneSignalXCFramework (< 6.0.0, >= 5.0.2)
57 |
58 | SPEC REPOS:
59 | trunk:
60 | - OneSignalXCFramework
61 |
62 | EXTERNAL SOURCES:
63 | Flutter:
64 | :path: Flutter
65 | onesignal_flutter:
66 | :path: ".symlinks/plugins/onesignal_flutter/ios"
67 |
68 | SPEC CHECKSUMS:
69 | Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
70 | onesignal_flutter: 6e7b22bc9bbdb32cbaf79728e624a02264adec94
71 | OneSignalXCFramework: bdf74fdc06888f9466dc21e826fe1549ed143095
72 |
73 | PODFILE CHECKSUM: 4866dde54f21b323e83902730ef350ff4a561f44
74 |
75 | COCOAPODS: 1.15.2
76 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
52 |
54 |
60 |
61 |
62 |
63 |
69 |
71 |
77 |
78 |
79 |
80 |
82 |
83 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface AppDelegate : FlutterAppDelegate
5 |
6 | @end
7 |
--------------------------------------------------------------------------------
/example/ios/Runner/AppDelegate.m:
--------------------------------------------------------------------------------
1 | #include "AppDelegate.h"
2 | #include "GeneratedPluginRegistrant.h"
3 |
4 | @implementation AppDelegate
5 |
6 | - (BOOL)application:(UIApplication *)application
7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
8 | [GeneratedPluginRegistrant registerWithRegistry:self];
9 | // Override point for customization after application launch.
10 | return [super application:application didFinishLaunchingWithOptions:launchOptions];
11 | }
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/example/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CADisableMinimumFrameDurationOnPhone
6 |
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleDisplayName
10 | OneSignalDemo
11 | CFBundleExecutable
12 | $(EXECUTABLE_NAME)
13 | CFBundleIdentifier
14 | $(PRODUCT_BUNDLE_IDENTIFIER)
15 | CFBundleInfoDictionaryVersion
16 | 6.0
17 | CFBundleName
18 | onesignal_example
19 | CFBundlePackageType
20 | APPL
21 | CFBundleShortVersionString
22 | 1.0
23 | CFBundleSignature
24 | ????
25 | CFBundleVersion
26 | 1
27 | LSRequiresIPhoneOS
28 |
29 | NSAppTransportSecurity
30 |
31 | NSAllowsArbitraryLoads
32 |
33 |
34 | NSSupportsLiveActivities
35 |
36 | UIApplicationSupportsIndirectInputEvents
37 |
38 | UILaunchStoryboardName
39 | LaunchScreen
40 | UIMainStoryboardFile
41 | Main
42 | UISupportedInterfaceOrientations
43 |
44 | UIInterfaceOrientationPortrait
45 | UIInterfaceOrientationLandscapeLeft
46 | UIInterfaceOrientationLandscapeRight
47 |
48 | UISupportedInterfaceOrientations~ipad
49 |
50 | UIInterfaceOrientationPortrait
51 | UIInterfaceOrientationPortraitUpsideDown
52 | UIInterfaceOrientationLandscapeLeft
53 | UIInterfaceOrientationLandscapeRight
54 |
55 | UIViewControllerBasedStatusBarAppearance
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/example/ios/Runner/Runner.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | aps-environment
6 | development
7 | com.apple.security.application-groups
8 |
9 | group.com.onesignal.example.onesignal
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/example/ios/Runner/main.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import "AppDelegate.h"
4 |
5 | int main(int argc, char* argv[]) {
6 | @autoreleasepool {
7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: onesignal_example
2 | description: Demonstrates how to use the onesignal plugin.
3 | version: 1.0.0+1
4 |
5 | dependencies:
6 | flutter:
7 | sdk: flutter
8 | # The following adds the Cupertino Icons font to your application.
9 | # Use with the CupertinoIcons class for iOS style icons.
10 | cupertino_icons: ^1.0.0
11 |
12 | environment:
13 | sdk: ">=2.12.0 <3.0.0"
14 |
15 | dev_dependencies:
16 | flutter_test:
17 | sdk: flutter
18 |
19 | onesignal_flutter:
20 | path: ../
21 |
22 | # For information on the generic Dart part of this file, see the
23 | # following page: https://www.dartlang.org/tools/pub/pubspec
24 |
25 | # The following section is specific to Flutter.
26 | flutter:
27 |
28 | # The following line ensures that the Material Icons font is
29 | # included with your application, so that you can use the icons in
30 | # the material Icons class.
31 | uses-material-design: true
32 |
33 | # To add assets to your application, add an assets section, like this:
34 | # assets:
35 | # - images/a_dot_burr.jpeg
36 | # - images/a_dot_ham.jpeg
37 |
38 | # An image asset can refer to one or more resolution-specific "variants", see
39 | # https://flutter.io/assets-and-images/#resolution-aware.
40 |
41 | # For details regarding adding assets from package dependencies, see
42 | # https://flutter.io/assets-and-images/#from-packages
43 |
44 | # To add custom fonts to your application, add a fonts section here,
45 | # in this "flutter" section. Each entry in this list should have a
46 | # "family" key with the font family name, and a "fonts" key with a
47 | # list giving the asset and other descriptors for the font. For
48 | # example:
49 | # fonts:
50 | # - family: Schyler
51 | # fonts:
52 | # - asset: fonts/Schyler-Regular.ttf
53 | # - asset: fonts/Schyler-Italic.ttf
54 | # style: italic
55 | # - family: Trajan Pro
56 | # fonts:
57 | # - asset: fonts/TrajanPro.ttf
58 | # - asset: fonts/TrajanPro_Bold.ttf
59 | # weight: 700
60 | #
61 | # For details regarding fonts from package dependencies,
62 | # see https://flutter.io/custom-fonts/#from-packages
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .vagrant/
3 | .sconsign.dblite
4 | .svn/
5 |
6 | .DS_Store
7 | *.swp
8 | profile
9 |
10 | DerivedData/
11 | build/
12 | GeneratedPluginRegistrant.h
13 | GeneratedPluginRegistrant.m
14 |
15 | .generated/
16 |
17 | *.pbxuser
18 | *.mode1v3
19 | *.mode2v3
20 | *.perspectivev3
21 |
22 | !default.pbxuser
23 | !default.mode1v3
24 | !default.mode2v3
25 | !default.perspectivev3
26 |
27 | xcuserdata
28 |
29 | *.moved-aside
30 |
31 | *.pyc
32 | *sync/
33 | Icon?
34 | .tags*
35 |
36 | /Flutter/Generated.xcconfig
37 |
--------------------------------------------------------------------------------
/ios/Assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneSignal/OneSignal-Flutter-SDK/4b0330cd008bbc07c84359f435263b7ad5cb1d16/ios/Assets/.gitkeep
--------------------------------------------------------------------------------
/ios/Classes/OSFlutterCategories.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Modified MIT License
3 | *
4 | * Copyright 2017 OneSignal
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * 1. The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * 2. All copies of substantial portions of the Software may only be used in connection
17 | * with services provided by OneSignal.
18 | *
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | * THE SOFTWARE.
26 | */
27 |
28 | #import
29 | #import
30 |
31 | #ifndef OneSignalCategories_h
32 | #define OneSignalCategories_h
33 |
34 | @interface OSNotification (Flutter)
35 | - (NSDictionary *)toJson;
36 | @end
37 |
38 | @interface OSNotificationWillDisplayEvent (Flutter)
39 | - (NSDictionary *)toJson;
40 | @end
41 |
42 | @interface OSNotificationClickEvent (Flutter)
43 | - (NSDictionary *)toJson;
44 | @end
45 |
46 | @interface OSNotificationClickResult (Flutter)
47 | - (NSDictionary *)toJson;
48 | @end
49 |
50 | @interface OSInAppMessage (Flutter)
51 | - (NSDictionary *)toJson;
52 | @end
53 |
54 | @interface NSError (Flutter)
55 | - (FlutterError *)flutterError;
56 | @end
57 |
58 | @interface OSInAppMessageWillDisplayEvent (Flutter)
59 | - (NSDictionary *)toJson;
60 | @end
61 |
62 | @interface OSInAppMessageDidDisplayEvent (Flutter)
63 | - (NSDictionary *)toJson;
64 | @end
65 |
66 | @interface OSInAppMessageWillDismissEvent (Flutter)
67 | - (NSDictionary *)toJson;
68 | @end
69 |
70 | @interface OSInAppMessageDidDismissEvent (Flutter)
71 | - (NSDictionary *)toJson;
72 | @end
73 |
74 | @interface OSInAppMessageClickEvent (Flutter)
75 | - (NSDictionary *)toJson;
76 | @end
77 |
78 | @interface OSInAppMessageClickResult (Flutter)
79 | - (NSDictionary *)toJson;
80 | @end
81 |
82 | #endif
83 |
--------------------------------------------------------------------------------
/ios/Classes/OSFlutterCategories.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Modified MIT License
3 | *
4 | * Copyright 2017 OneSignal
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * 1. The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * 2. All copies of substantial portions of the Software may only be used in connection
17 | * with services provided by OneSignal.
18 | *
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | * THE SOFTWARE.
26 | */
27 |
28 | #import "OSFlutterCategories.h"
29 |
30 | /*
31 | The OneSignal iOS SDK implements similar methods (`toDictionary`)
32 | However we decided to implement custom `toJson` methods for several
33 | of these objects to add more properties.
34 |
35 | TODO: Update the native iOS SDK to add these details
36 | (ie. `templateId` is missing from OSNotificationPayload's `toDictionary`
37 | method in the native SDK) and remove them from here.
38 | */
39 |
40 | @implementation OSNotification (Flutter)
41 | - (NSDictionary *)toJson {
42 | NSMutableDictionary *json = [NSMutableDictionary new];
43 |
44 | json[@"contentAvailable"] = @(self.contentAvailable);
45 | json[@"mutableContent"] = @(self.mutableContent);
46 |
47 | if (self.rawPayload) {
48 | NSError *jsonError;
49 | NSData *data = [NSJSONSerialization dataWithJSONObject:self.rawPayload options:NSJSONWritingPrettyPrinted error:&jsonError];
50 |
51 | if (!jsonError) {
52 | NSString *rawPayloadString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
53 | json[@"rawPayload"] = rawPayloadString;
54 | }
55 | }
56 |
57 | if (self.notificationId) json[@"notificationId"] = self.notificationId;
58 | if (self.templateName) json[@"templateName"] = self.templateName;
59 | if (self.templateId) json[@"templateId"] = self.templateId;
60 | if (self.badge) json[@"badge"] = @(self.badge);
61 | if (self.badgeIncrement) json[@"badgeIncrement"] = @(self.badgeIncrement);
62 | if (self.sound) json[@"sound"] = self.sound;
63 | if (self.title) json[@"title"] = self.title;
64 | if (self.subtitle) json[@"subtitle"] = self.subtitle;
65 | if (self.body) json[@"body"] = self.body;
66 | if (self.launchURL) json[@"launchUrl"] = self.launchURL;
67 | if (self.additionalData) json[@"additionalData"] = self.additionalData;
68 | if (self.attachments) json[@"attachments"] = self.attachments;
69 | if (self.actionButtons) json[@"buttons"] = self.actionButtons;
70 | if (self.category) json[@"category"] = self.category;
71 |
72 | return json;
73 | }
74 | @end
75 |
76 | @implementation OSNotificationClickEvent (Flutter)
77 | - (NSDictionary *)toJson {
78 | NSMutableDictionary *json = [NSMutableDictionary new];
79 |
80 | json[@"notification"] = self.notification.toJson;
81 | json[@"result"] = self.result.toJson;
82 |
83 | return json;
84 | }
85 | @end
86 |
87 | @implementation OSNotificationClickResult (Flutter)
88 | - (NSDictionary *)toJson {
89 | NSMutableDictionary *json = [NSMutableDictionary new];
90 |
91 | json[@"action_id"] = self.actionId;
92 | json[@"url"] = self.url;
93 |
94 | return json;
95 | }
96 | @end
97 |
98 | @implementation OSNotificationWillDisplayEvent (Flutter)
99 | - (NSDictionary *)toJson {
100 | NSMutableDictionary *json = [NSMutableDictionary new];
101 |
102 | json[@"notification"] = self.notification.toJson;
103 |
104 | return json;
105 | }
106 | @end
107 |
108 | @implementation OSInAppMessageWillDisplayEvent (Flutter)
109 | - (NSDictionary *)toJson {
110 | NSMutableDictionary *json = [NSMutableDictionary new];
111 |
112 | json[@"message"] = self.message.toJson;
113 |
114 | return json;
115 | }
116 | @end
117 |
118 | @implementation OSInAppMessageDidDisplayEvent (Flutter)
119 | - (NSDictionary *)toJson {
120 | NSMutableDictionary *json = [NSMutableDictionary new];
121 |
122 | json[@"message"] = self.message.toJson;
123 |
124 | return json;
125 | }
126 | @end
127 |
128 | @implementation OSInAppMessageWillDismissEvent (Flutter)
129 | - (NSDictionary *)toJson {
130 | NSMutableDictionary *json = [NSMutableDictionary new];
131 |
132 | json[@"message"] = self.message.toJson;
133 |
134 | return json;
135 | }
136 | @end
137 |
138 | @implementation OSInAppMessageDidDismissEvent (Flutter)
139 | - (NSDictionary *)toJson {
140 | NSMutableDictionary *json = [NSMutableDictionary new];
141 |
142 | json[@"message"] = self.message.toJson;
143 |
144 | return json;
145 | }
146 | @end
147 |
148 | @implementation OSInAppMessageClickEvent (Flutter)
149 | - (NSDictionary *)toJson {
150 | NSMutableDictionary *json = [NSMutableDictionary new];
151 |
152 | json[@"message"] = self.message.toJson;
153 | json[@"result"] = self.result.toJson;
154 |
155 | return json;
156 | }
157 | @end
158 |
159 | @implementation OSInAppMessageClickResult (Flutter)
160 | - (NSDictionary *)toJson {
161 | NSMutableDictionary *json = [NSMutableDictionary new];
162 |
163 | json[@"action_id"] = self.actionId;
164 | json[@"url"] = self.url;
165 | json[@"closing_message"] = @(self.closingMessage);
166 |
167 | return json;
168 | }
169 | @end
170 |
171 | @implementation OSInAppMessage (Flutter)
172 | - (NSDictionary *)toJson {
173 | NSMutableDictionary *json = [NSMutableDictionary new];
174 |
175 | json[@"message_id"] = self.messageId;
176 |
177 | return json;
178 | }
179 | @end
180 |
181 | @implementation NSError (Flutter)
182 | - (FlutterError *)flutterError {
183 | return [FlutterError errorWithCode:[NSString stringWithFormat:@"%i", (int)self.code] message:self.localizedDescription details:nil];
184 | }
185 | @end
186 |
--------------------------------------------------------------------------------
/ios/Classes/OSFlutterDebug.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Modified MIT License
3 | *
4 | * Copyright 2017 OneSignal
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * 1. The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * 2. All copies of substantial portions of the Software may only be used in connection
17 | * with services provided by OneSignal.
18 | *
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | * THE SOFTWARE.
26 | */
27 |
28 |
29 | #import
30 | #import
31 |
32 | @interface OSFlutterDebug : NSObject
33 |
34 | @property (strong, nonatomic) FlutterMethodChannel *channel;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/ios/Classes/OSFlutterDebug.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Modified MIT License
3 | *
4 | * Copyright 2023 OneSignal
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * 1. The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * 2. All copies of substantial portions of the Software may only be used in connection
17 | * with services provided by OneSignal.
18 | *
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | * THE SOFTWARE.
26 | */
27 |
28 | #import "OSFlutterDebug.h"
29 | #import
30 | #import "OSFlutterCategories.h"
31 |
32 | @implementation OSFlutterDebug
33 | + (void)registerWithRegistrar:(NSObject*)registrar {
34 | OSFlutterDebug *instance = [OSFlutterDebug new];
35 |
36 | instance.channel = [FlutterMethodChannel
37 | methodChannelWithName:@"OneSignal#debug"
38 | binaryMessenger:[registrar messenger]];
39 |
40 | [registrar addMethodCallDelegate:instance channel:instance.channel];
41 | }
42 |
43 | - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
44 | if ([@"OneSignal#setLogLevel" isEqualToString:call.method])
45 | [self setLogLevel:call withResult:result];
46 | else if ([@"OneSignal#setAlertLevel" isEqualToString:call.method])
47 | [self setAlertLevel:call withResult:result];
48 | else
49 | result(FlutterMethodNotImplemented);
50 | }
51 |
52 | - (void)setLogLevel:(FlutterMethodCall *)call withResult:(FlutterResult)result{
53 | ONE_S_LOG_LEVEL logLevel = (ONE_S_LOG_LEVEL)[call.arguments[@"logLevel"] intValue];
54 | [OneSignal.Debug setLogLevel:logLevel];
55 | result(nil);
56 | }
57 |
58 | - (void)setAlertLevel:(FlutterMethodCall *)call withResult:(FlutterResult)result{
59 | ONE_S_LOG_LEVEL visualLogLevel = (ONE_S_LOG_LEVEL)[call.arguments[@"visualLevel"] intValue];
60 | [OneSignal.Debug setAlertLevel:visualLogLevel];
61 | result(nil);
62 | }
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/ios/Classes/OSFlutterInAppMessages.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Modified MIT License
3 | *
4 | * Copyright 2017 OneSignal
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * 1. The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * 2. All copies of substantial portions of the Software may only be used in connection
17 | * with services provided by OneSignal.
18 | *
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | * THE SOFTWARE.
26 | */
27 |
28 |
29 | #import
30 | #import
31 | #import
32 |
33 | @interface OSFlutterInAppMessages : NSObject
34 |
35 | @property (strong, nonatomic) FlutterMethodChannel *channel;
36 | + (instancetype)sharedInstance;
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/ios/Classes/OSFlutterInAppMessages.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Modified MIT License
3 | *
4 | * Copyright 2023 OneSignal
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * 1. The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * 2. All copies of substantial portions of the Software may only be used in connection
17 | * with services provided by OneSignal.
18 | *
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | * THE SOFTWARE.
26 | */
27 |
28 | #import "OSFlutterInAppMessages.h"
29 | #import
30 | #import "OSFlutterCategories.h"
31 |
32 | @implementation OSFlutterInAppMessages
33 |
34 | + (instancetype)sharedInstance {
35 | static OSFlutterInAppMessages *sharedInstance = nil;
36 | static dispatch_once_t onceToken;
37 | dispatch_once(&onceToken, ^{
38 | sharedInstance = [OSFlutterInAppMessages new];
39 | });
40 | return sharedInstance;
41 | }
42 |
43 | + (void)registerWithRegistrar:(NSObject*)registrar {
44 |
45 | OSFlutterInAppMessages.sharedInstance.channel = [FlutterMethodChannel
46 | methodChannelWithName:@"OneSignal#inappmessages"
47 | binaryMessenger:[registrar messenger]];
48 |
49 | [registrar addMethodCallDelegate:OSFlutterInAppMessages.sharedInstance channel:OSFlutterInAppMessages.sharedInstance.channel];
50 | }
51 |
52 | - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
53 | if ([@"OneSignal#addTrigger" isEqualToString:call.method])
54 | [self addTriggers:call withResult:result];
55 | else if ([@"OneSignal#addTriggers" isEqualToString:call.method])
56 | [self addTriggers:call withResult:result];
57 | else if ([@"OneSignal#removeTrigger" isEqualToString:call.method])
58 | [self removeTrigger:call withResult:result];
59 | else if ([@"OneSignal#removeTriggers" isEqualToString:call.method])
60 | [self removeTriggers:call withResult:result];
61 | else if ([@"OneSignal#clearTriggers" isEqualToString:call.method])
62 | [self clearTriggers:call withResult:result];
63 | else if ([@"OneSignal#paused" isEqualToString:call.method])
64 | [self paused:call withResult:result];
65 | else if ([@"OneSignal#arePaused" isEqualToString:call.method])
66 | result(@([OneSignal.InAppMessages paused]));
67 | else if ([@"OneSignal#lifecycleInit" isEqualToString:call.method])
68 | [self lifecycleInit:call withResult:result];
69 | else
70 | result(FlutterMethodNotImplemented);
71 |
72 | }
73 |
74 | - (void)addTriggers:(FlutterMethodCall *)call withResult:(FlutterResult)result {
75 | NSDictionary *triggers = call.arguments;
76 | [OneSignal.InAppMessages addTriggers:triggers];
77 | result(nil);
78 | }
79 |
80 | - (void)removeTrigger:(FlutterMethodCall *)call withResult:(FlutterResult)result {
81 | NSString *key = call.arguments;
82 | [OneSignal.InAppMessages removeTrigger:key];
83 | result(nil);
84 | }
85 |
86 | - (void)removeTriggers:(FlutterMethodCall *)call withResult:(FlutterResult)result {
87 | NSArray *keys = call.arguments;
88 | [OneSignal.InAppMessages removeTriggers:keys];
89 | result(nil);
90 | }
91 |
92 | - (void)clearTriggers:(FlutterMethodCall *)call withResult:(FlutterResult)result {
93 | [OneSignal.InAppMessages clearTriggers];
94 | result(nil);
95 | }
96 |
97 | - (void)paused:(FlutterMethodCall *)call withResult:(FlutterResult)result {
98 | BOOL pause = [call.arguments boolValue];
99 | [OneSignal.InAppMessages paused:pause];
100 | result(nil);
101 | }
102 |
103 | - (void)lifecycleInit:(FlutterMethodCall *)call withResult:(FlutterResult)result {
104 | [OneSignal.InAppMessages addClickListener:OSFlutterInAppMessages.sharedInstance];
105 | [OneSignal.InAppMessages addLifecycleListener:OSFlutterInAppMessages.sharedInstance];
106 | }
107 |
108 |
109 |
110 | #pragma mark In App Message Click
111 |
112 | - (void)onClickInAppMessage:(OSInAppMessageClickEvent * _Nonnull)event {
113 | [self.channel invokeMethod:@"OneSignal#onClickInAppMessage" arguments:event.toJson];
114 | }
115 |
116 | #pragma mark OSInAppMessageLifecycleListener
117 | - (void)onWillDisplayInAppMessage:(OSInAppMessageWillDisplayEvent *) event {
118 | [self.channel invokeMethod:@"OneSignal#onWillDisplayInAppMessage" arguments:event.toJson];
119 | }
120 |
121 | - (void)onDidDisplayInAppMessage:(OSInAppMessageDidDisplayEvent *) event {
122 | [self.channel invokeMethod:@"OneSignal#onDidDisplayInAppMessage" arguments:event.toJson];
123 | }
124 |
125 | - (void)onWillDismissInAppMessage:(OSInAppMessageWillDismissEvent *) event {
126 | [self.channel invokeMethod:@"OneSignal#onWillDismissInAppMessage" arguments:event.toJson];
127 | }
128 |
129 | - (void)onDidDismissInAppMessage:(OSInAppMessageDidDismissEvent *) event {
130 | [self.channel invokeMethod:@"OneSignal#onDidDismissInAppMessage" arguments:event.toJson];
131 | }
132 |
133 | @end
134 |
--------------------------------------------------------------------------------
/ios/Classes/OSFlutterLiveActivities.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Modified MIT License
3 | *
4 | * Copyright 2023 OneSignal
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * 1. The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * 2. All copies of substantial portions of the Software may only be used in connection
17 | * with services provided by OneSignal.
18 | *
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | * THE SOFTWARE.
26 | */
27 |
28 | #import
29 | #import
30 |
31 | @interface OSFlutterLiveActivities : NSObject
32 |
33 | @property (strong, nonatomic) FlutterMethodChannel *channel;
34 |
35 | @end
--------------------------------------------------------------------------------
/ios/Classes/OSFlutterLiveActivities.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Modified MIT License
3 | *
4 | * Copyright 2023 OneSignal
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * 1. The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * 2. All copies of substantial portions of the Software may only be used in connection
17 | * with services provided by OneSignal.
18 | *
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | * THE SOFTWARE.
26 | */
27 |
28 | #import "OSFlutterLiveActivities.h"
29 | #import
30 | #import "OneSignalLiveActivities/OneSignalLiveActivities-Swift.h"
31 | #import "OSFlutterCategories.h"
32 |
33 | @implementation OSFlutterLiveActivities
34 | + (void)registerWithRegistrar:(NSObject*)registrar {
35 | OSFlutterLiveActivities *instance = [OSFlutterLiveActivities new];
36 |
37 | instance.channel = [FlutterMethodChannel
38 | methodChannelWithName:@"OneSignal#liveactivities"
39 | binaryMessenger:[registrar messenger]];
40 |
41 | [registrar addMethodCallDelegate:instance channel:instance.channel];
42 | }
43 |
44 | - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
45 | if ([@"OneSignal#enterLiveActivity" isEqualToString:call.method])
46 | [self enterLiveActivity:call withResult:result];
47 | else if ([@"OneSignal#exitLiveActivity" isEqualToString:call.method])
48 | [self exitLiveActivity:call withResult:result];
49 | else if ([@"OneSignal#setPushToStartToken" isEqualToString:call.method])
50 | [self setPushToStartToken:call withResult:result];
51 | else if ([@"OneSignal#removePushToStartToken" isEqualToString:call.method])
52 | [self removePushToStartToken:call withResult:result];
53 | else if ([@"OneSignal#setupDefault" isEqualToString:call.method])
54 | [self setupDefault:call withResult:result];
55 | else if ([@"OneSignal#startDefault" isEqualToString:call.method])
56 | [self startDefault:call withResult:result];
57 | else
58 | result(FlutterMethodNotImplemented);
59 | }
60 |
61 | - (void)enterLiveActivity:(FlutterMethodCall *)call withResult:(FlutterResult)result {
62 | NSString *activityId = call.arguments[@"activityId"];
63 | NSString *token = call.arguments[@"token"];
64 |
65 | [OneSignal.LiveActivities enter:activityId withToken:token withSuccess:^(NSDictionary *results) {
66 | result(results);
67 | } withFailure:^(NSError *error) {
68 | result(error.flutterError);
69 | }];
70 | }
71 |
72 | - (void)exitLiveActivity:(FlutterMethodCall *)call withResult:(FlutterResult)result {
73 | NSString *activityId = call.arguments[@"activityId"];
74 |
75 | [OneSignal.LiveActivities exit:activityId withSuccess:^(NSDictionary *results) {
76 | result(results);
77 | } withFailure:^(NSError *error) {
78 | result(error.flutterError);
79 | }];
80 | }
81 |
82 | - (void)setPushToStartToken:(FlutterMethodCall *)call withResult:(FlutterResult)result {
83 | NSString *activityType = call.arguments[@"activityType"];
84 | NSString *token = call.arguments[@"token"];
85 | NSError* err=nil;
86 |
87 | if (@available(iOS 17.2, *)) {
88 | [OneSignalLiveActivitiesManagerImpl setPushToStartToken:activityType withToken:token error:&err];
89 | if (err) {
90 | [OneSignalLog onesignalLog:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"activityType must be the name of your ActivityAttributes struct"]];
91 | }
92 | } else {
93 | [OneSignalLog onesignalLog:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"cannot setPushToStartToken on iOS < 17.2"]];
94 | }
95 |
96 | result(nil);
97 | }
98 |
99 | - (void)removePushToStartToken:(FlutterMethodCall *)call withResult:(FlutterResult)result {
100 | NSString *activityType = call.arguments[@"activityType"];
101 | NSError* err=nil;
102 |
103 | if (@available(iOS 17.2, *)) {
104 | [OneSignalLiveActivitiesManagerImpl removePushToStartToken:activityType error:&err];
105 | if (err) {
106 | [OneSignalLog onesignalLog:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"activityType must be the name of your ActivityAttributes struct"]];
107 | }
108 | } else {
109 | [OneSignalLog onesignalLog:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"cannot removePushToStartToken on iOS < 17.2"]];
110 | }
111 |
112 | result(nil);
113 | }
114 |
115 | - (void)setupDefault:(FlutterMethodCall *)call withResult:(FlutterResult)result {
116 | NSDictionary *options = call.arguments[@"options"];
117 |
118 | LiveActivitySetupOptions *laOptions = nil;
119 |
120 | if (options != [NSNull null]) {
121 | laOptions = [LiveActivitySetupOptions alloc];
122 | [laOptions setEnablePushToStart:[options[@"enablePushToStart"] boolValue]];
123 | [laOptions setEnablePushToUpdate:[options[@"enablePushToUpdate"] boolValue]];
124 | }
125 |
126 | if (@available(iOS 16.1, *)) {
127 | [OneSignalLiveActivitiesManagerImpl setupDefaultWithOptions:laOptions];
128 | } else {
129 | [OneSignalLog onesignalLog:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"cannot setupDefault on iOS < 16.1"]];
130 | }
131 |
132 | result(nil);
133 | }
134 |
135 | - (void)startDefault:(FlutterMethodCall *)call withResult:(FlutterResult)result {
136 | NSString *activityId = call.arguments[@"activityId"];
137 | NSDictionary *attributes = call.arguments[@"attributes"];
138 | NSDictionary *content = call.arguments[@"content"];
139 |
140 | if (@available(iOS 16.1, *)) {
141 | [OneSignalLiveActivitiesManagerImpl startDefault:activityId attributes:attributes content:content];
142 | } else {
143 | [OneSignalLog onesignalLog:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"cannot startDefault on iOS < 16.1"]];
144 | }
145 |
146 | result(nil);
147 | }
148 |
149 | @end
150 |
--------------------------------------------------------------------------------
/ios/Classes/OSFlutterLocation.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Modified MIT License
3 | *
4 | * Copyright 2017 OneSignal
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * 1. The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * 2. All copies of substantial portions of the Software may only be used in connection
17 | * with services provided by OneSignal.
18 | *
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | * THE SOFTWARE.
26 | */
27 |
28 |
29 | #import
30 | #import
31 |
32 | @interface OSFlutterLocation : NSObject
33 |
34 | @property (strong, nonatomic) FlutterMethodChannel *channel;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/ios/Classes/OSFlutterLocation.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Modified MIT License
3 | *
4 | * Copyright 2023 OneSignal
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * 1. The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * 2. All copies of substantial portions of the Software may only be used in connection
17 | * with services provided by OneSignal.
18 | *
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | * THE SOFTWARE.
26 | */
27 |
28 | #import "OSFlutterLocation.h"
29 | #import
30 | #import "OSFlutterCategories.h"
31 |
32 | @implementation OSFlutterLocation
33 | + (void)registerWithRegistrar:(NSObject*)registrar {
34 | OSFlutterLocation *instance = [OSFlutterLocation new];
35 |
36 | instance.channel = [FlutterMethodChannel
37 | methodChannelWithName:@"OneSignal#location"
38 | binaryMessenger:[registrar messenger]];
39 |
40 | [registrar addMethodCallDelegate:instance channel:instance.channel];
41 | }
42 |
43 | - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
44 | if ([@"OneSignal#requestPermission" isEqualToString:call.method])
45 | [self requestPermission:call withResult:result];
46 | else if ([@"OneSignal#setShared" isEqualToString:call.method])
47 | [self setLocationShared:call withResult:result];
48 | else if ([@"OneSignal#isShared" isEqualToString:call.method])
49 | result(@([OneSignal.Location isShared]));
50 | else
51 | result(FlutterMethodNotImplemented);
52 | }
53 |
54 | - (void)setLocationShared:(FlutterMethodCall *)call withResult:(FlutterResult)result {
55 | BOOL locationShared = [call.arguments boolValue];
56 | [OneSignal.Location setShared:locationShared];
57 | result(nil);
58 | }
59 |
60 | - (void)requestPermission:(FlutterMethodCall *)call withResult:(FlutterResult)result {
61 | [OneSignal.Location requestPermission];
62 | result(nil);
63 | }
64 |
65 |
66 |
67 | @end
68 |
--------------------------------------------------------------------------------
/ios/Classes/OSFlutterNotifications.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Modified MIT License
3 | *
4 | * Copyright 2017 OneSignal
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * 1. The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * 2. All copies of substantial portions of the Software may only be used in connection
17 | * with services provided by OneSignal.
18 | *
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | * THE SOFTWARE.
26 | */
27 |
28 |
29 | #import
30 | #import
31 | #import
32 |
33 | @interface OSFlutterNotifications : NSObject
34 |
35 | @property (strong, nonatomic) FlutterMethodChannel *channel;
36 | + (instancetype)sharedInstance;
37 | @property (strong, nonatomic) NSMutableDictionary* onWillDisplayEventCache;
38 | @property (strong, nonatomic) NSMutableDictionary* preventedDefaultCache;
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/ios/Classes/OSFlutterPushSubscription.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Modified MIT License
3 | *
4 | * Copyright 2017 OneSignal
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * 1. The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * 2. All copies of substantial portions of the Software may only be used in connection
17 | * with services provided by OneSignal.
18 | *
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | * THE SOFTWARE.
26 | */
27 |
28 |
29 | #import
30 | #import
31 | #import
32 |
33 | @interface OSFlutterPushSubscription : NSObject
34 |
35 | + (instancetype)sharedInstance;
36 | @property (strong, nonatomic) FlutterMethodChannel *channel;
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/ios/Classes/OSFlutterPushSubscription.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Modified MIT License
3 | *
4 | * Copyright 2023 OneSignal
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * 1. The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * 2. All copies of substantial portions of the Software may only be used in connection
17 | * with services provided by OneSignal.
18 | *
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | * THE SOFTWARE.
26 | */
27 |
28 | #import "OSFlutterPushSubscription.h"
29 | #import
30 | #import
31 | #import "OSFlutterCategories.h"
32 |
33 | @implementation OSFlutterPushSubscription
34 |
35 | + (void)registerWithRegistrar:(NSObject*)registrar {
36 | OSFlutterPushSubscription *instance = [OSFlutterPushSubscription new];
37 |
38 | instance.channel = [FlutterMethodChannel
39 | methodChannelWithName:@"OneSignal#pushsubscription"
40 | binaryMessenger:[registrar messenger]];
41 |
42 | [registrar addMethodCallDelegate:instance channel:instance.channel];
43 | }
44 |
45 | - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
46 | if ([@"OneSignal#pushSubscriptionId" isEqualToString:call.method])
47 | result(OneSignal.User.pushSubscription.id);
48 | else if ([@"OneSignal#pushSubscriptionToken" isEqualToString:call.method])
49 | result(OneSignal.User.pushSubscription.token);
50 | else if ([@"OneSignal#pushSubscriptionOptedIn" isEqualToString:call.method])
51 | result(@(OneSignal.User.pushSubscription.optedIn));
52 | else if ([@"OneSignal#optIn" isEqualToString:call.method])
53 | [self optIn:call withResult:result];
54 | else if ([@"OneSignal#optOut" isEqualToString:call.method])
55 | [self optOut:call withResult:result];
56 | else if ([@"OneSignal#lifecycleInit" isEqualToString:call.method])
57 | [self lifecycleInit:call withResult:result];
58 | else
59 | result(FlutterMethodNotImplemented);
60 | }
61 |
62 | - (void)optIn:(FlutterMethodCall *)call withResult:(FlutterResult)result {
63 | [OneSignal.User.pushSubscription optIn];
64 | result(nil);
65 | }
66 |
67 | - (void)optOut:(FlutterMethodCall *)call withResult:(FlutterResult)result {
68 | [OneSignal.User.pushSubscription optOut];
69 | result(nil);
70 | }
71 |
72 | - (void)lifecycleInit:(FlutterMethodCall *)call withResult:(FlutterResult)result {
73 | [OneSignal.User.pushSubscription addObserver:self];
74 | result(nil);
75 | }
76 |
77 | - (void)onPushSubscriptionDidChangeWithState:(OSPushSubscriptionChangedState *)state {
78 | [self.channel invokeMethod:@"OneSignal#onPushSubscriptionChange" arguments:state.jsonRepresentation];
79 | }
80 |
81 | @end
82 |
83 |
--------------------------------------------------------------------------------
/ios/Classes/OSFlutterSession.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Modified MIT License
3 | *
4 | * Copyright 2017 OneSignal
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * 1. The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * 2. All copies of substantial portions of the Software may only be used in connection
17 | * with services provided by OneSignal.
18 | *
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | * THE SOFTWARE.
26 | */
27 |
28 |
29 | #import
30 | #import
31 |
32 | @interface OSFlutterSession : NSObject
33 |
34 | @property (strong, nonatomic) FlutterMethodChannel *channel;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/ios/Classes/OSFlutterSession.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Modified MIT License
3 | *
4 | * Copyright 2023 OneSignal
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * 1. The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * 2. All copies of substantial portions of the Software may only be used in connection
17 | * with services provided by OneSignal.
18 | *
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | * THE SOFTWARE.
26 | */
27 |
28 | #import "OSFlutterSession.h"
29 | #import
30 | #import "OSFlutterCategories.h"
31 |
32 | @implementation OSFlutterSession
33 | + (void)registerWithRegistrar:(NSObject*)registrar {
34 | OSFlutterSession *instance = [OSFlutterSession new];
35 |
36 | instance.channel = [FlutterMethodChannel
37 | methodChannelWithName:@"OneSignal#session"
38 | binaryMessenger:[registrar messenger]];
39 |
40 | [registrar addMethodCallDelegate:instance channel:instance.channel];
41 | }
42 |
43 | - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
44 | if ([@"OneSignal#addOutcome" isEqualToString:call.method]) {
45 | [self addOutcome:call withResult:result];
46 | } else if ([@"OneSignal#addUniqueOutcome" isEqualToString:call.method]) {
47 | [self addUniqueOutcome:call withResult:result];
48 | } else if ([@"OneSignal#addOutcomeWithValue" isEqualToString:call.method]) {
49 | [self addOutcomeWithValue:call withResult:result];
50 | } else {
51 | result(FlutterMethodNotImplemented);
52 | }
53 | }
54 |
55 | - (void)addOutcome:(FlutterMethodCall *)call withResult:(FlutterResult)result {
56 | NSString *name = call.arguments;
57 | [OneSignal.Session addOutcome:name];
58 | result(nil);
59 | }
60 |
61 | - (void)addUniqueOutcome:(FlutterMethodCall *)call withResult:(FlutterResult)result {
62 | NSString *name = call.arguments;
63 | [OneSignal.Session addUniqueOutcome:name];
64 | result(nil);
65 | }
66 |
67 | - (void)addOutcomeWithValue:(FlutterMethodCall *)call withResult:(FlutterResult)result {
68 | NSString *name = call.arguments[@"outcome_name"];
69 | NSNumber *value = call.arguments[@"outcome_value"];
70 | [OneSignal.Session addOutcomeWithValue:name value:value];
71 | result(nil);
72 | }
73 |
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/ios/Classes/OSFlutterUser.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Modified MIT License
3 | *
4 | * Copyright 2017 OneSignal
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * 1. The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * 2. All copies of substantial portions of the Software may only be used in connection
17 | * with services provided by OneSignal.
18 | *
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | * THE SOFTWARE.
26 | */
27 |
28 |
29 | #import
30 | #import
31 |
32 | @interface OSFlutterUser : NSObject
33 |
34 | @property (strong, nonatomic) FlutterMethodChannel *channel;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/ios/Classes/OneSignalPlugin.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Modified MIT License
3 | *
4 | * Copyright 2017 OneSignal
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * 1. The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * 2. All copies of substantial portions of the Software may only be used in connection
17 | * with services provided by OneSignal.
18 | *
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | * THE SOFTWARE.
26 | */
27 |
28 | #import
29 | #import
30 |
31 | @interface OneSignalPlugin : NSObject
32 |
33 | // Do NOT initialize instances of this class.
34 | // You must only reference the shared instance.
35 | + (instancetype)sharedInstance;
36 | @end
37 |
--------------------------------------------------------------------------------
/ios/Classes/OneSignalPlugin.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Modified MIT License
3 | *
4 | * Copyright 2023 OneSignal
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * 1. The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * 2. All copies of substantial portions of the Software may only be used in connection
17 | * with services provided by OneSignal.
18 | *
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | * THE SOFTWARE.
26 | */
27 |
28 | #import "OneSignalPlugin.h"
29 | #import "OSFlutterCategories.h"
30 | #import "OSFlutterDebug.h"
31 | #import "OSFlutterUser.h"
32 | #import "OSFlutterNotifications.h"
33 | #import "OSFlutterSession.h"
34 | #import "OSFlutterLocation.h"
35 | #import "OSFlutterInAppMessages.h"
36 | #import "OSFlutterLiveActivities.h"
37 |
38 |
39 | @interface OneSignalPlugin ()
40 |
41 | @property (strong, nonatomic) FlutterMethodChannel *channel;
42 |
43 | @end
44 |
45 | @implementation OneSignalPlugin
46 |
47 | + (instancetype)sharedInstance {
48 | static OneSignalPlugin *sharedInstance = nil;
49 | static dispatch_once_t onceToken;
50 | dispatch_once(&onceToken, ^{
51 | sharedInstance = [OneSignalPlugin new];
52 | });
53 | return sharedInstance;
54 | }
55 |
56 | #pragma mark FlutterPlugin
57 | + (void)registerWithRegistrar:(NSObject*)registrar {
58 |
59 | OneSignalWrapper.sdkType = @"flutter";
60 | OneSignalWrapper.sdkVersion = @"050303";
61 | [OneSignal initialize:nil withLaunchOptions:nil];
62 |
63 | OneSignalPlugin.sharedInstance.channel = [FlutterMethodChannel
64 | methodChannelWithName:@"OneSignal"
65 | binaryMessenger:[registrar messenger]];
66 |
67 | [registrar addMethodCallDelegate:OneSignalPlugin.sharedInstance channel:OneSignalPlugin.sharedInstance.channel];
68 | [OSFlutterDebug registerWithRegistrar:registrar];
69 | [OSFlutterUser registerWithRegistrar:registrar];
70 | [OSFlutterNotifications registerWithRegistrar:registrar];
71 | [OSFlutterSession registerWithRegistrar:registrar];
72 | [OSFlutterLocation registerWithRegistrar:registrar];
73 | [OSFlutterInAppMessages registerWithRegistrar:registrar];
74 | [OSFlutterLiveActivities registerWithRegistrar:registrar];
75 | }
76 |
77 | - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
78 | if ([@"OneSignal#initialize" isEqualToString:call.method])
79 | [self initialize:call withResult:result];
80 | else if ([@"OneSignal#login" isEqualToString:call.method])
81 | [self login:call withResult:result];
82 | else if ([@"OneSignal#logout" isEqualToString:call.method])
83 | [self logout:call withResult:result];
84 | else if ([@"OneSignal#consentRequired" isEqualToString:call.method])
85 | [self setConsentRequired:call withResult:result];
86 | else if ([@"OneSignal#consentGiven" isEqualToString:call.method])
87 | [self setConsentGiven:call withResult:result];
88 | else
89 | result(FlutterMethodNotImplemented);
90 | }
91 |
92 | #pragma mark Init
93 |
94 | - (void)initialize:(FlutterMethodCall *)call withResult:(FlutterResult)result{
95 | [OneSignal initialize:call.arguments[@"appId"] withLaunchOptions:nil];
96 | result(nil);
97 | }
98 |
99 | #pragma mark Login Logout
100 |
101 | - (void)login:(FlutterMethodCall *)call withResult:(FlutterResult)result{
102 | [OneSignal login:call.arguments[@"externalId"]];
103 | result(nil);
104 | }
105 |
106 | - (void)logout:(FlutterMethodCall *)call withResult:(FlutterResult)result{
107 | [OneSignal logout];
108 | result(nil);
109 | }
110 |
111 | #pragma mark Privacy Consent
112 |
113 | - (void)setConsentGiven:(FlutterMethodCall *)call withResult:(FlutterResult)result{
114 | BOOL granted = [call.arguments[@"granted"] boolValue];
115 | [OneSignal setConsentGiven:granted];
116 | result(nil);
117 | }
118 |
119 | - (void)setConsentRequired:(FlutterMethodCall *)call withResult:(FlutterResult)result{
120 | BOOL required = [call.arguments[@"required"] boolValue];
121 | [OneSignal setConsentRequired:required];
122 | result(nil);
123 | }
124 |
125 | @end
126 |
--------------------------------------------------------------------------------
/ios/onesignal_flutter.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
3 | #
4 | Pod::Spec.new do |s|
5 | s.name = 'onesignal_flutter'
6 | s.version = '5.3.3'
7 | s.summary = 'The OneSignal Flutter SDK'
8 | s.description = 'Allows you to easily add OneSignal to your flutter projects, to make sending and handling push notifications easy'
9 | s.homepage = 'https://www.onesignal.com'
10 | s.license = { :file => '../LICENSE' }
11 | s.author = { 'Brad Hesse' => 'brad@onesignal.com', 'Josh Kasten' => 'josh@onesignal.com' }
12 | s.source = { :path => '.' }
13 | s.source_files = 'Classes/**/*'
14 | s.public_header_files = 'Classes/**/*.h'
15 | s.dependency 'Flutter'
16 | s.dependency 'OneSignalXCFramework', '5.2.13'
17 | s.ios.deployment_target = '11.0'
18 | s.static_framework = true
19 | end
20 |
--------------------------------------------------------------------------------
/lib/onesignal_flutter.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:io' show Platform;
3 | import 'package:flutter/services.dart';
4 | import 'package:onesignal_flutter/src/debug.dart';
5 | import 'package:onesignal_flutter/src/user.dart';
6 | import 'package:onesignal_flutter/src/notifications.dart';
7 | import 'package:onesignal_flutter/src/session.dart';
8 | import 'package:onesignal_flutter/src/location.dart';
9 | import 'package:onesignal_flutter/src/inappmessages.dart';
10 | import 'package:onesignal_flutter/src/liveactivities.dart';
11 |
12 | export 'src/defines.dart';
13 | export 'src/pushsubscription.dart';
14 | export 'src/subscription.dart';
15 | export 'src/notification.dart';
16 | export 'src/notifications.dart';
17 | export 'src/inappmessage.dart';
18 | export 'src/inappmessages.dart';
19 | export 'src/liveactivities.dart';
20 |
21 | class OneSignal {
22 | /// A singleton representing the OneSignal SDK.
23 | /// Note that the iOS and Android native libraries are static,
24 | /// so if you create multiple instances of OneSignal, they will
25 | /// mostly share the same state.
26 | // ignore: non_constant_identifier_names
27 | static OneSignalDebug Debug = new OneSignalDebug();
28 | // ignore: non_constant_identifier_names
29 | static OneSignalUser User = new OneSignalUser();
30 | // ignore: non_constant_identifier_names
31 | static OneSignalNotifications Notifications = new OneSignalNotifications();
32 | // ignore: non_constant_identifier_names
33 | static OneSignalSession Session = new OneSignalSession();
34 | // ignore: non_constant_identifier_names
35 | static OneSignalLocation Location = new OneSignalLocation();
36 | // ignore: non_constant_identifier_names
37 | static OneSignalInAppMessages InAppMessages = new OneSignalInAppMessages();
38 | // ignore: non_constant_identifier_names
39 | static OneSignalLiveActivities LiveActivities = new OneSignalLiveActivities();
40 |
41 | // private channels used to bridge to ObjC/Java
42 | static MethodChannel _channel = const MethodChannel('OneSignal');
43 |
44 | /// The initializer for OneSignal.
45 | ///
46 | /// The initializer accepts an [appId] which the developer can get
47 | /// from the OneSignal consoleas well as a dictonary of [launchOptions]
48 | static void initialize(String appId) {
49 | _channel.invokeMethod('OneSignal#initialize', {'appId': appId});
50 | InAppMessages.lifecycleInit();
51 | User.lifecycleInit();
52 | User.pushSubscription.lifecycleInit();
53 | Notifications.lifecycleInit();
54 | }
55 |
56 | /// Login to OneSignal under the user identified by the [externalId] provided.
57 | ///
58 | /// The act of logging a user into the OneSignal SDK will switch the
59 | /// user context to that specific user.
60 | static Future login(String externalId) async {
61 | return await _channel
62 | .invokeMethod('OneSignal#login', {'externalId': externalId});
63 | }
64 |
65 | /// Login to OneSignal under the user identified by the [externalId] provided.
66 | ///
67 | /// The act of logging a user into the OneSignal SDK will switch the
68 | /// user context to that specific user.
69 | @Deprecated(
70 | 'Do not use, this method is not implemented. See https://documentation.onesignal.com/docs/identity-verification for updates.')
71 | static Future loginWithJWT(String externalId, String jwt) async {
72 | if (Platform.isAndroid) {
73 | return await _channel.invokeMethod(
74 | 'OneSignal#loginWithJWT', {'externalId': externalId, 'jwt': jwt});
75 | }
76 | }
77 |
78 | /// Logout the user previously logged in via [login]. The user property now
79 | ///
80 | /// references a new device-scoped user. A device-scoped user has no user identity
81 | /// that can later be retrieved, except through this device as long as the app
82 | /// remains installed and the app data is not cleared.
83 | static Future logout() async {
84 | return await _channel.invokeMethod('OneSignal#logout');
85 | }
86 |
87 | /// Sets the whether or not privacy consent has been [granted]
88 | ///
89 | /// This field is only relevant when the application has
90 | /// opted into data privacy protections. See [consentRequired].
91 | static Future consentGiven(bool granted) async {
92 | return await _channel
93 | .invokeMethod("OneSignal#consentGiven", {'granted': granted});
94 | }
95 |
96 | /// Allows you to completely disable the SDK until your app calls the
97 | /// OneSignal.consentGiven(true) function. This is useful if you want
98 | /// to show a Terms and Conditions or privacy popup for GDPR.
99 | static Future consentRequired(bool require) async {
100 | return await _channel
101 | .invokeMethod("OneSignal#consentRequired", {'required': require});
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/lib/src/debug.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'package:flutter/services.dart';
3 | import 'package:onesignal_flutter/src/defines.dart';
4 |
5 | class OneSignalDebug {
6 | // private channels used to bridge to ObjC/Java
7 | MethodChannel _channel = const MethodChannel('OneSignal#debug');
8 |
9 | /// Sets the log level for the SDK.
10 | ///
11 | /// The parameter [logLevel] controls
12 | /// how verbose logs in the console/logcat are
13 | Future setLogLevel(OSLogLevel logLevel) async {
14 | return await _channel
15 | .invokeMethod("OneSignal#setLogLevel", {'logLevel': logLevel.index});
16 | }
17 |
18 | /// Sets the log level for the SDK.
19 | ///
20 | /// The parameter [visualLevel] controls
21 | /// if the SDK will show alerts for each logged message
22 | Future setAlertLevel(OSLogLevel visualLevel) async {
23 | return await _channel.invokeMethod(
24 | "OneSignal#setAlertLevel", {'visualLevel': visualLevel.index});
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/lib/src/defines.dart:
--------------------------------------------------------------------------------
1 | // Determines how notifications should be displayed
2 | enum OSNotificationDisplayType { none, alert, notification }
3 |
4 | /// Indicates whether a user tapped a notification (`opened`)
5 | /// or took a specific action by tapping a button (`actionTaken`)
6 | enum OSNotificationActionType { opened, actionTaken }
7 |
8 | enum OSNotificationPermission {
9 | notDetermined,
10 | denied,
11 | authorized,
12 | provisional, // only available in iOS 12
13 | ephemeral, // only available in iOS 14
14 | }
15 |
16 | /// An enum that declares different types of log levels you can
17 | /// use with the OneSignal SDK, going from the least verbose (none)
18 | /// to verbose (print all comments).
19 | enum OSLogLevel { none, fatal, error, warn, info, debug, verbose }
20 |
21 | /// Various iOS Settings that can be passed during initialization
22 | enum OSiOSSettings {
23 | autoPrompt,
24 | inAppAlerts,
25 | inAppLaunchUrl,
26 | promptBeforeOpeningPushUrl,
27 | inFocusDisplayOption
28 | }
29 |
30 | enum OSSession { DIRECT, INDIRECT, UNATTRIBUTED, DISABLED }
31 |
32 | /// Applies to iOS notifications only
33 | /// Determines if the badgeCount is used to increment
34 | /// the existing badge count, or sets the badge count directly
35 | enum OSCreateNotificationBadgeType { increase, setTo }
36 |
37 | /// control how the notification is delayed
38 | /// timezone: Deliver at a specific time of day in each user's timezone
39 | /// last-active: Deliver at the same time the user last used your app
40 | enum OSCreateNotificationDelayOption { timezone, lastActive }
41 |
--------------------------------------------------------------------------------
/lib/src/inappmessage.dart:
--------------------------------------------------------------------------------
1 | import 'package:onesignal_flutter/src/utils.dart';
2 |
3 | /// When a click action is defined on an In App Message form the dashboard,
4 | /// the handler returns an OSInAppMessageClickEvent object so the Dart code can act accordingly
5 | /// This event includes the message and the result of the click
6 | class OSInAppMessageClickEvent extends JSONStringRepresentable {
7 | late OSInAppMessage message;
8 |
9 | late OSInAppMessageClickResult result;
10 |
11 | OSInAppMessageClickEvent(Map json) {
12 | this.message = OSInAppMessage(json["message"].cast());
13 | this.result =
14 | OSInAppMessageClickResult(json["result"].cast());
15 | }
16 |
17 | String jsonRepresentation() {
18 | return convertToJsonString({
19 | 'message': this.message,
20 | 'result': this.result,
21 | });
22 | }
23 | }
24 |
25 | /// When a click action is defined on an In App Message form the dashboard,
26 | /// the handler returns an OSInAppMessageAction object so the Dart code can act accordingly
27 | /// This allows for custom action events within Dart
28 | class OSInAppMessageClickResult extends JSONStringRepresentable {
29 | // Name of the action event defined for the IAM element
30 | String? actionId;
31 |
32 | // URL given to the IAM element defined in the dashboard
33 | String? url;
34 |
35 | // Whether or not the click action should dismiss the IAM
36 | bool closingMessage = false;
37 |
38 | OSInAppMessageClickResult(Map json) {
39 | this.actionId = json["action_id"];
40 | this.url = json["url"];
41 | this.closingMessage = json["closing_message"] as bool;
42 | }
43 |
44 | String jsonRepresentation() {
45 | return convertToJsonString({
46 | 'action_id': this.actionId,
47 | 'url': this.url,
48 | 'closing_message': this.closingMessage,
49 | });
50 | }
51 | }
52 |
53 | class OSInAppMessage extends JSONStringRepresentable {
54 | String? messageId;
55 |
56 | OSInAppMessage(Map json) {
57 | this.messageId = json["message_id"];
58 | }
59 |
60 | String jsonRepresentation() {
61 | return convertToJsonString({'message_id': this.messageId});
62 | }
63 | }
64 |
65 | class OSInAppMessageWillDisplayEvent extends JSONStringRepresentable {
66 | late OSInAppMessage message;
67 |
68 | OSInAppMessageWillDisplayEvent(Map json) {
69 | this.message = OSInAppMessage(json["message"].cast());
70 | }
71 |
72 | String jsonRepresentation() {
73 | return convertToJsonString({'message': this.message.jsonRepresentation()});
74 | }
75 | }
76 |
77 | class OSInAppMessageDidDisplayEvent extends JSONStringRepresentable {
78 | late OSInAppMessage message;
79 |
80 | OSInAppMessageDidDisplayEvent(Map json) {
81 | this.message = OSInAppMessage(json["message"].cast());
82 | }
83 |
84 | String jsonRepresentation() {
85 | return convertToJsonString({'message': this.message.jsonRepresentation()});
86 | }
87 | }
88 |
89 | class OSInAppMessageWillDismissEvent extends JSONStringRepresentable {
90 | late OSInAppMessage message;
91 |
92 | OSInAppMessageWillDismissEvent(Map json) {
93 | this.message = OSInAppMessage(json["message"].cast());
94 | }
95 |
96 | String jsonRepresentation() {
97 | return convertToJsonString({'message': this.message.jsonRepresentation()});
98 | }
99 | }
100 |
101 | class OSInAppMessageDidDismissEvent extends JSONStringRepresentable {
102 | late OSInAppMessage message;
103 |
104 | OSInAppMessageDidDismissEvent(Map json) {
105 | this.message = OSInAppMessage(json["message"].cast());
106 | }
107 |
108 | String jsonRepresentation() {
109 | return convertToJsonString({'message': this.message.jsonRepresentation()});
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/lib/src/inappmessages.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'package:flutter/services.dart';
3 | import 'package:onesignal_flutter/onesignal_flutter.dart';
4 | import 'package:onesignal_flutter/src/inappmessage.dart';
5 |
6 | typedef void OnClickInAppMessageListener(OSInAppMessageClickEvent event);
7 |
8 | typedef void OnWillDisplayInAppMessageListener(
9 | OSInAppMessageWillDisplayEvent event);
10 | typedef void OnDidDisplayInAppMessageListener(
11 | OSInAppMessageDidDisplayEvent event);
12 | typedef void OnWillDismissInAppMessageListener(
13 | OSInAppMessageWillDismissEvent event);
14 | typedef void OnDidDismissInAppMessageListener(
15 | OSInAppMessageDidDismissEvent event);
16 |
17 | class OneSignalInAppMessages {
18 | // private channels used to bridge to ObjC/Java
19 | MethodChannel _channel = const MethodChannel('OneSignal#inappmessages');
20 |
21 | // constructor method
22 | OneSignalInAppMessages() {
23 | this._channel.setMethodCallHandler(_handleMethod);
24 | }
25 |
26 | List _clickListeners =
27 | [];
28 | List _willDisplayListeners =
29 | [];
30 | List _didDisplayListeners =
31 | [];
32 | List _willDismissListeners =
33 | [];
34 | List _didDismissListeners =
35 | [];
36 |
37 | /// Adds a single key, value trigger, which will trigger an in app message
38 | /// if one exists matching the specific trigger added
39 | Future addTrigger(String key, String value) async {
40 | return await _channel.invokeMethod("OneSignal#addTrigger", {key: value});
41 | }
42 |
43 | /// Adds one or more key, value triggers, which will trigger in app messages
44 | /// (one at a time) if any exist matching the specific triggers added
45 | Future addTriggers(Map triggers) async {
46 | return await _channel.invokeMethod("OneSignal#addTriggers", triggers);
47 | }
48 |
49 | /// Remove a single key, value trigger to prevent an in app message from
50 | /// showing with that trigger
51 | Future removeTrigger(String key) async {
52 | return await _channel.invokeMethod("OneSignal#removeTrigger", key);
53 | }
54 |
55 | /// Remove one or more key, value triggers to prevent any in app messages
56 | /// from showing with those triggers
57 | Future removeTriggers(List keys) async {
58 | return await _channel.invokeMethod("OneSignal#removeTriggers", keys);
59 | }
60 |
61 | /// Get the trigger value associated with the key provided
62 | Future clearTriggers() async {
63 | return await _channel.invokeMethod("OneSignal#clearTriggers");
64 | }
65 |
66 | /// Toggles the showing of all in app messages
67 | Future paused(bool pause) async {
68 | return await _channel.invokeMethod("OneSignal#paused", pause);
69 | }
70 |
71 | /// Gets whether of not in app messages are paused
72 | Future arePaused() async {
73 | return await _channel.invokeMethod("OneSignal#arePaused");
74 | }
75 |
76 | Future lifecycleInit() async {
77 | return await _channel.invokeMethod("OneSignal#lifecycleInit");
78 | }
79 |
80 | // Private function that gets called by ObjC/Java
81 | Future _handleMethod(MethodCall call) async {
82 | if (call.method == 'OneSignal#onClickInAppMessage') {
83 | for (var listener in _clickListeners) {
84 | listener(
85 | OSInAppMessageClickEvent(call.arguments.cast()));
86 | }
87 | } else if (call.method == 'OneSignal#onWillDisplayInAppMessage') {
88 | for (var listener in _willDisplayListeners) {
89 | listener(OSInAppMessageWillDisplayEvent(
90 | call.arguments.cast()));
91 | }
92 | } else if (call.method == 'OneSignal#onDidDisplayInAppMessage') {
93 | for (var listener in _didDisplayListeners) {
94 | listener(OSInAppMessageDidDisplayEvent(
95 | call.arguments.cast()));
96 | }
97 | } else if (call.method == 'OneSignal#onWillDismissInAppMessage') {
98 | for (var listener in _willDismissListeners) {
99 | listener(OSInAppMessageWillDismissEvent(
100 | call.arguments.cast()));
101 | }
102 | } else if (call.method == 'OneSignal#onDidDismissInAppMessage') {
103 | for (var listener in _didDismissListeners) {
104 | listener(OSInAppMessageDidDismissEvent(
105 | call.arguments.cast()));
106 | }
107 | }
108 | return null;
109 | }
110 |
111 | /// The in app message clicked handler is called whenever the user clicks a
112 | /// OneSignal IAM button or image with an action event attacthed to it
113 | void addClickListener(OnClickInAppMessageListener listener) {
114 | _clickListeners.add(listener);
115 | }
116 |
117 | void removeClickListener(OnClickInAppMessageListener listener) {
118 | _clickListeners.remove(listener);
119 | }
120 |
121 | void addWillDisplayListener(OnWillDisplayInAppMessageListener listener) {
122 | _willDisplayListeners.add(listener);
123 | }
124 |
125 | void removeWillDisplayListener(OnWillDisplayInAppMessageListener listener) {
126 | _willDisplayListeners.remove(listener);
127 | }
128 |
129 | void addDidDisplayListener(OnDidDisplayInAppMessageListener listener) {
130 | _didDisplayListeners.add(listener);
131 | }
132 |
133 | void removeDidDisplayListener(OnDidDisplayInAppMessageListener listener) {
134 | _didDisplayListeners.remove(listener);
135 | }
136 |
137 | void addWillDismissListener(OnWillDismissInAppMessageListener listener) {
138 | _willDismissListeners.add(listener);
139 | }
140 |
141 | void removeWillDismissListener(OnWillDismissInAppMessageListener listener) {
142 | _willDismissListeners.remove(listener);
143 | }
144 |
145 | void addDidDismissListener(OnDidDismissInAppMessageListener listener) {
146 | _didDismissListeners.add(listener);
147 | }
148 |
149 | void removeDidDismissListener(OnDidDismissInAppMessageListener listener) {
150 | _didDismissListeners.remove(listener);
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/lib/src/liveactivities.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:io';
3 | import 'package:flutter/services.dart';
4 |
5 | class OneSignalLiveActivities {
6 | // private channels used to bridge to ObjC/Java
7 | MethodChannel _channel = const MethodChannel('OneSignal#liveactivities');
8 |
9 | /// Indicate this device has exited a live activity, identified within OneSignal by the [activityId]. The
10 | /// [token] is the ActivityKit's update token that will be used to update the live activity.
11 | ///
12 | /// Only applies to iOS.
13 | Future enterLiveActivity(String activityId, String token) async {
14 | if (Platform.isIOS) {
15 | return await _channel.invokeMethod("OneSignal#enterLiveActivity",
16 | {'activityId': activityId, 'token': token});
17 | }
18 | }
19 |
20 | /// Indicate this device has exited a live activity, identified within OneSignal by the [activityId].
21 | ///
22 | /// Only applies to iOS.
23 | Future exitLiveActivity(String activityId) async {
24 | if (Platform.isIOS) {
25 | return await _channel.invokeMethod(
26 | "OneSignal#exitLiveActivity", {'activityId': activityId});
27 | }
28 | }
29 |
30 | /// Enable the OneSignalSDK to setup the default`DefaultLiveActivityAttributes` structure,
31 | /// which conforms to the `OneSignalLiveActivityAttributes`. When using this function, the
32 | /// widget attributes are owned by the OneSignal SDK, which will allow the SDK to handle the
33 | /// entire lifecycle of the live activity. All that is needed from an app-perspective is to
34 | /// create a Live Activity widget in a widget extension, with a `ActivityConfiguration` for
35 | /// `DefaultLiveActivityAttributes`. This is most useful for users that (1) only have one Live
36 | /// Activity widget and (2) are using a cross-platform framework and do not want to create the
37 | /// cross-platform <-> iOS native bindings to manage ActivityKit. An optional [options]
38 | /// parameter can be provided for more granular setup options.
39 | ///
40 | /// Only applies to iOS.
41 | Future setupDefault({LiveActivitySetupOptions? options}) async {
42 | if (Platform.isIOS) {
43 | dynamic optionsMap;
44 |
45 | if (options != null) {
46 | optionsMap = {
47 | 'enablePushToStart': options.enablePushToStart,
48 | 'enablePushToUpdate': options.enablePushToUpdate,
49 | };
50 | }
51 |
52 | return await _channel
53 | .invokeMethod("OneSignal#setupDefault", {'options': optionsMap});
54 | }
55 | }
56 |
57 | /// Start a new LiveActivity that is modelled by the default`DefaultLiveActivityAttributes`
58 | /// structure. The `DefaultLiveActivityAttributes` is initialized with the dynamic [attributes]
59 | /// and [content] passed in. The live activity started can be updated with the [activityId]
60 | /// provided.
61 | ///
62 | /// Only applies to iOS.
63 | Future startDefault(
64 | String activityId, dynamic attributes, dynamic content) async {
65 | if (Platform.isIOS) {
66 | return await _channel.invokeMethod("OneSignal#startDefault", {
67 | 'activityId': activityId,
68 | 'attributes': attributes,
69 | 'content': content
70 | });
71 | }
72 | }
73 |
74 | /// Indicate this device is capable of receiving pushToStart live activities for the
75 | /// [activityType]. The [activityType] **must** be the name of the struct conforming
76 | /// to `ActivityAttributes` that will be used to start the live activity. The [token]
77 | /// is ActivityKit's pushToStart token that will be used to start the live activity.
78 | ///
79 | /// Only applies to iOS.
80 | Future setPushToStartToken(String activityType, String token) async {
81 | if (Platform.isIOS) {
82 | return await _channel.invokeMethod("OneSignal#setPushToStartToken",
83 | {'activityType': activityType, 'token': token});
84 | }
85 | }
86 |
87 | /// Indicate this device is no longer capable of receiving pushToStart live activities
88 | /// for the [activityType]. The [activityType] **must** be the name of the struct conforming
89 | /// to `ActivityAttributes` that will be used to start the live activity.
90 | ///
91 | /// Only applies to iOS.
92 | Future removePushToStartToken(String activityType) async {
93 | if (Platform.isIOS) {
94 | return await _channel.invokeMethod(
95 | "OneSignal#removePushToStartToken", {'activityType': activityType});
96 | }
97 | }
98 | }
99 |
100 | /// The setup options for [OneSignal.LiveActivities.setupDefault].
101 | class LiveActivitySetupOptions {
102 | bool _enablePushToStart = true;
103 | bool _enablePushToUpdate = true;
104 |
105 | LiveActivitySetupOptions(
106 | {bool enablePushToStart = true, bool enablePushToUpdate = true}) {
107 | this._enablePushToStart = enablePushToStart;
108 | this._enablePushToUpdate = enablePushToUpdate;
109 | }
110 |
111 | /// When true, OneSignal will listen for pushToStart tokens.
112 | bool get enablePushToStart {
113 | return this._enablePushToStart;
114 | }
115 |
116 | /// When true, OneSignal will listen for pushToUpdate tokens for each started live activity.
117 | bool get enablePushToUpdate {
118 | return this._enablePushToUpdate;
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/lib/src/location.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'package:flutter/services.dart';
3 |
4 | class OneSignalLocation {
5 | // private channels used to bridge to ObjC/Java
6 | MethodChannel _channel = const MethodChannel('OneSignal#location');
7 |
8 | /// Allows you to prompt the user for permission to use location services
9 | Future requestPermission() async {
10 | return await _channel.invokeMethod("OneSignal#requestPermission");
11 | }
12 |
13 | /// Set whether location is currently shared with OneSignal.
14 | Future setShared(bool shared) async {
15 | return await _channel.invokeMethod("OneSignal#setShared", shared);
16 | }
17 |
18 | /// Allows you to determine if the user's location data is shared with OneSignal.
19 | /// This allows you to do things like geofenced notifications, etc.
20 | Future isShared() async {
21 | return await _channel.invokeMethod("OneSignal#isShared");
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/lib/src/permission.dart:
--------------------------------------------------------------------------------
1 | import 'package:onesignal_flutter/src/utils.dart';
2 |
3 | class OSPermissionState extends JSONStringRepresentable {
4 | bool permission = false;
5 | OSPermissionState(Map json) {
6 | if (json.containsKey('permission')) {
7 | permission = json['permission'] as bool;
8 | }
9 | }
10 |
11 | String jsonRepresentation() {
12 | return convertToJsonString({'permission': this.permission});
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/lib/src/pushsubscription.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'package:flutter/services.dart';
3 | import 'package:onesignal_flutter/src/subscription.dart';
4 |
5 | typedef void OnPushSubscriptionChangeObserver(
6 | OSPushSubscriptionChangedState stateChanges);
7 |
8 | class OneSignalPushSubscription {
9 | MethodChannel _channel = const MethodChannel('OneSignal#pushsubscription');
10 |
11 | String? _id;
12 | String? _token;
13 | bool? _optedIn;
14 |
15 | List _observers =
16 | [];
17 | // constructor method
18 | OneSignalPushSubscription() {
19 | this._channel.setMethodCallHandler(_handleMethod);
20 | }
21 |
22 | String? get id {
23 | return this._id;
24 | }
25 |
26 | /// The readonly push token.
27 | String? get token {
28 | return this._token;
29 | }
30 |
31 | /// Gets a boolean value indicating whether the current user is opted in to receive push notifications.
32 | /// If the device does not have push permission, optedIn is false.
33 | /// If the device has push permission, but no push token or subscription ID yet, optedIn is true.
34 | /// If the device has push permission and optOut() was not called, optedIn is true.
35 | /// If the device has push permission and optOut() was called, optedIn is false.
36 | bool? get optedIn {
37 | return _optedIn;
38 | }
39 |
40 | /// Call this method to receive push notifications on the device or to resume receiving of
41 | /// push notifications after calling optOut. If needed, this method will prompt the user for
42 | /// push notifications permission.
43 | Future optIn() async {
44 | await _channel.invokeMethod("OneSignal#optIn");
45 | }
46 |
47 | /// If at any point you want the user to stop receiving push notifications on the current
48 | /// device (regardless of system-level permission status), you can call this method to opt out.
49 | Future optOut() async {
50 | await _channel.invokeMethod("OneSignal#optOut");
51 | }
52 |
53 | /// The OSPushSubscriptionObserver.onOSPushSubscriptionChanged method will be fired on the passed-in
54 | // object when the push subscription changes. This method returns the current OSPushSubscriptionState
55 | // at the time of adding this observer.
56 | void addObserver(OnPushSubscriptionChangeObserver observer) {
57 | _observers.add(observer);
58 | }
59 |
60 | // Remove a push subscription observer that has been previously added.
61 | void removeObserver(OnPushSubscriptionChangeObserver observer) {
62 | _observers.remove(observer);
63 | }
64 |
65 | Future lifecycleInit() async {
66 | _token = await _channel.invokeMethod("OneSignal#pushSubscriptionToken");
67 | _id = await _channel.invokeMethod("OneSignal#pushSubscriptionId");
68 | _optedIn = await _channel.invokeMethod("OneSignal#pushSubscriptionOptedIn");
69 | return await _channel.invokeMethod("OneSignal#lifecycleInit");
70 | }
71 |
72 | // Private function that gets called by ObjC/Java
73 | Future _handleMethod(MethodCall call) async {
74 | if (call.method == 'OneSignal#onPushSubscriptionChange') {
75 | this._onPushSubscriptionChange(OSPushSubscriptionChangedState(
76 | call.arguments.cast()));
77 | }
78 | return null;
79 | }
80 |
81 | void _onPushSubscriptionChange(
82 | OSPushSubscriptionChangedState stateChanges) async {
83 | this._id = stateChanges.current.id;
84 | this._token = stateChanges.current.token;
85 | this._optedIn = stateChanges.current.optedIn;
86 |
87 | for (var observer in _observers) {
88 | observer(stateChanges);
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/lib/src/session.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'package:flutter/services.dart';
3 |
4 | class OneSignalSession {
5 | // private channels used to bridge to ObjC/Java
6 | MethodChannel _channel = const MethodChannel('OneSignal#session');
7 |
8 | /// Send a normal outcome event for the current session and notifications with the attribution window
9 | /// Counted each time sent successfully, failed ones will be cached and reattempted in future
10 | Future addOutcome(String name) async {
11 | return await _channel.invokeMethod("OneSignal#addOutcome", name);
12 | }
13 |
14 | /// Send a unique outcome event for the current session and notifications with the attribution window
15 | /// Counted once per notification when sent successfully, failed ones will be cached and reattempted in future
16 | Future addUniqueOutcome(String name) async {
17 | return await _channel.invokeMethod("OneSignal#addUniqueOutcome", name);
18 | }
19 |
20 | /// Send an outcome event with a value for the current session and notifications with the attribution window
21 | /// Counted each time sent successfully, failed ones will be cached and reattempted in future
22 | Future addOutcomeWithValue(String name, double value) async {
23 | return await _channel.invokeMethod("OneSignal#addOutcomeWithValue",
24 | {"outcome_name": name, "outcome_value": value});
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/lib/src/subscription.dart:
--------------------------------------------------------------------------------
1 | import 'package:onesignal_flutter/src/utils.dart';
2 |
3 | /// Represents the current user's subscription state with OneSignal
4 | class OSPushSubscriptionState extends JSONStringRepresentable {
5 | String? id;
6 |
7 | /// The APNS (iOS), GCM/FCM (Android) push token
8 | String? token;
9 |
10 | bool optedIn = false;
11 |
12 | OSPushSubscriptionState(Map json) {
13 | if (json.containsKey('id')) this.id = json['id'] as String?;
14 | if (json.containsKey('token')) this.token = json['token'] as String?;
15 | this.optedIn = json['optedIn'] as bool;
16 | }
17 |
18 | String jsonRepresentation() {
19 | return convertToJsonString(
20 | {'id': this.id, 'token': this.token, 'optedIn': this.optedIn});
21 | }
22 | }
23 |
24 | /// An instance of this class describes a change in the user's OneSignal
25 | /// push notification subscription state, ie. the user subscribed to
26 | /// push notifications with your app.
27 | class OSPushSubscriptionChangedState extends JSONStringRepresentable {
28 | late OSPushSubscriptionState current;
29 | late OSPushSubscriptionState previous;
30 |
31 | OSPushSubscriptionChangedState(Map json) {
32 | if (json.containsKey('current'))
33 | this.current =
34 | OSPushSubscriptionState(json['current'].cast());
35 | if (json.containsKey('previous'))
36 | this.previous =
37 | OSPushSubscriptionState(json['previous'].cast());
38 | }
39 |
40 | String jsonRepresentation() {
41 | return convertToJsonString({
42 | 'current': current.jsonRepresentation(),
43 | 'previous': previous.jsonRepresentation()
44 | });
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/lib/src/utils.dart:
--------------------------------------------------------------------------------
1 | import 'package:onesignal_flutter/src/defines.dart';
2 | import 'dart:convert';
3 |
4 | // produces a string like this: 2018-07-23T17:56:30.951030 UTC-7:00
5 | String dateToStringWithOffset(DateTime date) {
6 | var offsetHours = date.timeZoneOffset.inHours;
7 | var offsetMinutes = date.timeZoneOffset.inMinutes % 60;
8 | var dateString = "${date.toIso8601String()} ";
9 |
10 | dateString += "UTC" +
11 | ((offsetHours > 10 || offsetHours < 0)
12 | ? "$offsetHours"
13 | : "0$offsetHours");
14 | dateString += ":" +
15 | ((offsetMinutes.abs() > 10) ? "$offsetMinutes" : "0$offsetMinutes:00");
16 |
17 | return dateString;
18 | }
19 |
20 | // in some places, we want to send an enum value to
21 | // ObjC. Before we can do this, we must convert it
22 | // to a string/int/etc.
23 | // However, in some places such as iOS init settings,
24 | // there could be multiple different types of enum,
25 | // so we've combined it into this one function.
26 | dynamic convertEnumCaseToValue(dynamic key) {
27 | switch (key) {
28 | case OSiOSSettings.autoPrompt:
29 | return "kOSSettingsKeyAutoPrompt";
30 | case OSiOSSettings.inAppAlerts:
31 | return "kOSSettingsKeyInAppAlerts";
32 | case OSiOSSettings.inAppLaunchUrl:
33 | return "kOSSettingsKeyInAppLaunchURL";
34 | case OSiOSSettings.inFocusDisplayOption:
35 | return "kOSSettingsKeyInFocusDisplayOption";
36 | case OSiOSSettings.promptBeforeOpeningPushUrl:
37 | return "kOSSSettingsKeyPromptBeforeOpeningPushURL";
38 | }
39 |
40 | switch (key) {
41 | case OSCreateNotificationBadgeType.increase:
42 | return "Increase";
43 | case OSCreateNotificationBadgeType.setTo:
44 | return "SetTo";
45 | }
46 |
47 | switch (key) {
48 | case OSCreateNotificationDelayOption.lastActive:
49 | return "last_active";
50 | case OSCreateNotificationDelayOption.timezone:
51 | return "timezone";
52 | }
53 |
54 | switch (key) {
55 | case OSNotificationDisplayType.none:
56 | return 0;
57 | case OSNotificationDisplayType.alert:
58 | return 1;
59 | case OSNotificationDisplayType.notification:
60 | return 2;
61 | }
62 |
63 | switch (key) {
64 | case OSSession.DIRECT:
65 | return "DIRECT";
66 | case OSSession.INDIRECT:
67 | return "INDIRECT";
68 | case OSSession.UNATTRIBUTED:
69 | return "UNATTRIBUTED";
70 | case OSSession.DISABLED:
71 | return "DISABLED";
72 | }
73 |
74 | return key;
75 | }
76 |
77 | /// An abstract class to provide JSON decoding
78 | abstract class JSONStringRepresentable {
79 | String jsonRepresentation();
80 |
81 | String convertToJsonString(Map? object) =>
82 | JsonEncoder.withIndent(' ')
83 | .convert(object)
84 | .replaceAll("\\n", "\n")
85 | .replaceAll("\\", "");
86 | }
87 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: onesignal_flutter
2 | description: OneSignal is a free push notification service for mobile apps. This plugin makes it easy to integrate your flutter app with OneSignal
3 | version: 5.3.3
4 | homepage: https://github.com/OneSignal/OneSignal-Flutter-SDK
5 |
6 | flutter:
7 | plugin:
8 | platforms:
9 | android:
10 | package: com.onesignal.flutter
11 | pluginClass: OneSignalPlugin
12 | ios:
13 | pluginClass: OneSignalPlugin
14 |
15 | dependencies:
16 | flutter:
17 | sdk: flutter
18 |
19 | dev_dependencies:
20 | test: ^1.5.1
21 | flutter_test:
22 | sdk: flutter
23 |
24 | environment:
25 | sdk: '>=2.12.0 <3.0.0'
26 | flutter: '>=1.10.0'
27 |
--------------------------------------------------------------------------------
/test.json:
--------------------------------------------------------------------------------
1 | {
2 | "subscription_changed_test" : {
3 | "from": {
4 | "isSubscribed": false,
5 | "isPushDisabled": true,
6 | "pushToken": "07afbb0b4cb6e7ae5e81efc7fd5d35267ea9a4f12120045aebe29945e52ea30e",
7 | "userId": null
8 | },
9 | "to": {
10 | "isSubscribed": true,
11 | "isPushDisabled": true,
12 | "pushToken": "07afbb0b4cb6e7ae5e81efc7fd5d35267ea9a4f12120045aebe29945e52ea30e",
13 | "userId": "c1b395fc-3b17-4c18-aaa6-195cd3461311"
14 | }
15 | },
16 | "email_changed_test" : {
17 | "from" : {
18 | "subscribed" : false,
19 | "emailUserId" : null,
20 | "emailAddress" : null
21 | },
22 | "to" : {
23 | "subscribed" : true,
24 | "emailUserId" : "c1b395fc-3b17-4c18-aaa6-195cd3461311",
25 | "emailAddress" : "brad@hesse.io"
26 | }
27 | },
28 | "notification_parsing_test" : {
29 | "shown" : true,
30 | "rawPayload" : "{ \"test\" : \"raw payload\" }",
31 | "additionalData" : {
32 | "additional" : "data"
33 | },
34 | "notificationId" : "8e0eeec2-aa42-4ff7-a74b-bce9ca9e588b",
35 | "buttons" : [
36 | {
37 | "id" : "test1",
38 | "text" : "BTN1"
39 | }
40 | ],
41 | "contentAvailable" : true,
42 | "sound" : "default",
43 | "attachments" : {
44 | "id" : "https://www.onesignal.com"
45 | },
46 | "body" : "Welcome to OneSignal!",
47 | "mutableContent" : true,
48 | "displayType" : 1,
49 | "appInFocus" : true,
50 | "silent" : true
51 | },
52 | "permission_parsing_test" : {
53 | "from" : {
54 | "hasPrompted" : false,
55 | "provisional" : false,
56 | "status" : 0
57 | },
58 | "to" : {
59 | "hasPrompted" : true,
60 | "provisional" : true,
61 | "status" : 2
62 | }
63 | }
64 | }
--------------------------------------------------------------------------------
/test/mock_channel.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/services.dart';
2 | import 'package:onesignal_flutter/onesignal_flutter.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | /*
6 | This class mocks an iOS or Android host device
7 | It has a OneSignalState object that reflects changes to
8 | state that the various requests make.
9 | */
10 |
11 | class OneSignalMockChannelController {
12 | MethodChannel _channel = const MethodChannel('OneSignal');
13 | MethodChannel _debugChannel = const MethodChannel('OneSignal#debug');
14 | MethodChannel _tagsChannel = const MethodChannel('OneSignal#tags');
15 |
16 | late OneSignalState state;
17 |
18 | OneSignalMockChannelController() {
19 | this._channel.setMockMethodCallHandler(_handleMethod);
20 | this._tagsChannel.setMockMethodCallHandler(_handleMethod);
21 | this._debugChannel.setMockMethodCallHandler(_handleMethod);
22 | }
23 |
24 | void resetState() {
25 | state = OneSignalState();
26 | }
27 |
28 | Future _handleMethod(MethodCall call) async {
29 | print("Mock method called: ${call.method}");
30 | switch (call.method) {
31 | case "OneSignal#setAppId":
32 | this.state.setAppId(call.arguments);
33 | break;
34 | case "OneSignal#setLogLevel":
35 | this.state.setLogLevel(call.arguments);
36 | break;
37 | case "OneSignal#consentGiven":
38 | this.state.consentGiven =
39 | (call.arguments as Map)['given'] as bool?;
40 | break;
41 | case "OneSignal#promptPermission":
42 | this.state.calledPromptPermission = true;
43 | break;
44 | case "OneSignal#log":
45 | this.state.log(call.arguments);
46 | break;
47 | case "OneSignal#disablePush":
48 | this.state.disablePush = call.arguments as bool?;
49 | break;
50 | case "OneSignal#postNotification":
51 | this.state.postNotificationJson =
52 | call.arguments as Map?;
53 | return {"success": true};
54 | case "OneSignal#setLocationShared":
55 | this.state.locationShared = call.arguments as bool?;
56 | break;
57 | case "OneSignal#setEmail":
58 | this.state.setEmail(call.arguments);
59 | break;
60 | case "OneSignal#sendTags":
61 | this.state.tags = call.arguments;
62 | return {"success": true};
63 | case "OneSignal#deleteTags":
64 | this.state.deleteTags = call.arguments;
65 | return {"success": true};
66 | case "OneSignal#setExternalUserId":
67 | this.state.externalId = (call.arguments
68 | as Map)['externalUserId'] as String?;
69 | return {"success": true};
70 | case "OneSignal#removeExternalUserId":
71 | this.state.externalId = null;
72 | return {"success": true};
73 | case "OneSignal#setLanguage":
74 | this.state.language =
75 | (call.arguments as Map)['language'] as String?;
76 | return {"success": true};
77 | }
78 | }
79 | }
80 |
81 | class OneSignalState {
82 | //initialization
83 | String? appId;
84 |
85 | //email
86 | String? email;
87 | String? emailAuthHashToken;
88 |
89 | // logging
90 | String? latestLogStatement;
91 | OSLogLevel? latestLogLevel;
92 |
93 | // miscellaneous params
94 | bool? requiresPrivacyConsent = false;
95 | late OSLogLevel logLevel;
96 | late OSLogLevel visualLevel;
97 | bool? consentGiven = false;
98 | bool? calledPromptPermission;
99 | bool? locationShared;
100 | OSNotificationDisplayType? inFocusDisplayType;
101 | bool? disablePush;
102 | String? externalId;
103 | String? language;
104 |
105 | // tags
106 | Map? tags;
107 | List? deleteTags;
108 |
109 | // notifications
110 | Map? postNotificationJson;
111 |
112 | /*
113 | All of the following functions parse the MethodCall
114 | parameters, and sets properties on the object itself
115 | */
116 |
117 | void setAppId(Map params) {
118 | this.appId = params['appId'];
119 | }
120 |
121 | void setLogLevel(Map params) {
122 | int? level = params['logLevel'] as int?;
123 | int? visual = params['visual'] as int?;
124 |
125 | if (level != null) this.logLevel = OSLogLevel.values[level];
126 | if (visual != null) this.visualLevel = OSLogLevel.values[visual];
127 | }
128 |
129 | void consentRequired(Map params) {
130 | this.requiresPrivacyConsent = params['required'] as bool?;
131 | }
132 |
133 | void log(Map params) {
134 | var level = params['logLevel'] as int?;
135 |
136 | if (level != null) this.latestLogLevel = OSLogLevel.values[level];
137 | this.latestLogStatement = params['message'];
138 | }
139 |
140 | void setDisplayType(Map params) {
141 | var type = params['displayType'] as int?;
142 | if (type != null)
143 | this.inFocusDisplayType = OSNotificationDisplayType.values[type];
144 | }
145 |
146 | void setEmail(Map params) {
147 | this.email = params['email'] as String?;
148 | this.emailAuthHashToken = params['emailAuthHashToken'] as String?;
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/test/onesignalflutter_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_test/flutter_test.dart';
2 | import 'package:onesignal_flutter/onesignal_flutter.dart';
3 | import 'mock_channel.dart';
4 |
5 | void main() {
6 | TestWidgetsFlutterBinding.ensureInitialized();
7 |
8 | OneSignalMockChannelController channelController =
9 | OneSignalMockChannelController();
10 |
11 | setUp(() {
12 | channelController.resetState();
13 | });
14 |
15 | test('set log level', () {
16 | OneSignal.Debug.setLogLevel(
17 | OSLogLevel.info,
18 | ).then(expectAsync1((v) {
19 | expect(channelController.state.logLevel.index, OSLogLevel.info.index);
20 | }));
21 | });
22 | }
23 |
--------------------------------------------------------------------------------