{"id":19839417,"url":"https://github.com/scientifichackers/flutter-plugin-scaffold","last_synced_at":"2025-05-01T19:30:20.410Z","repository":{"id":56837071,"uuid":"188213350","full_name":"scientifichackers/flutter-plugin-scaffold","owner":"scientifichackers","description":"A scaffold for writing flutter plugins","archived":false,"fork":false,"pushed_at":"2020-04-16T06:50:40.000Z","size":156,"stargazers_count":17,"open_issues_count":0,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-06T17:03:52.334Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scientifichackers.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-05-23T10:34:24.000Z","updated_at":"2025-03-14T11:40:15.000Z","dependencies_parsed_at":"2022-09-09T18:00:59.686Z","dependency_job_id":null,"html_url":"https://github.com/scientifichackers/flutter-plugin-scaffold","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scientifichackers%2Fflutter-plugin-scaffold","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scientifichackers%2Fflutter-plugin-scaffold/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scientifichackers%2Fflutter-plugin-scaffold/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scientifichackers%2Fflutter-plugin-scaffold/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scientifichackers","download_url":"https://codeload.github.com/scientifichackers/flutter-plugin-scaffold/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251932513,"owners_count":21667157,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-12T12:22:21.332Z","updated_at":"2025-05-01T19:30:19.864Z","avatar_url":"https://github.com/scientifichackers.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Sponsor](https://img.shields.io/badge/Sponsor-jaaga_labs-red.svg?style=for-the-badge)](https://www.jaaga.in/labs)\n[![Pub](https://img.shields.io/pub/v/plugin_scaffold.svg?style=for-the-badge)](https://pub.dartlang.org/packages/plugin_scaffold)\n\n# Flutter Plugin Scaffold\n\nTired of endless switch-cases in your Flutter plugin code?\nThis module is for you!\n\n- Dynamic method dispatch (Only Kotlin)\n- Built-in error serialization for both platforms\n- Superior streams.\n\nUsed to create plugins such as [flutter_cogntio_plugin](https://github.com/pycampers/flutter_cognito_plugin),\n[rx_ble](https://github.com/pycampers/flutter-rx-ble), [flutter_pdf_viewer](https://github.com/pycampers/flutter_pdf_viewer),\netc.\n\n## TLDR\n\nIt lets you turn this:-\n\n```kotlin\nchannel.setMethodCallHandler { call, result -\u003e\n  when (call.method) {\n    \"orange\" -\u003e ...\n    \"banana\" -\u003e ...\n    \"mango\" -\u003e ...\n    \"apple\" -\u003e ...\n  }\n}\n```\n\nInto this beauty:-\n\n```kotlin\nimport com.pycampers.plugin_scaffold.createPluginScaffold\n\n\nclass MyPlugin {\n    fun orange(call: MethodCall, result: Result) {\n        ...\n    }\n\n    fun banana(call: MethodCall, result: Result) {\n        ...\n    }\n\n    fun mango(call: MethodCall, result: Result) {\n        ...\n    }\n\n    fun apple(call: MethodCall, result: Result) {\n        ...\n    }\n}\n\ncreatePluginScaffold(registrar.messenger(), \"myFancyChannel\", MyPlugin())\n```\n\n## Errors\n\nAny errors that occur in native code tend to instantly crash the app.\nSending them back to flutter can be a real PITA.\n\nThis module does everything in its power to prevent such mishaps.\n\nSo yes,\nYou get 100% dart catch-able `PlatformExceptions` with stacktraces of native code!\n\n```\nD/MethodCallDispatcher( 3572): piping exception to flutter: java.lang.IllegalArgumentException: Hello from Kotlin!\nE/flutter ( 3572): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: PlatformException(java.lang.IllegalArgumentException, Hello from Kotlin!, java.lang.IllegalArgumentException: Hello from Kotlin!\nE/flutter ( 3572): \tat com.pycampers.method_call_dispatcher_example.MyPlugin$myBrokenCallbackMethod$1$run$1.invoke(MainActivity.kt:33)\nE/flutter ( 3572): \tat com.pycampers.method_call_dispatcher_example.MyPlugin$myBrokenCallbackMethod$1$run$1.invoke(MainActivity.kt:30)\nE/flutter ( 3572): \tat com.pycampers.method_call_dispatcher.MethodCallDispatcherPluginKt.trySend(MethodCallDispatcherPlugin.kt:52)\nE/flutter ( 3572): \tat com.pycampers.method_call_dispatcher_example.MyPlugin$myBrokenCallbackMethod$1.run(MainActivity.kt:32)\nE/flutter ( 3572): \tat java.util.Timer$TimerImpl.run(Timer.java:284)\nE/flutter ( 3572): )\n```\n\n```\n[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: PlatformException(Runner.MyError.fatalError, The operation couldn’t be completed. (Runner.MyError error 0.), 0   plugin_scaffold                     0x0000000106131435 $s15plugin_scaffold14serializeErrorySo07FlutterD0CypF + 309\n1   plugin_scaffold                     0x0000000106135a39 $s15plugin_scaffold20createPluginScaffold9messenger11channelName9methodMap05eventJ0So20FlutterMethodChannelC_SDySSSo0l5EventN0CGtSo0L15BinaryMessenger_p_SSSDySSypGSDySSSo0L13StreamHandler_So8NSObjectpGtFySo0lM4CallC_yypSgctcfU_yycfU_ASycfU_ + 121\n2   plugin_scaffold                     0x000000010613654d $s15plugin_scaffold20createPluginScaffold9messenger11channelName9methodMap05eventJ0So20FlutterMethodChannelC_SDySSSo0l5EventN0CGtSo0L15BinaryMessenger_p_SSSDySSypGSDySSSo0L13StreamHandler_So8NSObjectpGtFySo0lM4CallC_yypSgctcfU_yycfU_ASycfU_TA + 13\n3   plugin_scaffold                     0x0000000106133099 $s15plugin_scaffold7trySendyyyypSgc_ACyKcSgtFyycfU_ + 297\n\u003c…\u003e\n[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: PlatformException(Error Domain=hello Code=123 \"(null)\", The operation couldn’t be completed. (hello error 123.), 0   plugin_scaffold                     0x0000000106131435 $s15plugin_scaffold14serializeErrorySo07FlutterD0CypF + 309\n1   plugin_scaffold                     0x0000000106135a39 $s15plugin_scaffold20createPluginScaffold9messenger11channelName9methodMap05eventJ0So20FlutterMethodChannelC_SDySSSo0l5EventN0CGtSo0L15BinaryMessenger_p_SSSDySSypGSDySSSo0L13StreamHandler_So8NSObjectpGtFySo0lM4CallC_yypSgctcfU_yycfU_ASycfU_ + 121\n2   plugin_scaffold                     0x000000010613654d $s15plugin_scaffold20createPluginScaffold9messenger11channelName9methodMap05eventJ0So20FlutterMethodChannelC_SDySSSo0l5EventN0CGtSo0L15BinaryMessenger_p_SSSDySSypGSDySSSo0L13StreamHandler_So8NSObjectpGtFySo0lM4CallC_yypSgctcfU_yycfU_ASycfU_TA + 13\n3   plugin_scaffold                     0x0000000106133099 $s15plugin_scaffold7trySendyyyypSgc_ACyKcSgtFyycfU_ + \u003c…\u003e\n```\n\n## Streams\n\nFlutter's `EventChannel`, has a flaw in that it only lets you open only a single stream at a time.\n\nPlugin Scaffold's stream methods build upon regular `MethodChannel` callback methods,\nand provide a more flexible solution.\n\n*This comes with a caveat, though. You can no longer use regular `MethodChannel.setMethodCallHandler()`,\nand must use `PluginScaffold.setMethodCallHandler()` instead.*\n\n## Install\n\nFirst install the plugin using regular instructions on [dart pub](https://pub.dartlang.org/packages/plugin_scaffold#-installing-tab-).\n\nNext, add the follwoing to `ios/\u003cplugin-name\u003e.podspec`\n\n```\nPod::Spec.new do |s|\n  ...\n  \n  s.dependency 'plugin_scaffold'\nend\n```\n\n## Usage\n\nThe example is app available @ [`main.dart`](example/lib/main.dart),\n[`MainActivity.kt`](example/android/app/src/main/kotlin/com/pycampers/plugin_scaffold_example/MainActivity.kt)\n\u0026 [`AppDelegate.dart`](example/ios/Runner/AppDelegate.swift)\n\nThe core plugin code can be found @ [`plugin_scaffold.dart`](lib/plugin_scaffold.dart),\n[`MethodCallDispatcherPlugin.kt`](android/src/main/kotlin/com/pycampers/plugin_scaffold/PluginScaffoldPlugin.kt)\n\u0026 [`SwiftPluginScaffoldPlugin.swift`](ios/Classes/SwiftPluginScaffoldPlugin.swift)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscientifichackers%2Fflutter-plugin-scaffold","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscientifichackers%2Fflutter-plugin-scaffold","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscientifichackers%2Fflutter-plugin-scaffold/lists"}