Browse Source

first commit

main
Akhilesh 7 months ago
commit
03c2d35fbb
96 changed files with 2721 additions and 0 deletions
  1. BIN
      .DS_Store
  2. +0
    -0
      README.md
  3. +7
    -0
      next-steps.html
  4. BIN
      src/.DS_Store
  5. +92
    -0
      src/.gitignore
  6. +39
    -0
      src/CheckoutPaymentViewController.swift
  7. +38
    -0
      src/GoogleService-Info.plist
  8. +24
    -0
      src/LICENSE
  9. +507
    -0
      src/Nivesh.xcodeproj/project.pbxproj
  10. +7
    -0
      src/Nivesh.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  11. +8
    -0
      src/Nivesh.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
  12. +8
    -0
      src/Nivesh.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
  13. +85
    -0
      src/Nivesh.xcodeproj/xcshareddata/xcschemes/Nivesh.xcscheme
  14. +10
    -0
      src/Nivesh.xcworkspace/contents.xcworkspacedata
  15. +8
    -0
      src/Nivesh.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
  16. +132
    -0
      src/Nivesh.xcworkspace/xcshareddata/swiftpm/Package.resolved
  17. BIN
      src/Nivesh/.DS_Store
  18. +151
    -0
      src/Nivesh/AppDelegate.swift
  19. BIN
      src/Nivesh/Assets.xcassets/.DS_Store
  20. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/.DS_Store
  21. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/100.png
  22. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/102.png
  23. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/1024.png
  24. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/108.png
  25. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/114.png
  26. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/120.png
  27. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/128.png
  28. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/144.png
  29. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/152.png
  30. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/16.png
  31. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/167.png
  32. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/172.png
  33. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/180.png
  34. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/192.png
  35. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/196.png
  36. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/20.png
  37. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/216.png
  38. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/234.png
  39. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/256.png
  40. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/258.png
  41. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/29.png
  42. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/32.png
  43. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/40.png
  44. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/48.png
  45. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/50.png
  46. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/512.png
  47. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/55.png
  48. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/57.png
  49. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/58.png
  50. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/60.png
  51. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/64.png
  52. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/66.png
  53. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/72.png
  54. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/76.png
  55. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/80.png
  56. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/87.png
  57. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/88.png
  58. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/92.png
  59. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/AppIcon-128.png
  60. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/AppIcon-128@2x.png
  61. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/AppIcon-16.png
  62. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/AppIcon-16@2x.png
  63. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/AppIcon-256.png
  64. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/AppIcon-256@2x.png
  65. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/AppIcon-32.png
  66. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/AppIcon-32@2x.png
  67. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/AppIcon-512.png
  68. BIN
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png
  69. +224
    -0
      src/Nivesh/Assets.xcassets/AppIcon.appiconset/Contents.json
  70. +9
    -0
      src/Nivesh/Assets.xcassets/Contents.json
  71. BIN
      src/Nivesh/Assets.xcassets/n-logo.imageset/1080.png
  72. BIN
      src/Nivesh/Assets.xcassets/n-logo.imageset/1080@2x.png
  73. BIN
      src/Nivesh/Assets.xcassets/n-logo.imageset/1080@3x.png
  74. +23
    -0
      src/Nivesh/Assets.xcassets/n-logo.imageset/Contents.json
  75. +23
    -0
      src/Nivesh/Assets.xcassets/splash-screen-logo.imageset/Contents.json
  76. BIN
      src/Nivesh/Assets.xcassets/splash-screen-logo.imageset/splash-screen-logo.png
  77. BIN
      src/Nivesh/Assets.xcassets/splash-screen-logo.imageset/splash-screen-logo@2x.png
  78. BIN
      src/Nivesh/Assets.xcassets/splash-screen-logo.imageset/splash-screen-logo@3x.png
  79. +50
    -0
      src/Nivesh/Base.lproj/LaunchScreen.storyboard
  80. +86
    -0
      src/Nivesh/Base.lproj/Main.storyboard
  81. +1
    -0
      src/Nivesh/Entitlements/.gitignore
  82. +27
    -0
      src/Nivesh/Entitlements/Entitlements.plist
  83. +124
    -0
      src/Nivesh/Info.plist
  84. +29
    -0
      src/Nivesh/NiveshRelease.entitlements
  85. +20
    -0
      src/Nivesh/Printer.swift
  86. +173
    -0
      src/Nivesh/PushNotifications.swift
  87. +111
    -0
      src/Nivesh/SceneDelegate.swift
  88. +29
    -0
      src/Nivesh/Settings.swift
  89. +249
    -0
      src/Nivesh/ViewController.swift
  90. +406
    -0
      src/Nivesh/WebView.swift
  91. +21
    -0
      src/Podfile
  92. BIN
      src/launch-128.png
  93. BIN
      src/launch-192.png
  94. BIN
      src/launch-256.png
  95. BIN
      src/launch-512.png
  96. BIN
      src/launch-64.png

BIN
.DS_Store View File


+ 0
- 0
README.md View File


+ 7
- 0
next-steps.html View File

@ -0,0 +1,7 @@
<html>
<body>
<script>
window.location = "https://docs.pwabuilder.com/#/builder/app-store?id=building-your-app";
</script>
</body>
</html>

BIN
src/.DS_Store View File


+ 92
- 0
src/.gitignore View File

@ -0,0 +1,92 @@
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## User settings
xcuserdata/
## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
*.xcscmblueprint
*.xccheckout
## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
build/
DerivedData/
*.moved-aside
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
## Obj-C/Swift specific
*.hmap
## App packaging
*.ipa
*.dSYM.zip
*.dSYM
## Playgrounds
timeline.xctimeline
playground.xcworkspace
# Swift Package Manager
#
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
# Package.pins
# Package.resolved
# *.xcodeproj
#
# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
# hence it is not needed unless you have added a package configuration file to your project
# .swiftpm
.build/
# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
#
# Add this line if you want to avoid checking in source code from the Xcode workspace
# *.xcworkspace
# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts
Carthage/Build/
# Accio dependency management
Dependencies/
.accio/
# fastlane
#
# It is recommended to not store the screenshots in the git repo.
# Instead, use fastlane to re-generate the screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output
# Code Injection
#
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode
iOSInjectionProject/
/Podfile.lock
/Pods

+ 39
- 0
src/CheckoutPaymentViewController.swift View File

@ -0,0 +1,39 @@
import UIKit
import WebKit
class CheckoutPaymentViewController: UIViewController, WKNavigationDelegate {
var checkoutUrl: String? // Razorpay checkout URL
var wkWebView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Initialize WebView
wkWebView = WKWebView(frame: self.view.frame)
wkWebView.navigationDelegate = self
self.view.addSubview(wkWebView)
self.loadWebPage()
}
func loadWebPage() {
guard let urlString = self.checkoutUrl else { return }
guard let url = URL(string: urlString) else { return }
self.wkWebView.load(URLRequest(url: url))
}
// Handle Payment Success or Failure (Optional)
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if let url = navigationAction.request.url?.absoluteString {
if url.contains("success") {
print("Payment Successful")
self.dismiss(animated: true, completion: nil) // Dismiss ViewController on Success
} else if url.contains("failure") {
print("Payment Failed")
}
}
decisionHandler(.allow)
}
}

+ 38
- 0
src/GoogleService-Info.plist View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CLIENT_ID</key>
<string>9350938798-9pjd1etaka84smk519q61iclr52iu64s.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.9350938798-9pjd1etaka84smk519q61iclr52iu64s</string>
<key>ANDROID_CLIENT_ID</key>
<string>9350938798-1nmut59vc84ap49t076qine91qpsetal.apps.googleusercontent.com</string>
<key>API_KEY</key>
<string>AIzaSyAFHcM26WF_WlaVjgN0AO_LfHKeluNU4vM</string>
<key>GCM_SENDER_ID</key>
<string>9350938798</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.nivesh.app</string>
<key>PROJECT_ID</key>
<string>firebase-nivesh</string>
<key>STORAGE_BUCKET</key>
<string>firebase-nivesh.appspot.com</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:9350938798:ios:e85e4205437e211450ed3f</string>
<key>DATABASE_URL</key>
<string>https://fir-nivesh.firebaseio.com</string>
</dict>
</plist>

+ 24
- 0
src/LICENSE View File

@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <https://unlicense.org>

+ 507
- 0
src/Nivesh.xcodeproj/project.pbxproj View File

@ -0,0 +1,507 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
1E01BF082D50AB030044ED2D /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1E01BF072D50AB030044ED2D /* GoogleService-Info.plist */; };
1EBE67732D50CF2300F6C6D0 /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 1EBE67722D50CF2300F6C6D0 /* FirebaseAnalytics */; };
1EBE67752D50CF2300F6C6D0 /* FirebaseAppCheck in Frameworks */ = {isa = PBXBuildFile; productRef = 1EBE67742D50CF2300F6C6D0 /* FirebaseAppCheck */; };
1EBE67772D50CF2300F6C6D0 /* FirebaseAuth in Frameworks */ = {isa = PBXBuildFile; productRef = 1EBE67762D50CF2300F6C6D0 /* FirebaseAuth */; };
1EBE67792D50CF2300F6C6D0 /* FirebaseCore in Frameworks */ = {isa = PBXBuildFile; productRef = 1EBE67782D50CF2300F6C6D0 /* FirebaseCore */; };
1EBE677B2D50CF2300F6C6D0 /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = 1EBE677A2D50CF2300F6C6D0 /* FirebaseCrashlytics */; };
1EBE677D2D50CF2300F6C6D0 /* FirebaseDynamicLinks in Frameworks */ = {isa = PBXBuildFile; productRef = 1EBE677C2D50CF2300F6C6D0 /* FirebaseDynamicLinks */; };
1EBE677F2D50CF2300F6C6D0 /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = 1EBE677E2D50CF2300F6C6D0 /* FirebaseMessaging */; };
1EBE67812D50CF2300F6C6D0 /* FirebasePerformance in Frameworks */ = {isa = PBXBuildFile; productRef = 1EBE67802D50CF2300F6C6D0 /* FirebasePerformance */; };
1EBE67852D54952900F6C6D0 /* BranchSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 1EBE67842D54952900F6C6D0 /* BranchSDK */; };
1EBE67882D54958E00F6C6D0 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1EBE67872D54958E00F6C6D0 /* CoreServices.framework */; };
1EBE678A2D5495A900F6C6D0 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1EBE67892D5495A900F6C6D0 /* SystemConfiguration.framework */; };
1EBE678C2D5495B900F6C6D0 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1EBE678B2D5495B900F6C6D0 /* WebKit.framework */; };
1EBE678E2D5495D000F6C6D0 /* CoreSpotlight.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1EBE678D2D5495D000F6C6D0 /* CoreSpotlight.framework */; };
595F23A525CEFBFE0053416C /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 595F239A25CEFBFD0053416C /* Settings.swift */; };
595F23A625CEFBFE0053416C /* Entitlements in Resources */ = {isa = PBXBuildFile; fileRef = 595F239B25CEFBFD0053416C /* Entitlements */; };
595F23A725CEFBFE0053416C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 595F239C25CEFBFD0053416C /* Assets.xcassets */; };
595F23A825CEFBFE0053416C /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 595F239D25CEFBFD0053416C /* SceneDelegate.swift */; };
595F23AA25CEFBFE0053416C /* PushNotifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 595F239F25CEFBFE0053416C /* PushNotifications.swift */; };
595F23AC25CEFBFE0053416C /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 595F23A125CEFBFE0053416C /* ViewController.swift */; };
595F23AD25CEFBFE0053416C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 595F23A225CEFBFE0053416C /* AppDelegate.swift */; };
595F23AE25CEFBFE0053416C /* Printer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 595F23A325CEFBFE0053416C /* Printer.swift */; };
595F23AF25CEFBFE0053416C /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 595F23A425CEFBFE0053416C /* WebView.swift */; };
CDC0FE292388222C002C8D56 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CDC0FE252388222B002C8D56 /* Main.storyboard */; };
CDC0FE2A2388222C002C8D56 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CDC0FE272388222B002C8D56 /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
1E01BF072D50AB030044ED2D /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
1EBE67822D54865300F6C6D0 /* NiveshRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = NiveshRelease.entitlements; path = Nivesh/NiveshRelease.entitlements; sourceTree = "<group>"; };
1EBE67872D54958E00F6C6D0 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
1EBE67892D5495A900F6C6D0 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
1EBE678B2D5495B900F6C6D0 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
1EBE678D2D5495D000F6C6D0 /* CoreSpotlight.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreSpotlight.framework; path = System/Library/Frameworks/CoreSpotlight.framework; sourceTree = SDKROOT; };
59333BAA25CFF706003392A4 /* Nivesh.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Nivesh.app; sourceTree = BUILT_PRODUCTS_DIR; };
595F239A25CEFBFD0053416C /* Settings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Settings.swift; path = Nivesh/Settings.swift; sourceTree = "<group>"; };
595F239B25CEFBFD0053416C /* Entitlements */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Entitlements; path = Nivesh/Entitlements; sourceTree = "<group>"; };
595F239C25CEFBFD0053416C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Nivesh/Assets.xcassets; sourceTree = "<group>"; };
595F239D25CEFBFD0053416C /* SceneDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SceneDelegate.swift; path = Nivesh/SceneDelegate.swift; sourceTree = "<group>"; };
595F239F25CEFBFE0053416C /* PushNotifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PushNotifications.swift; path = Nivesh/PushNotifications.swift; sourceTree = "<group>"; };
595F23A025CEFBFE0053416C /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Nivesh/Info.plist; sourceTree = "<group>"; };
595F23A125CEFBFE0053416C /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ViewController.swift; path = Nivesh/ViewController.swift; sourceTree = "<group>"; };
595F23A225CEFBFE0053416C /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = Nivesh/AppDelegate.swift; sourceTree = "<group>"; };
595F23A325CEFBFE0053416C /* Printer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Printer.swift; path = Nivesh/Printer.swift; sourceTree = "<group>"; };
595F23A425CEFBFE0053416C /* WebView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = WebView.swift; path = Nivesh/WebView.swift; sourceTree = "<group>"; };
CDC0FE262388222B002C8D56 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Nivesh/Base.lproj/Main.storyboard; sourceTree = "<group>"; };
CDC0FE282388222B002C8D56 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Nivesh/Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
CD89F886237E9D9200C436A1 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
1EBE67852D54952900F6C6D0 /* BranchSDK in Frameworks */,
1EBE67882D54958E00F6C6D0 /* CoreServices.framework in Frameworks */,
1EBE678A2D5495A900F6C6D0 /* SystemConfiguration.framework in Frameworks */,
1EBE678C2D5495B900F6C6D0 /* WebKit.framework in Frameworks */,
1EBE678E2D5495D000F6C6D0 /* CoreSpotlight.framework in Frameworks */,
1EBE677F2D50CF2300F6C6D0 /* FirebaseMessaging in Frameworks */,
1EBE67732D50CF2300F6C6D0 /* FirebaseAnalytics in Frameworks */,
1EBE67812D50CF2300F6C6D0 /* FirebasePerformance in Frameworks */,
1EBE67792D50CF2300F6C6D0 /* FirebaseCore in Frameworks */,
1EBE67752D50CF2300F6C6D0 /* FirebaseAppCheck in Frameworks */,
1EBE677B2D50CF2300F6C6D0 /* FirebaseCrashlytics in Frameworks */,
1EBE677D2D50CF2300F6C6D0 /* FirebaseDynamicLinks in Frameworks */,
1EBE67772D50CF2300F6C6D0 /* FirebaseAuth in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
1EBE67862D54958E00F6C6D0 /* Frameworks */ = {
isa = PBXGroup;
children = (
1EBE678D2D5495D000F6C6D0 /* CoreSpotlight.framework */,
1EBE678B2D5495B900F6C6D0 /* WebKit.framework */,
1EBE67892D5495A900F6C6D0 /* SystemConfiguration.framework */,
1EBE67872D54958E00F6C6D0 /* CoreServices.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
30FCACC6A7BF53CD6D9CF6C0 /* Pods */ = {
isa = PBXGroup;
children = (
);
path = Pods;
sourceTree = "<group>";
};
CD89F880237E9D9200C436A1 = {
isa = PBXGroup;
children = (
1EBE67822D54865300F6C6D0 /* NiveshRelease.entitlements */,
595F23A225CEFBFE0053416C /* AppDelegate.swift */,
595F239C25CEFBFD0053416C /* Assets.xcassets */,
595F239B25CEFBFD0053416C /* Entitlements */,
595F23A025CEFBFE0053416C /* Info.plist */,
1E01BF072D50AB030044ED2D /* GoogleService-Info.plist */,
595F23A325CEFBFE0053416C /* Printer.swift */,
595F239F25CEFBFE0053416C /* PushNotifications.swift */,
595F239D25CEFBFD0053416C /* SceneDelegate.swift */,
595F239A25CEFBFD0053416C /* Settings.swift */,
595F23A125CEFBFE0053416C /* ViewController.swift */,
CDC0FE272388222B002C8D56 /* LaunchScreen.storyboard */,
CDC0FE252388222B002C8D56 /* Main.storyboard */,
595F23A425CEFBFE0053416C /* WebView.swift */,
30FCACC6A7BF53CD6D9CF6C0 /* Pods */,
59333BAA25CFF706003392A4 /* Nivesh.app */,
1EBE67862D54958E00F6C6D0 /* Frameworks */,
);
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
CD89F888237E9D9200C436A1 /* Nivesh */ = {
isa = PBXNativeTarget;
buildConfigurationList = CD89F89D237E9D9300C436A1 /* Build configuration list for PBXNativeTarget "Nivesh" */;
buildPhases = (
CD89F885237E9D9200C436A1 /* Sources */,
CD89F886237E9D9200C436A1 /* Frameworks */,
CD89F887237E9D9200C436A1 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = Nivesh;
productName = Nivesh;
productReference = 59333BAA25CFF706003392A4 /* Nivesh.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
CD89F881237E9D9200C436A1 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastSwiftUpdateCheck = 1120;
LastUpgradeCheck = 1620;
ORGANIZATIONNAME = "";
TargetAttributes = {
CD89F888237E9D9200C436A1 = {
CreatedOnToolsVersion = 11.2.1;
LastSwiftMigration = 1120;
};
};
};
buildConfigurationList = CD89F884237E9D9200C436A1 /* Build configuration list for PBXProject "Nivesh" */;
compatibilityVersion = "Xcode 11.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = CD89F880237E9D9200C436A1;
packageReferences = (
1EBE67712D50CF2300F6C6D0 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */,
1EBE67832D54952900F6C6D0 /* XCRemoteSwiftPackageReference "ios-branch-sdk-spm" */,
);
productRefGroup = CD89F880237E9D9200C436A1;
projectDirPath = "";
projectRoot = "";
targets = (
CD89F888237E9D9200C436A1 /* Nivesh */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
CD89F887237E9D9200C436A1 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
595F23A625CEFBFE0053416C /* Entitlements in Resources */,
CDC0FE292388222C002C8D56 /* Main.storyboard in Resources */,
1E01BF082D50AB030044ED2D /* GoogleService-Info.plist in Resources */,
CDC0FE2A2388222C002C8D56 /* LaunchScreen.storyboard in Resources */,
595F23A725CEFBFE0053416C /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
CD89F885237E9D9200C436A1 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
595F23AD25CEFBFE0053416C /* AppDelegate.swift in Sources */,
595F23A825CEFBFE0053416C /* SceneDelegate.swift in Sources */,
595F23A525CEFBFE0053416C /* Settings.swift in Sources */,
595F23AE25CEFBFE0053416C /* Printer.swift in Sources */,
595F23AC25CEFBFE0053416C /* ViewController.swift in Sources */,
595F23AA25CEFBFE0053416C /* PushNotifications.swift in Sources */,
595F23AF25CEFBFE0053416C /* WebView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
CDC0FE252388222B002C8D56 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
CDC0FE262388222B002C8D56 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
CDC0FE272388222B002C8D56 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
CDC0FE282388222B002C8D56 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
CD89F89B237E9D9300C436A1 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
TARGETED_DEVICE_FAMILY = "1,2,6";
VALID_ARCHS = "$(ARCHS_STANDARD)";
};
name = Debug;
};
CD89F89C237E9D9300C436A1 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
TARGETED_DEVICE_FAMILY = "1,2,6";
VALIDATE_PRODUCT = YES;
VALID_ARCHS = "$(ARCHS_STANDARD)";
};
name = Release;
};
CD89F89E237E9D9300C436A1 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = NO;
CODE_SIGN_ENTITLEMENTS = Nivesh/Entitlements/Entitlements.plist;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = 892H6H36S9;
INFOPLIST_FILE = Nivesh/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.1;
PRODUCT_BUNDLE_IDENTIFIER = com.nivesh.app;
PRODUCT_NAME = Nivesh;
PROVISIONING_PROFILE_SPECIFIER = "";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2,6";
};
name = Debug;
};
CD89F89F237E9D9300C436A1 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = NO;
CODE_SIGN_ENTITLEMENTS = Nivesh/NiveshRelease.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = 892H6H36S9;
INFOPLIST_FILE = Nivesh/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.1;
PRODUCT_BUNDLE_IDENTIFIER = com.nivesh.app;
PRODUCT_NAME = Nivesh;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OPTIMIZATION_LEVEL = "-Osize";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2,6";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
CD89F884237E9D9200C436A1 /* Build configuration list for PBXProject "Nivesh" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CD89F89B237E9D9300C436A1 /* Debug */,
CD89F89C237E9D9300C436A1 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
CD89F89D237E9D9300C436A1 /* Build configuration list for PBXNativeTarget "Nivesh" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CD89F89E237E9D9300C436A1 /* Debug */,
CD89F89F237E9D9300C436A1 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
1EBE67712D50CF2300F6C6D0 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/firebase/firebase-ios-sdk";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 11.7.0;
};
};
1EBE67832D54952900F6C6D0 /* XCRemoteSwiftPackageReference "ios-branch-sdk-spm" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/BranchMetrics/ios-branch-sdk-spm";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 3.8.0;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
1EBE67722D50CF2300F6C6D0 /* FirebaseAnalytics */ = {
isa = XCSwiftPackageProductDependency;
package = 1EBE67712D50CF2300F6C6D0 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
productName = FirebaseAnalytics;
};
1EBE67742D50CF2300F6C6D0 /* FirebaseAppCheck */ = {
isa = XCSwiftPackageProductDependency;
package = 1EBE67712D50CF2300F6C6D0 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
productName = FirebaseAppCheck;
};
1EBE67762D50CF2300F6C6D0 /* FirebaseAuth */ = {
isa = XCSwiftPackageProductDependency;
package = 1EBE67712D50CF2300F6C6D0 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
productName = FirebaseAuth;
};
1EBE67782D50CF2300F6C6D0 /* FirebaseCore */ = {
isa = XCSwiftPackageProductDependency;
package = 1EBE67712D50CF2300F6C6D0 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
productName = FirebaseCore;
};
1EBE677A2D50CF2300F6C6D0 /* FirebaseCrashlytics */ = {
isa = XCSwiftPackageProductDependency;
package = 1EBE67712D50CF2300F6C6D0 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
productName = FirebaseCrashlytics;
};
1EBE677C2D50CF2300F6C6D0 /* FirebaseDynamicLinks */ = {
isa = XCSwiftPackageProductDependency;
package = 1EBE67712D50CF2300F6C6D0 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
productName = FirebaseDynamicLinks;
};
1EBE677E2D50CF2300F6C6D0 /* FirebaseMessaging */ = {
isa = XCSwiftPackageProductDependency;
package = 1EBE67712D50CF2300F6C6D0 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
productName = FirebaseMessaging;
};
1EBE67802D50CF2300F6C6D0 /* FirebasePerformance */ = {
isa = XCSwiftPackageProductDependency;
package = 1EBE67712D50CF2300F6C6D0 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
productName = FirebasePerformance;
};
1EBE67842D54952900F6C6D0 /* BranchSDK */ = {
isa = XCSwiftPackageProductDependency;
package = 1EBE67832D54952900F6C6D0 /* XCRemoteSwiftPackageReference "ios-branch-sdk-spm" */;
productName = BranchSDK;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = CD89F881237E9D9200C436A1 /* Project object */;
}

+ 7
- 0
src/Nivesh.xcodeproj/project.xcworkspace/contents.xcworkspacedata View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Nivesh.xcodeproj">
</FileRef>
</Workspace>

+ 8
- 0
src/Nivesh.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

+ 8
- 0
src/Nivesh.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

+ 85
- 0
src/Nivesh.xcodeproj/xcshareddata/xcschemes/Nivesh.xcscheme View File

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1620"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CD89F888237E9D9200C436A1"
BuildableName = "Nivesh.app"
BlueprintName = "Nivesh"
ReferencedContainer = "container:Nivesh.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CD89F888237E9D9200C436A1"
BuildableName = "Nivesh.app"
BlueprintName = "Nivesh"
ReferencedContainer = "container:Nivesh.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<EnvironmentVariables>
<EnvironmentVariable
key = "OS_ACTIVITY_MODE"
value = "disable"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CD89F888237E9D9200C436A1"
BuildableName = "Nivesh.app"
BlueprintName = "Nivesh"
ReferencedContainer = "container:Nivesh.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

+ 10
- 0
src/Nivesh.xcworkspace/contents.xcworkspacedata View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Nivesh.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

+ 8
- 0
src/Nivesh.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

+ 132
- 0
src/Nivesh.xcworkspace/xcshareddata/swiftpm/Package.resolved View File

@ -0,0 +1,132 @@
{
"originHash" : "d3fa15d926fa0f697cb981b51acbaff616acb7eb437695719dedfca1f38b248c",
"pins" : [
{
"identity" : "abseil-cpp-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/abseil-cpp-binary.git",
"state" : {
"revision" : "194a6706acbd25e4ef639bcaddea16e8758a3e27",
"version" : "1.2024011602.0"
}
},
{
"identity" : "app-check",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/app-check.git",
"state" : {
"revision" : "61b85103a1aeed8218f17c794687781505fbbef5",
"version" : "11.2.0"
}
},
{
"identity" : "firebase-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/firebase-ios-sdk",
"state" : {
"revision" : "0d885d28250fb1196b614bc9455079b75c531f72",
"version" : "11.7.0"
}
},
{
"identity" : "googleappmeasurement",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleAppMeasurement.git",
"state" : {
"revision" : "be0881ff728eca210ccb628092af400c086abda3",
"version" : "11.7.0"
}
},
{
"identity" : "googledatatransport",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleDataTransport.git",
"state" : {
"revision" : "617af071af9aa1d6a091d59a202910ac482128f9",
"version" : "10.1.0"
}
},
{
"identity" : "googleutilities",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleUtilities.git",
"state" : {
"revision" : "53156c7ec267db846e6b64c9f4c4e31ba4cf75eb",
"version" : "8.0.2"
}
},
{
"identity" : "grpc-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/grpc-binary.git",
"state" : {
"revision" : "f56d8fc3162de9a498377c7b6cea43431f4f5083",
"version" : "1.65.1"
}
},
{
"identity" : "gtm-session-fetcher",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/gtm-session-fetcher.git",
"state" : {
"revision" : "3cdb78efb79b4a5383c3911488d8025bfc545b5e",
"version" : "4.3.0"
}
},
{
"identity" : "interop-ios-for-google-sdks",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/interop-ios-for-google-sdks.git",
"state" : {
"revision" : "2d12673670417654f08f5f90fdd62926dc3a2648",
"version" : "100.0.0"
}
},
{
"identity" : "ios-branch-sdk-spm",
"kind" : "remoteSourceControl",
"location" : "https://github.com/BranchMetrics/ios-branch-sdk-spm",
"state" : {
"revision" : "37d0fb8ff04098807957b1d387812ed8f96fbdc7",
"version" : "3.8.0"
}
},
{
"identity" : "leveldb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/leveldb.git",
"state" : {
"revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1",
"version" : "1.22.5"
}
},
{
"identity" : "nanopb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/nanopb.git",
"state" : {
"revision" : "b7e1104502eca3a213b46303391ca4d3bc8ddec1",
"version" : "2.30910.0"
}
},
{
"identity" : "promises",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/promises.git",
"state" : {
"revision" : "540318ecedd63d883069ae7f1ed811a2df00b6ac",
"version" : "2.4.0"
}
},
{
"identity" : "swift-protobuf",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-protobuf.git",
"state" : {
"revision" : "ebc7251dd5b37f627c93698e4374084d98409633",
"version" : "1.28.2"
}
}
],
"version" : 3
}

BIN
src/Nivesh/.DS_Store View File


+ 151
- 0
src/Nivesh/AppDelegate.swift View File

@ -0,0 +1,151 @@
import UIKit
import FirebaseCore
import FirebaseMessaging
import UserNotifications
import BranchSDK
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window : UIWindow?
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// TODO: if we're using Firebase, uncomment next string
FirebaseApp.configure()
// [START set_messaging_delegate]
Messaging.messaging().delegate = self
// [END set_messaging_delegate]
// Register for remote notifications. This shows a permission dialog on first run, to
// show the dialog at a more appropriate time move this registration accordingly.
// [START register_for_notifications]
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in })
// TODO: if we're using Firebase, uncomment next string
application.registerForRemoteNotifications()
// [END register_for_notifications]
// This version of `initSession` includes the source UIScene in the callback
BranchScene.shared().initSession(launchOptions: launchOptions, registerDeepLinkHandler: { (params, error, scene) in
})
return true
}
// [START receive_message]
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// With swizzling disabled you must let Messaging know about the message, for Analytics
Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID 1: \(messageID)")
}
// Print full message.
print("push userInfo 1:", userInfo)
sendPushToWebView(userInfo: userInfo)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// With swizzling disabled you must let Messaging know about the message, for Analytics
Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID 2: \(messageID)")
}
// Print full message. **
print("push userInfo 2:", userInfo)
sendPushToWebView(userInfo: userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
// [END receive_message]
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Unable to register for remote notifications: \(error.localizedDescription)")
}
// This function is added here only for debugging purposes, and can be removed if swizzling is enabled.
// If swizzling is disabled then this function must be implemented so that the APNs token can be paired to
// the FCM registration token.
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print("APNs token retrieved: \(deviceToken)")
// With swizzling disabled you must set the APNs token here.
Messaging.messaging().apnsToken = deviceToken
}
}
// [START ios_10_message_handling]
extension AppDelegate : UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
// With swizzling disabled you must let Messaging know about the message, for Analytics
Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: 3 \(messageID)")
}
// Print full message.
print("push userInfo 3:", userInfo)
sendPushToWebView(userInfo: userInfo)
// Change this to your preferred presentation option
completionHandler([[.banner, .list, .sound]])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID 4: \(messageID)")
}
// With swizzling disabled you must let Messaging know about the message, for Analytics
Messaging.messaging().appDidReceiveMessage(userInfo)
// Print full message.
print("push userInfo 4:", userInfo)
sendPushToWebView(userInfo: userInfo)
completionHandler()
}
}
// [END ios_10_message_handling]
extension AppDelegate : MessagingDelegate {
// [START refresh_token]
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
print("Firebase registration token: \(String(describing: fcmToken))")
let dataDict:[String: String] = ["token": fcmToken ?? ""]
NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
handleFCMToken()
// TODO: If necessary send token to application server.
// Note: This callback is fired at each app startup and whenever a new token is generated.
}
// [END refresh_token]
}

BIN
src/Nivesh/Assets.xcassets/.DS_Store View File


BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/.DS_Store View File


BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/100.png View File

Before After
Width: 100  |  Height: 100  |  Size: 4.5 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/102.png View File

Before After
Width: 102  |  Height: 102  |  Size: 4.7 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/1024.png View File

Before After
Width: 1024  |  Height: 1024  |  Size: 100 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/108.png View File

Before After
Width: 108  |  Height: 108  |  Size: 4.9 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/114.png View File

Before After
Width: 114  |  Height: 114  |  Size: 5.3 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/120.png View File

Before After
Width: 120  |  Height: 120  |  Size: 5.5 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/128.png View File

Before After
Width: 128  |  Height: 128  |  Size: 6.0 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/144.png View File

Before After
Width: 144  |  Height: 144  |  Size: 6.8 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/152.png View File

Before After
Width: 152  |  Height: 152  |  Size: 7.0 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/16.png View File

Before After
Width: 16  |  Height: 16  |  Size: 674 B

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/167.png View File

Before After
Width: 167  |  Height: 167  |  Size: 7.7 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/172.png View File

Before After
Width: 172  |  Height: 172  |  Size: 8.1 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/180.png View File

Before After
Width: 180  |  Height: 180  |  Size: 8.5 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/192.png View File

Before After
Width: 192  |  Height: 192  |  Size: 6.2 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/196.png View File

Before After
Width: 196  |  Height: 196  |  Size: 9.3 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/20.png View File

Before After
Width: 20  |  Height: 20  |  Size: 877 B

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/216.png View File

Before After
Width: 216  |  Height: 216  |  Size: 10 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/234.png View File

Before After
Width: 234  |  Height: 234  |  Size: 11 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/256.png View File

Before After
Width: 256  |  Height: 256  |  Size: 13 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/258.png View File

Before After
Width: 258  |  Height: 258  |  Size: 13 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/29.png View File

Before After
Width: 29  |  Height: 29  |  Size: 1.3 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/32.png View File

Before After
Width: 32  |  Height: 32  |  Size: 1.4 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/40.png View File

Before After
Width: 40  |  Height: 40  |  Size: 1.8 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/48.png View File

Before After
Width: 48  |  Height: 48  |  Size: 2.2 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/50.png View File

Before After
Width: 50  |  Height: 50  |  Size: 2.2 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/512.png View File

Before After
Width: 512  |  Height: 512  |  Size: 32 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/55.png View File

Before After
Width: 55  |  Height: 55  |  Size: 2.4 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/57.png View File

Before After
Width: 57  |  Height: 57  |  Size: 2.5 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/58.png View File

Before After
Width: 58  |  Height: 58  |  Size: 2.6 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/60.png View File

Before After
Width: 60  |  Height: 60  |  Size: 2.8 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/64.png View File

Before After
Width: 64  |  Height: 64  |  Size: 2.9 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/66.png View File

Before After
Width: 66  |  Height: 66  |  Size: 3.0 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/72.png View File

Before After
Width: 72  |  Height: 72  |  Size: 3.3 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/76.png View File

Before After
Width: 76  |  Height: 76  |  Size: 3.4 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/80.png View File

Before After
Width: 80  |  Height: 80  |  Size: 3.6 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/87.png View File

Before After
Width: 87  |  Height: 87  |  Size: 3.9 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/88.png View File

Before After
Width: 88  |  Height: 88  |  Size: 4.1 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/92.png View File

Before After
Width: 92  |  Height: 92  |  Size: 4.3 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/AppIcon-128.png View File

Before After
Width: 128  |  Height: 128  |  Size: 10 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/AppIcon-128@2x.png View File

Before After
Width: 256  |  Height: 256  |  Size: 26 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/AppIcon-16.png View File

Before After
Width: 16  |  Height: 16  |  Size: 771 B

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/AppIcon-16@2x.png View File

Before After
Width: 32  |  Height: 32  |  Size: 1.8 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/AppIcon-256.png View File

Before After
Width: 256  |  Height: 256  |  Size: 26 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/AppIcon-256@2x.png View File

Before After
Width: 512  |  Height: 512  |  Size: 71 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/AppIcon-32.png View File

Before After
Width: 32  |  Height: 32  |  Size: 1.8 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/AppIcon-32@2x.png View File

Before After
Width: 64  |  Height: 64  |  Size: 4.3 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/AppIcon-512.png View File

Before After
Width: 512  |  Height: 512  |  Size: 71 KiB

BIN
src/Nivesh/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png View File

Before After
Width: 1024  |  Height: 1024  |  Size: 226 KiB

+ 224
- 0
src/Nivesh/Assets.xcassets/AppIcon.appiconset/Contents.json View File

@ -0,0 +1,224 @@
{
"images" : [
{
"filename" : "40.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "60.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"filename" : "29.png",
"idiom" : "iphone",
"scale" : "1x",
"size" : "29x29"
},
{
"filename" : "58.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "87.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"filename" : "80.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "120.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
"filename" : "57.png",
"idiom" : "iphone",
"scale" : "1x",
"size" : "57x57"
},
{
"filename" : "114.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "57x57"
},
{
"filename" : "120.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"filename" : "180.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"filename" : "20.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"filename" : "40.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "29.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"filename" : "58.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "40.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
"filename" : "80.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "50.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "50x50"
},
{
"filename" : "100.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "50x50"
},
{
"filename" : "72.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "72x72"
},
{
"filename" : "144.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "72x72"
},
{
"filename" : "76.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"filename" : "152.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"filename" : "167.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"filename" : "1024.png",
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
},
{
"filename" : "AppIcon-16.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "16x16"
},
{
"filename" : "AppIcon-16@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "16x16"
},
{
"filename" : "AppIcon-32.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "32x32"
},
{
"filename" : "AppIcon-32@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "32x32"
},
{
"filename" : "AppIcon-128.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "128x128"
},
{
"filename" : "AppIcon-128@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "128x128"
},
{
"filename" : "AppIcon-256.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "256x256"
},
{
"filename" : "AppIcon-256@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "256x256"
},
{
"filename" : "AppIcon-512.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "512x512"
},
{
"filename" : "AppIcon-512@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "512x512"
},
{
"filename" : "192.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "192x192"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

+ 9
- 0
src/Nivesh/Assets.xcassets/Contents.json View File

@ -0,0 +1,9 @@
{
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"compression-type" : "gpu-optimized-smallest"
}
}

BIN
src/Nivesh/Assets.xcassets/n-logo.imageset/1080.png View File

Before After
Width: 360  |  Height: 360  |  Size: 24 KiB

BIN
src/Nivesh/Assets.xcassets/n-logo.imageset/1080@2x.png View File

Before After
Width: 720  |  Height: 720  |  Size: 55 KiB

BIN
src/Nivesh/Assets.xcassets/n-logo.imageset/1080@3x.png View File

Before After
Width: 1080  |  Height: 1080  |  Size: 48 KiB

+ 23
- 0
src/Nivesh/Assets.xcassets/n-logo.imageset/Contents.json View File

@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "1080.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "1080@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "1080@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

+ 23
- 0
src/Nivesh/Assets.xcassets/splash-screen-logo.imageset/Contents.json View File

@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "splash-screen-logo.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "splash-screen-logo@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "splash-screen-logo@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

BIN
src/Nivesh/Assets.xcassets/splash-screen-logo.imageset/splash-screen-logo.png View File

Before After
Width: 170  |  Height: 360  |  Size: 12 KiB

BIN
src/Nivesh/Assets.xcassets/splash-screen-logo.imageset/splash-screen-logo@2x.png View File

Before After
Width: 341  |  Height: 720  |  Size: 29 KiB

BIN
src/Nivesh/Assets.xcassets/splash-screen-logo.imageset/splash-screen-logo@3x.png View File

Before After
Width: 512  |  Height: 1080  |  Size: 28 KiB

+ 50
- 0
src/Nivesh/Base.lproj/LaunchScreen.storyboard View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina6_0" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="4mO-e4-REQ">
<rect key="frame" x="0.0" y="0.0" width="390" height="844"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="1000" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" verticalCompressionResistancePriority="1000" image="splash-screen-logo" translatesAutoresizingMaskIntoConstraints="NO" id="I2s-HW-Q4d">
<rect key="frame" x="0.0" y="0.0" width="390" height="844"/>
<color key="tintColor" systemColor="secondarySystemFillColor"/>
</imageView>
</subviews>
<viewLayoutGuide key="safeArea" id="XpK-Bq-A7U"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="I2s-HW-Q4d" firstAttribute="centerY" secondItem="4mO-e4-REQ" secondAttribute="centerY" id="4kv-Qc-mPU"/>
<constraint firstItem="I2s-HW-Q4d" firstAttribute="centerX" secondItem="4mO-e4-REQ" secondAttribute="centerX" id="6Z0-rS-c8Q"/>
<constraint firstItem="XpK-Bq-A7U" firstAttribute="trailing" secondItem="I2s-HW-Q4d" secondAttribute="trailing" id="P0W-Yo-EXM"/>
<constraint firstItem="I2s-HW-Q4d" firstAttribute="leading" secondItem="XpK-Bq-A7U" secondAttribute="leading" id="uVQ-4m-DsE"/>
<constraint firstItem="I2s-HW-Q4d" firstAttribute="top" secondItem="4mO-e4-REQ" secondAttribute="top" id="wM3-pS-BxC"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="50.724637681159422" y="374.33035714285711"/>
</scene>
</scenes>
<resources>
<image name="splash-screen-logo" width="170.66667175292969" height="360"/>
<systemColor name="secondarySystemFillColor">
<color red="0.47058823529999999" green="0.47058823529999999" blue="0.50196078430000002" alpha="0.16" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

+ 86
- 0
src/Nivesh/Base.lproj/Main.storyboard View File

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina5_9" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="Nivesh" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="812"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" id="PHY-vp-dMl" userLabel="Webview View">
<rect key="frame" x="0.0" y="0.0" width="375" height="812"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="p0s-Fg-eGP" userLabel="Splash Background">
<rect key="frame" x="0.0" y="0.0" width="375" height="812"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DIO-mU-n27" userLabel="Loading View">
<rect key="frame" x="88" y="306" width="200" height="200"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="n-logo" translatesAutoresizingMaskIntoConstraints="NO" id="4oa-LZ-pgs">
<rect key="frame" x="68" y="68" width="64" height="64"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<color key="tintColor" systemColor="secondarySystemFillColor"/>
<rect key="contentStretch" x="0.0" y="0.0" width="0.0" height="0.0"/>
</imageView>
<progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" progress="0.10000000000000001" id="xSD-dq-HF9">
<rect key="frame" x="50" y="146" width="100" height="15"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="secondarySystemFillColor"/>
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</progressView>
<imageView hidden="YES" opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="wifi.slash" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="TpV-I7-c6z">
<rect key="frame" x="85" y="159.33333333333314" width="31.999999999999886" height="30.000000000000085"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
</imageView>
</subviews>
<viewLayoutGuide key="safeArea" id="a0B-Gx-0cO"/>
<rect key="contentStretch" x="0.0" y="0.0" width="0.0" height="0.0"/>
</view>
</subviews>
</view>
</subviews>
</view>
</subviews>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
<connections>
<outlet property="connectionProblemView" destination="TpV-I7-c6z" id="76F-WR-UnJ"/>
<outlet property="loadingView" destination="DIO-mU-n27" id="Wlk-Yd-6b1"/>
<outlet property="progressView" destination="xSD-dq-HF9" id="0jL-XR-Xwq"/>
<outlet property="webviewView" destination="PHY-vp-dMl" id="qhH-E4-3lf"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1036.9230769230769" y="135.07109004739337"/>
</scene>
</scenes>
<resources>
<image name="n-logo" width="360" height="360"/>
<image name="wifi.slash" catalog="system" width="128" height="111"/>
<systemColor name="secondaryLabelColor">
<color red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="secondarySystemFillColor">
<color red="0.47058823529999999" green="0.47058823529999999" blue="0.50196078430000002" alpha="0.16" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

+ 1
- 0
src/Nivesh/Entitlements/.gitignore View File

@ -0,0 +1 @@
/GoogleService-Info.plist

+ 27
- 0
src/Nivesh/Entitlements/Entitlements.plist View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>production</string>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:app.nivesh.com</string>
<string>webcredentials:app.nivesh.com</string>
</array>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.personal-information.location</key>
<true/>
<key>com.apple.security.print</key>
<true/>
</dict>
</plist>

+ 124
- 0
src/Nivesh/Info.plist View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
</array>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Nivesh</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>com.nivesh.app</string>
<key>CFBundleURLSchemes</key>
<array>
<string>app</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationCategoryType</key>
<string></string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSCameraUsageDescription</key>
<string>App needs to capture user document for KYC mandated by Indian regulation (SEBI)</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Track current location by user request</string>
<key>NSMicrophoneUsageDescription</key>
<string>Capture Audio by user request</string>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
<key>UIBackgroundModes</key>
<array>
<string>processing</string>
<string>remote-notification</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleDefault</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>
<key>WKAppBoundDomains</key>
<array>
<string>sandbox.nivesh.com</string>
</array>
<key>branch_key</key>
<dict>
<key>live</key>
<string>key_live_ihFWcIYhk9JEbG6TR0dOSbkoDydh2HKF</string>
</dict>
<key>branch_universal_link_domains</key>
<dict>
<key>Item 0</key>
<string>nivesh.app.link</string>
<key>Item 1</key>
<string>nivesh-alternate.app.link</string>
</dict>
</dict>
</plist>

+ 29
- 0
src/Nivesh/NiveshRelease.entitlements View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>production</string>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:app.nivesh.com</string>
<string>webcredentials:app.nivesh.com</string>
<string>nivesh.app.link</string>
<string>nivesh-alternate.app.link</string>
</array>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.personal-information.location</key>
<true/>
<key>com.apple.security.print</key>
<true/>
</dict>
</plist>

+ 20
- 0
src/Nivesh/Printer.swift View File

@ -0,0 +1,20 @@
import UIKit
import WebKit
func printView(webView: WKWebView){
let printController = UIPrintInteractionController.shared
let printInfo = UIPrintInfo(dictionary:nil)
printInfo.outputType = UIPrintInfo.OutputType.general
printInfo.jobName = (webView.url?.absoluteString)!
printInfo.duplex = UIPrintInfo.Duplex.none
printInfo.orientation = UIPrintInfo.Orientation.portrait
printController.printPageRenderer = UIPrintPageRenderer()
printController.printPageRenderer?.addPrintFormatter(webView.viewPrintFormatter(), startingAtPageAt: 0)
printController.printInfo = printInfo
printController.showsNumberOfCopies = true
printController.present(animated: true)
}

+ 173
- 0
src/Nivesh/PushNotifications.swift View File

@ -0,0 +1,173 @@
import WebKit
import FirebaseMessaging
class SubscribeMessage {
var topic = ""
var eventValue = ""
var unsubscribe = false
struct Keys {
static var TOPIC = "topic"
static var UNSUBSCRIBE = "unsubscribe"
static var EVENTVALUE = "eventValue"
}
convenience init(dict: Dictionary<String,Any>) {
self.init()
if let topic = dict[Keys.TOPIC] as? String {
self.topic = topic
}
if let unsubscribe = dict[Keys.UNSUBSCRIBE] as? Bool {
self.unsubscribe = unsubscribe
}
if let eventValue = dict[Keys.EVENTVALUE] as? String {
self.eventValue = eventValue
}
}
}
func handleSubscribeTouch(message: WKScriptMessage) {
// [START subscribe_topic]
let subscribeMessages = parseSubscribeMessage(message: message)
if (subscribeMessages.count > 0){
let _message = subscribeMessages[0]
if (_message.unsubscribe) {
Messaging.messaging().unsubscribe(fromTopic: _message.topic) { error in }
}
else {
Messaging.messaging().subscribe(toTopic: _message.topic) { error in }
}
}
// [END subscribe_topic]
}
func parseSubscribeMessage(message: WKScriptMessage) -> [SubscribeMessage] {
var subscribeMessages = [SubscribeMessage]()
if let objStr = message.body as? String {
let data: Data = objStr.data(using: .utf8)!
do {
let jsObj = try JSONSerialization.jsonObject(with: data, options: .init(rawValue: 0))
if let jsonObjDict = jsObj as? Dictionary<String, Any> {
let subscribeMessage = SubscribeMessage(dict: jsonObjDict)
subscribeMessages.append(subscribeMessage)
} else if let jsonArr = jsObj as? [Dictionary<String, Any>] {
for jsonObj in jsonArr {
let sMessage = SubscribeMessage(dict: jsonObj)
subscribeMessages.append(sMessage)
}
}
} catch _ {
}
}
return subscribeMessages
}
func returnPermissionResult(isGranted: Bool){
DispatchQueue.main.async(execute: {
if (isGranted){
Nivesh.webView.evaluateJavaScript("this.dispatchEvent(new CustomEvent('push-permission-request', { detail: 'granted' }))")
}
else {
Nivesh.webView.evaluateJavaScript("this.dispatchEvent(new CustomEvent('push-permission-request', { detail: 'denied' }))")
}
})
}
func returnPermissionState(state: String){
DispatchQueue.main.async(execute: {
Nivesh.webView.evaluateJavaScript("this.dispatchEvent(new CustomEvent('push-permission-state', { detail: '\(state)' }))")
})
}
func handlePushPermission() {
UNUserNotificationCenter.current().getNotificationSettings () { settings in
switch settings.authorizationStatus {
case .notDetermined:
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: { (success, error) in
if error == nil {
if success == true {
returnPermissionResult(isGranted: true)
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
else {
returnPermissionResult(isGranted: false)
}
}
else {
returnPermissionResult(isGranted: false)
}
}
)
case .denied:
returnPermissionResult(isGranted: false)
case .authorized, .ephemeral, .provisional:
returnPermissionResult(isGranted: true)
@unknown default:
return;
}
}
}
func handlePushState() {
UNUserNotificationCenter.current().getNotificationSettings () { settings in
switch settings.authorizationStatus {
case .notDetermined:
returnPermissionState(state: "notDetermined")
case .denied:
returnPermissionState(state: "denied")
case .authorized:
returnPermissionState(state: "authorized")
case .ephemeral:
returnPermissionState(state: "ephemeral")
case .provisional:
returnPermissionState(state: "provisional")
@unknown default:
returnPermissionState(state: "unknown")
return;
}
}
}
func checkViewAndEvaluate(event: String, detail: String) {
if (!Nivesh.webView.isHidden && !Nivesh.webView.isLoading ) {
DispatchQueue.main.async(execute: {
Nivesh.webView.evaluateJavaScript("this.dispatchEvent(new CustomEvent('\(event)', { detail: \(detail) }))")
})
}
else {
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
checkViewAndEvaluate(event: event, detail: detail)
}
}
}
func handleFCMToken(){
DispatchQueue.main.async(execute: {
Messaging.messaging().token { token, error in
if let error = error {
print("Error fetching FCM registration token: \(error)")
checkViewAndEvaluate(event: "push-token", detail: "ERROR GET TOKEN")
} else if let token = token {
print("FCM registration token: \(token)")
checkViewAndEvaluate(event: "push-token", detail: "'\(token)'")
}
}
})
}
func sendPushToWebView(userInfo: [AnyHashable: Any]){
var json = "";
do {
let jsonData = try JSONSerialization.data(withJSONObject: userInfo)
json = String(data: jsonData, encoding: .utf8)!
} catch {
print("ERROR: userInfo parsing problem")
return
}
checkViewAndEvaluate(event: "push-notification", detail: json)
}

+ 111
- 0
src/Nivesh/SceneDelegate.swift View File

@ -0,0 +1,111 @@
import UIKit
@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
// If our app is launched with a universal link, we'll store it in this variable
static var universalLinkToLaunch: URL? = nil;
static var shortcutLinkToLaunch: URL? = nil
// This function is called when your app launches.
// Check to see if we were launched via a universal link or a shortcut.
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// See if our app is being launched via universal link.
// If so, store that link so we can navigate to it once our webView is initialized.
for userActivity in connectionOptions.userActivities {
if let universalLink = userActivity.webpageURL {
SceneDelegate.universalLinkToLaunch = universalLink;
break
}
}
// See if we were launched via shortcut
if let shortcutUrl = connectionOptions.shortcutItem?.type {
SceneDelegate.shortcutLinkToLaunch = URL.init(string: shortcutUrl)
}
// See if we were launched via scheme URL
if let schemeUrl = connectionOptions.urlContexts.first?.url {
// Convert scheme://url to a https://url
var comps = URLComponents(url: schemeUrl, resolvingAgainstBaseURL: false)
comps?.scheme = "https"
if let url = comps?.url {
SceneDelegate.universalLinkToLaunch = url;
}
}
}
// This function is called when our app is already running and the user clicks a custom scheme URL
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
if let scheme = URLContexts.first?.url {
// Convert scheme://url to a https://url and navigate to it
var comps = URLComponents(url: scheme, resolvingAgainstBaseURL: false)
comps?.scheme = "https"
if let url = comps?.url {
// Handle it inside our web view in a SPA-friendly way.
Nivesh.webView.evaluateJavaScript("location.href = '\(url)'")
}
}
}
// This function is called when our app is already running and the user clicks a universal link.
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
// Handle universal links into our app when the app is already running.
// This allows your PWA to open links to your domain, rather than opening in a browser tab.
// For more info about universal links, see https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app
// Ensure we're trying to launch a link.
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let universalLink = userActivity.webpageURL else {
return
}
// Handle it inside our web view in a SPA-friendly way.
Nivesh.webView.evaluateJavaScript("location.href = '\(universalLink)'")
}
// This function is called if our app is already loaded and the user activates the app via shortcut
func windowScene(_ windowScene: UIWindowScene,
performActionFor shortcutItem: UIApplicationShortcutItem,
completionHandler: @escaping (Bool) -> Void) {
if let shortcutUrl = URL.init(string: shortcutItem.type) {
Nivesh.webView.evaluateJavaScript("location.href = '\(shortcutUrl)'");
}
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}
}

+ 29
- 0
src/Nivesh/Settings.swift View File

@ -0,0 +1,29 @@
import WebKit
struct Cookie {
var name: String
var value: String
}
let gcmMessageIDKey = "00000000000" // update this with actual ID if using Firebase
// URL for first launch
let rootUrl = URL(string: "https://sandbox.nivesh.com")!
// allowed origin is for what we are sticking to pwa domain
// This should also appear in Info.plist
let allowedOrigins: [String] = ["sandbox.nivesh.com"]
// auth origins will open in modal and show toolbar for back into the main origin.
// These should also appear in Info.plist
let authOrigins: [String] = []
// allowedOrigins + authOrigins <= 10
let platformCookie = Cookie(name: "app-platform", value: "iOS App Store")
// UI options
let displayMode = "standalone" // standalone / fullscreen.
let adaptiveUIStyle = true // iOS 15+ only. Change app theme on the fly to dark/light related to WebView background color.
let overrideStatusBar = false // iOS 13-14 only. if you don't support dark/light system theme.
let statusBarTheme = "dark" // dark / light, related to override option.
let pullToRefresh = true // Enable/disable pull down to refresh page

+ 249
- 0
src/Nivesh/ViewController.swift View File

@ -0,0 +1,249 @@
import UIKit
import WebKit
var webView: WKWebView! = nil
class ViewController: UIViewController, WKNavigationDelegate, UIDocumentInteractionControllerDelegate {
var documentController: UIDocumentInteractionController?
func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
return self
}
@IBOutlet weak var loadingView: UIView!
@IBOutlet weak var progressView: UIProgressView!
@IBOutlet weak var connectionProblemView: UIImageView!
@IBOutlet weak var webviewView: UIView!
var toolbarView: UIToolbar!
var htmlIsLoaded = false;
private var themeObservation: NSKeyValueObservation?
var currentWebViewTheme: UIUserInterfaceStyle = .unspecified
override var preferredStatusBarStyle : UIStatusBarStyle {
if #available(iOS 13, *), overrideStatusBar{
if #available(iOS 15, *) {
return .default
} else {
return statusBarTheme == "dark" ? .lightContent : .darkContent
}
}
return .default
}
override func viewDidLoad() {
super.viewDidLoad()
initWebView()
initToolbarView()
loadRootUrl()
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification , object: nil)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
Nivesh.webView.frame = calcWebviewFrame(webviewView: webviewView, toolbarView: nil)
}
@objc func keyboardWillHide(_ notification: NSNotification) {
Nivesh.webView.setNeedsLayout()
}
func initWebView() {
Nivesh.webView = createWebView(container: webviewView, WKSMH: self, WKND: self, NSO: self, VC: self)
webviewView.addSubview(Nivesh.webView);
Nivesh.webView.uiDelegate = self;
Nivesh.webView.addObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress), options: .new, context: nil)
if(pullToRefresh){
let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: #selector(refreshWebView(_:)), for: UIControl.Event.valueChanged)
Nivesh.webView.scrollView.addSubview(refreshControl)
Nivesh.webView.scrollView.bounces = true
}
if #available(iOS 15.0, *), adaptiveUIStyle {
themeObservation = Nivesh.webView.observe(\.underPageBackgroundColor) { [unowned self] webView, _ in
currentWebViewTheme = Nivesh.webView.underPageBackgroundColor.isLight() ?? true ? .light : .dark
self.overrideUIStyle()
}
}
}
@objc func refreshWebView(_ sender: UIRefreshControl) {
Nivesh.webView?.reload()
sender.endRefreshing()
}
func createToolbarView() -> UIToolbar{
let winScene = UIApplication.shared.connectedScenes.first
let windowScene = winScene as! UIWindowScene
var statusBarHeight = windowScene.statusBarManager?.statusBarFrame.height ?? 60
#if targetEnvironment(macCatalyst)
if (statusBarHeight == 0){
statusBarHeight = 30
}
#endif
let toolbarView = UIToolbar(frame: CGRect(x: 0, y: 0, width: webviewView.frame.width, height: 0))
toolbarView.sizeToFit()
toolbarView.frame = CGRect(x: 0, y: 0, width: webviewView.frame.width, height: toolbarView.frame.height + statusBarHeight)
// toolbarView.autoresizingMask = [.flexibleTopMargin, .flexibleRightMargin, .flexibleWidth]
let flex = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let close = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(loadRootUrl))
toolbarView.setItems([close,flex], animated: true)
toolbarView.isHidden = true
return toolbarView
}
func overrideUIStyle(toDefault: Bool = false) {
if #available(iOS 15.0, *), adaptiveUIStyle {
if (((htmlIsLoaded && !Nivesh.webView.isHidden) || toDefault) && self.currentWebViewTheme != .unspecified) {
UIApplication
.shared
.connectedScenes
.flatMap { ($0 as? UIWindowScene)?.windows ?? [] }
.first { $0.isKeyWindow }?.overrideUserInterfaceStyle = toDefault ? .unspecified : self.currentWebViewTheme;
}
}
}
func initToolbarView() {
toolbarView = createToolbarView()
webviewView.addSubview(toolbarView)
}
@objc func loadRootUrl() {
Nivesh.webView.load(URLRequest(url: SceneDelegate.universalLinkToLaunch ?? SceneDelegate.shortcutLinkToLaunch ?? rootUrl))
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!){
htmlIsLoaded = true
self.setProgress(1.0, true)
self.animateConnectionProblem(false)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.8) {
Nivesh.webView.isHidden = false
self.loadingView.isHidden = true
self.setProgress(0.0, false)
self.overrideUIStyle()
}
}
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
htmlIsLoaded = false;
if (error as NSError)._code != (-999) {
self.overrideUIStyle(toDefault: true);
webView.isHidden = true;
loadingView.isHidden = false;
animateConnectionProblem(true);
setProgress(0.05, true);
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
self.setProgress(0.1, true);
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
self.loadRootUrl();
}
}
}
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if (keyPath == #keyPath(WKWebView.estimatedProgress) &&
Nivesh.webView.isLoading &&
!self.loadingView.isHidden &&
!self.htmlIsLoaded) {
var progress = Float(Nivesh.webView.estimatedProgress);
if (progress >= 0.8) { progress = 1.0; };
if (progress >= 0.3) { self.animateConnectionProblem(false); }
self.setProgress(progress, true);
}
}
func setProgress(_ progress: Float, _ animated: Bool) {
self.progressView.setProgress(progress, animated: animated);
}
func animateConnectionProblem(_ show: Bool) {
if (show) {
self.connectionProblemView.isHidden = false;
self.connectionProblemView.alpha = 0
UIView.animate(withDuration: 0.7, delay: 0, options: [.repeat, .autoreverse], animations: {
self.connectionProblemView.alpha = 1
})
}
else {
UIView.animate(withDuration: 0.3, delay: 0, options: [], animations: {
self.connectionProblemView.alpha = 0 // Here you will get the animation you want
}, completion: { _ in
self.connectionProblemView.isHidden = true;
self.connectionProblemView.layer.removeAllAnimations();
})
}
}
deinit {
Nivesh.webView.removeObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress))
}
}
extension UIColor {
// Check if the color is light or dark, as defined by the injected lightness threshold.
// Some people report that 0.7 is best. I suggest to find out for yourself.
// A nil value is returned if the lightness couldn't be determined.
func isLight(threshold: Float = 0.5) -> Bool? {
let originalCGColor = self.cgColor
// Now we need to convert it to the RGB colorspace. UIColor.white / UIColor.black are greyscale and not RGB.
// If you don't do this then you will crash when accessing components index 2 below when evaluating greyscale colors.
let RGBCGColor = originalCGColor.converted(to: CGColorSpaceCreateDeviceRGB(), intent: .defaultIntent, options: nil)
guard let components = RGBCGColor?.components else {
return nil
}
guard components.count >= 3 else {
return nil
}
let brightness = Float(((components[0] * 299) + (components[1] * 587) + (components[2] * 114)) / 1000)
return (brightness > threshold)
}
}
extension ViewController: WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "print" {
printView(webView: Nivesh.webView)
}
if message.name == "push-subscribe" {
handleSubscribeTouch(message: message)
}
if message.name == "push-permission-request" {
handlePushPermission()
}
if message.name == "push-permission-state" {
handlePushState()
}
if message.name == "push-token" {
handleFCMToken()
}
}
}

+ 406
- 0
src/Nivesh/WebView.swift View File

@ -0,0 +1,406 @@
import UIKit
import WebKit
import AuthenticationServices
import SafariServices
import FirebaseMessaging
func createWebView(container: UIView, WKSMH: WKScriptMessageHandler, WKND: WKNavigationDelegate, NSO: NSObject, VC: ViewController) -> WKWebView{
let config = WKWebViewConfiguration()
let userContentController = WKUserContentController()
userContentController.add(WKSMH, name: "print")
userContentController.add(WKSMH, name: "push-subscribe")
userContentController.add(WKSMH, name: "push-permission-request")
userContentController.add(WKSMH, name: "push-permission-state")
userContentController.add(WKSMH, name: "push-token")
config.userContentController = userContentController
config.limitsNavigationsToAppBoundDomains = false;
config.allowsInlineMediaPlayback = true
config.preferences.javaScriptCanOpenWindowsAutomatically = true
config.preferences.setValue(true, forKey: "standalone")
let webView = WKWebView(frame: calcWebviewFrame(webviewView: container, toolbarView: nil), configuration: config)
setCustomCookie(webView: webView)
webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
webView.isHidden = true;
webView.navigationDelegate = WKND
webView.scrollView.bounces = false
webView.scrollView.contentInsetAdjustmentBehavior = .never
webView.allowsBackForwardNavigationGestures = true
let deviceModel = UIDevice.current.model
let osVersion = UIDevice.current.systemVersion
let deviceID = UIDevice.current.identifierForVendor!.uuidString
let deviceName = UIDevice.current.name
let FCMToken = Messaging.messaging().fcmToken
webView.configuration.applicationNameForUserAgent = "Safari/604.1"
webView.customUserAgent = "Mozilla/5.0 (\(deviceModel); CPU \(deviceModel) OS \(osVersion.replacingOccurrences(of: ".", with: "_")) like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/\(osVersion) Mobile/15E148 Safari/604.1 PWAShell"
webView.addObserver(NSO, forKeyPath: #keyPath(WKWebView.estimatedProgress), options: NSKeyValueObservingOptions.new, context: nil)
let localStorageData: [String: Any] = [
"model": deviceModel,
"systemVersion": osVersion,
"deviceID": deviceID,
"deviceName": deviceName,
"FCMtoken" : FCMToken!
]
print("test", localStorageData)
if JSONSerialization.isValidJSONObject(localStorageData),
let data = try? JSONSerialization.data(withJSONObject: localStorageData, options: []),
let value = String(data: data, encoding: .utf8) {
let _deviceCookie = HTTPCookie(properties: [
.domain: rootUrl.host!,
.path: "/",
.name: "deviceInfo",
.value: "\(value)",
.secure: "FALSE",
.expires: NSDate(timeIntervalSinceNow: 31556926)
])!
webView.configuration.websiteDataStore.httpCookieStore.setCookie(_deviceCookie)
}
#if DEBUG
if #available(iOS 16.4, *) {
webView.isInspectable = true
}
#endif
return webView
}
func setAppStoreAsReferrer(contentController: WKUserContentController) {
let scriptSource = "document.referrer = `app-info://platform/ios-store`;"
let script = WKUserScript(source: scriptSource, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
contentController.addUserScript(script);
}
func setCustomCookie(webView: WKWebView) {
let _platformCookie = HTTPCookie(properties: [
.domain: rootUrl.host!,
.path: "/",
.name: platformCookie.name,
.value: platformCookie.value,
.secure: "FALSE",
.expires: NSDate(timeIntervalSinceNow: 31556926)
])!
webView.configuration.websiteDataStore.httpCookieStore.setCookie(_platformCookie)
}
func calcWebviewFrame(webviewView: UIView, toolbarView: UIToolbar?) -> CGRect{
if ((toolbarView) != nil) {
return CGRect(x: 0, y: toolbarView!.frame.height, width: webviewView.frame.width, height: webviewView.frame.height - toolbarView!.frame.height)
}
else {
let winScene = UIApplication.shared.connectedScenes.first
let windowScene = winScene as! UIWindowScene
var statusBarHeight = windowScene.statusBarManager?.statusBarFrame.height ?? 0
switch displayMode {
case "fullscreen":
#if targetEnvironment(macCatalyst)
if let titlebar = windowScene.titlebar {
titlebar.titleVisibility = .hidden
titlebar.toolbar = nil
}
#endif
return CGRect(x: 0, y: 0, width: webviewView.frame.width, height: webviewView.frame.height)
default:
#if targetEnvironment(macCatalyst)
statusBarHeight = 29
#endif
let windowHeight = webviewView.frame.height - statusBarHeight
return CGRect(x: 0, y: statusBarHeight, width: webviewView.frame.width, height: windowHeight)
}
}
}
extension ViewController: WKUIDelegate, WKDownloadDelegate {
// redirect new tabs to main webview
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
if (navigationAction.targetFrame == nil) {
webView.load(navigationAction.request)
}
return nil
}
// restrict navigation to target host, open external links in 3rd party apps
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if (navigationAction.request.url?.scheme == "about") {
return decisionHandler(.allow)
}
if (navigationAction.shouldPerformDownload || navigationAction.request.url?.scheme == "blob") {
return decisionHandler(.download)
}
if let requestUrl = navigationAction.request.url{
if let requestHost = requestUrl.host {
// NOTE: Match auth origin first, because host origin may be a subset of auth origin and may therefore always match
let matchingAuthOrigin = authOrigins.first(where: { requestHost.range(of: $0) != nil })
if (matchingAuthOrigin != nil) {
decisionHandler(.allow)
if (toolbarView.isHidden) {
toolbarView.isHidden = false
webView.frame = calcWebviewFrame(webviewView: webviewView, toolbarView: toolbarView)
}
return
}
let matchingHostOrigin = allowedOrigins.first(where: { requestHost.range(of: $0) != nil })
if (matchingHostOrigin != nil) {
// Open in main webview
decisionHandler(.allow)
if (!toolbarView.isHidden) {
toolbarView.isHidden = true
webView.frame = calcWebviewFrame(webviewView: webviewView, toolbarView: nil)
}
return
}
if (navigationAction.navigationType == .other &&
navigationAction.value(forKey: "syntheticClickType") as! Int == 0 &&
(navigationAction.targetFrame != nil) &&
// no error here, fake warning
(navigationAction.sourceFrame != nil)
) {
decisionHandler(.allow)
return
}
else {
decisionHandler(.cancel)
}
if ["http", "https"].contains(requestUrl.scheme?.lowercased() ?? "") {
// Can open with SFSafariViewController
let safariViewController = SFSafariViewController(url: requestUrl)
self.present(safariViewController, animated: true, completion: nil)
} else {
// Scheme is not supported or no scheme is given, use openURL
if (UIApplication.shared.canOpenURL(requestUrl)) {
UIApplication.shared.open(requestUrl)
}
}
} else {
decisionHandler(.cancel)
if (navigationAction.request.url?.scheme == "tel" || navigationAction.request.url?.scheme == "mailto" ){
if (UIApplication.shared.canOpenURL(requestUrl)) {
UIApplication.shared.open(requestUrl)
}
}
else {
if requestUrl.isFileURL {
// not tested
downloadAndOpenFile(url: requestUrl.absoluteURL)
}
// if (requestUrl.absoluteString.contains("base64")){
// downloadAndOpenBase64File(base64String: requestUrl.absoluteString)
// }
}
}
}
else {
decisionHandler(.cancel)
}
}
// Handle javascript: `window.alert(message: String)`
func webView(_ webView: WKWebView,
runJavaScriptAlertPanelWithMessage message: String,
initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping () -> Void) {
// Set the message as the UIAlertController message
let alert = UIAlertController(
title: nil,
message: message,
preferredStyle: .alert
)
// Add a confirmation action OK
let okAction = UIAlertAction(
title: "OK",
style: .default,
handler: { _ in
// Call completionHandler
completionHandler()
}
)
alert.addAction(okAction)
// Display the NSAlert
present(alert, animated: true, completion: nil)
}
// Handle javascript: `window.confirm(message: String)`
func webView(_ webView: WKWebView,
runJavaScriptConfirmPanelWithMessage message: String,
initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping (Bool) -> Void) {
// Set the message as the UIAlertController message
let alert = UIAlertController(
title: nil,
message: message,
preferredStyle: .alert
)
// Add a confirmation action Cancel
let cancelAction = UIAlertAction(
title: "Cancel",
style: .cancel,
handler: { _ in
// Call completionHandler
completionHandler(false)
}
)
// Add a confirmation action OK
let okAction = UIAlertAction(
title: "OK",
style: .default,
handler: { _ in
// Call completionHandler
completionHandler(true)
}
)
alert.addAction(cancelAction)
alert.addAction(okAction)
// Display the NSAlert
present(alert, animated: true, completion: nil)
}
// Handle javascript: `window.prompt(prompt: String, defaultText: String?)`
func webView(_ webView: WKWebView,
runJavaScriptTextInputPanelWithPrompt prompt: String,
defaultText: String?,
initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping (String?) -> Void) {
// Set the message as the UIAlertController message
let alert = UIAlertController(
title: nil,
message: prompt,
preferredStyle: .alert
)
// Add a confirmation action Cancel
let cancelAction = UIAlertAction(
title: "Cancel",
style: .cancel,
handler: { _ in
// Call completionHandler
completionHandler(nil)
}
)
// Add a confirmation action OK
let okAction = UIAlertAction(
title: "OK",
style: .default,
handler: { _ in
// Call completionHandler with Alert input
if let input = alert.textFields?.first?.text {
completionHandler(input)
}
}
)
alert.addTextField { textField in
textField.placeholder = defaultText
}
alert.addAction(cancelAction)
alert.addAction(okAction)
// Display the NSAlert
present(alert, animated: true, completion: nil)
}
func downloadAndOpenFile(url: URL){
let destinationFileUrl = url
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)
let request = URLRequest(url:url)
let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
if let tempLocalUrl = tempLocalUrl, error == nil {
if let statusCode = (response as? HTTPURLResponse)?.statusCode {
print("Successfully download. Status code: \(statusCode)")
}
do {
try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
self.openFile(url: destinationFileUrl)
} catch (let writeError) {
print("Error creating a file \(destinationFileUrl) : \(writeError)")
}
} else {
print("Error took place while downloading a file. Error description: \(error?.localizedDescription ?? "N/A") ")
}
}
task.resume()
}
// func downloadAndOpenBase64File(base64String: String) {
// // Split the base64 string to extract the data and the file extension
// let components = base64String.components(separatedBy: ";base64,")
// // Make sure the base64 string has the correct format
// guard components.count == 2, let format = components.first?.split(separator: "/").last else {
// print("Invalid base64 string format")
// return
// }
// // Remove the data type prefix to get the base64 data
// let dataString = components.last!
// if let imageData = Data(base64Encoded: dataString) {
// let documentsUrl: URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
// let destinationFileUrl = documentsUrl.appendingPathComponent("image.\(format)")
// do {
// try imageData.write(to: destinationFileUrl)
// self.openFile(url: destinationFileUrl)
// } catch {
// print("Error writing image to file url: \(destinationFileUrl): \(error)")
// }
// }
// }
func openFile(url: URL) {
self.documentController = UIDocumentInteractionController(url: url)
self.documentController?.delegate = self
self.documentController?.presentPreview(animated: true)
}
func webView(_ webView: WKWebView, navigationAction: WKNavigationAction, didBecome download: WKDownload) {
download.delegate = self
}
func download(_ download: WKDownload, decideDestinationUsing response: URLResponse,
suggestedFilename: String,
completionHandler: @escaping (URL?) -> Void) {
let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let fileURL = documentsPath.appendingPathComponent(suggestedFilename)
self.openFile(url: fileURL)
completionHandler(fileURL)
}
}

+ 21
- 0
src/Podfile View File

@ -0,0 +1,21 @@
# Uncomment the next line to define a global platform for your project
platform :ios, '15.0'
target 'Nivesh' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# Add the pod for Firebase Cloud Messaging
pod 'FirebaseCore'
pod 'FirebaseAnalytics'
pod 'Firebase/Messaging'
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.0'
end
end
end

BIN
src/launch-128.png View File

Before After
Width: 128  |  Height: 128  |  Size: 12 KiB

BIN
src/launch-192.png View File

Before After
Width: 196  |  Height: 196  |  Size: 20 KiB

BIN
src/launch-256.png View File

Before After
Width: 256  |  Height: 256  |  Size: 27 KiB

BIN
src/launch-512.png View File

Before After
Width: 512  |  Height: 512  |  Size: 63 KiB

BIN
src/launch-64.png View File

Before After
Width: 64  |  Height: 64  |  Size: 5.1 KiB

Loading…
Cancel
Save

Powered by TurnKey Linux.