{"id":19810546,"url":"https://github.com/goodow/gdoperation","last_synced_at":"2025-06-28T15:33:19.942Z","repository":{"id":56911932,"uuid":"76102300","full_name":"goodow/GDOperation","owner":"goodow","description":"Collaborative Rich Text on iOS (基于 JSON 的差量数据传输和多人实时协同编辑)","archived":false,"fork":false,"pushed_at":"2017-12-29T09:15:12.000Z","size":22682,"stargazers_count":9,"open_issues_count":0,"forks_count":7,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-04-28T12:54:23.123Z","etag":null,"topics":["collaborative-editing","ios","nsattributedstring","operational-transformation","rich-text"],"latest_commit_sha":null,"homepage":"https://live.goodow.com/editor","language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/goodow.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2016-12-10T09:10:32.000Z","updated_at":"2021-02-08T08:45:52.000Z","dependencies_parsed_at":"2022-08-21T03:20:12.014Z","dependency_job_id":null,"html_url":"https://github.com/goodow/GDOperation","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goodow%2FGDOperation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goodow%2FGDOperation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goodow%2FGDOperation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goodow%2FGDOperation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/goodow","download_url":"https://codeload.github.com/goodow/GDOperation/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251847828,"owners_count":21653582,"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":["collaborative-editing","ios","nsattributedstring","operational-transformation","rich-text"],"created_at":"2024-11-12T09:22:19.279Z","updated_at":"2025-05-01T08:32:03.272Z","avatar_url":"https://github.com/goodow.png","language":"Objective-C","readme":"# GDOperation\n\n## Installation\n\nGDOperation is available through [CocoaPods](http://cocoapods.org). To install\nit, simply add the following line to your Podfile:\n\n```ruby\npod \"GDOperation\"\n```\n\n## Quickstart\n\n```objective-c\n// 使用 UITextView 创建 GDORichText\nUITextView *textView = ...;\nGDORichText *richText = GDOTextView.attachView(textView);\n// 或者使用 UILabel 和 YYTextView\n// GDORichText *richText = GDOLabel.attachView(uiLabel);\n// GDORichText *richText = GDOYYTextView.attachView(yyTextView);\n\n// 在索引 0 处插入文本\"Hello World!\", 同时指定文本颜色和点击链接\nrichText.insertText(0, @\"Hello World!\",\n    GDOPBAttribute.new.setColor(@\"#cccccc\").setLink(@\"schema://views/GiftPanel?k=v\"));\n```\n\n## Live Playground\n打开 https://live.goodow.com/editor 试试看, 当你在网页上的富文本编辑器里进行编辑的同时, iOS 应用里的富文本预览会即时生效, 实时反应你的修改. 要在 iOS 上预览, 可以:\n  - 运行 [Example 工程](https://github.com/goodow/GDOperation/tree/master/Example)\n    - `git clone https://github.com/goodow/GDOperation.git`\n    - `cd GDOperation/Example; pod install`\n  - 在 AppStore 上下载 [腾讯直播](https://itunes.apple.com/cn/app/id1059716058), 打开路径: 我的-\u003e设置-\u003e快速连续三次点击\"设置\"标题栏打开彩蛋-\u003e实验室-\u003e开发者-\u003e富文本预览\n\n网页编辑|iOS Example 工程预览\n---|---\n![网页编辑截图](screenshots/web.png)|![iOS 原生应用预览截图](screenshots/ios.png)\n\n## Delta: 富文本的数据模型\n\n富文本的数据来源有两类: 后台下发和使用客户端 API 创建.\n这些数据最终将被转换成一个NSAttributedString来表示内容和样式. 由于iOS自身的限制, 三种界面实现所支持的特性丰富程度依次为: UILabel \u003c UITextView \u003c YYTextView. 例如UILabel不支持链接的点击事件, 只有YYTextView可支持任意自定义视图元素, 所以引入第三方界面组件[YYText](https://github.com/ibireme/YYText)扩展了NSAttributedString以支持Button等控件.\n\n#### 后台下发\n\n后台下发数据是目前用得最多的场景. 支持 Google Protobuf ([.proto 文件](protos/goodow_operation.proto)) 和 JSON 数据格式. JSON 格式可以在 [Live Playground](https://live.goodow.com/editor) 上进行编辑和观察.\n\n```objective-c\n// 使用 UITextView 创建 GDORichText\nUITextView *textView = ...;\nGDORichText *richText = GDOTextView.attachView(textView);\n\n// 创建数据模型, 反序列化自JSON, JCE 或 Protobuf\nNSDictionary *json = @{@\"ops\": @[\n    @{\n      @\"insert\": @\"Hello World!\",\n      @\"attributes\": @{\n        @\"color\": @\"#cccccc\",\n        @\"link\": @\"txlive://views/GiftPanel?a=b\",\n      }\n    },\n    @{\n      @\"insert\": @\"\\n\", // 换行符表示一个段落的结束, 这里的样式作用于整个段落\n      @\"attributes\": @{\n        @\"align\": @\"center\"\n      }\n    }\n  ]};\nGDOPBDelta *delta = [GDOPBDelta parseFromJson:json error:nil];\n// 更新界面\nrichText.updateContents(delta);\n```\n\n\n#### 客户端 API\n\niOS 提供 Objective-C 语言的 API, 使用链式形式调用\n\n```objective-c\n// 调用API创建数据\nGDOPBAttribute *attributes = GDOPBAttribute.new.setColor(@\"#cccccc\").setLink(@\"txlive://views/GiftPanel?a=b\");\nGDOPBDelta *delta = GDOPBDelta.new.insert(@\"Hello\", attributes).insert(@\" World!\", nil);\n// 更新界面\nrichText.updateContents(delta);\n```\n\n## Formats\n\nGDOperation支持很多种格式, 分为三类: Inline, Block, Embeds.\n\n#### Inline 字符样式\n\n  - Color - `color` 字符着色\n  - Background Color - `background` 背景色, \"#cccccc\", Uses six character hex values to represent colors\n  - Size - `size` 字号\n  - Font - `font` 字体\n  - Link - `link` 链接\n  - Bold - `bold`  字重, false: UIFontWeightLight, true: UIFontWeightBold\n  - Italic - `italic` 斜体\n  - Underline - `underline` 下划线\n  - Strikethrough - `strike` 删除线\n  - Inline Code - `code`\n  - Superscript/Subscript - `script`\n\n#### Block 段落样式\n\n  - Text Alignment - `align` 对齐方式\n\n#### Embeds 非文本类型界面元素\n\n  - Image - `image` 图片, 值可以为以下类型:\"http[s]://xxx\", \"file://abc\", \"file:///Documents/abc.jpg\", \"data:image/png;base64,xyz==\". 可指定 width, height, link 等属性\n  - Button - `button` 按钮, 仅YYTextView支持, 字符串值将为按钮的标题\n  - Space - `space` 空白占位\n\n## Comparison Table\n\n|  | UILabel | UITextView | YYTextView | UIWebView |\n| ------------ | ------------ | ------------ | ------------ | ------------ |\n| 底层数据格式 | NSAttributedString | NSAttributedString | NSAttributedString | HTML |\n| 链接事件 | No | Yes | Yes | Yes |\n| 图片 | Yes | Yes | Yes | Yes |\n| 可编辑 | No | Yes | Yes | Yes |\n| 嵌入自定义元素 | No | No | Yes | No |\n\n相较于 WebView 方案, GDOperation 更加轻量, 当需求变得复杂时, 可定制化开发自定义元素, 因而具备更强的可扩展性.\n\n\n\n## Author\n\nLarry Tin, dev@goodow.com\n\n## License\n\nGDOperation is available under the MIT license. See the LICENSE file for more info.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoodow%2Fgdoperation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgoodow%2Fgdoperation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoodow%2Fgdoperation/lists"}