Add Objective-C iOS demo app (UIKit) matching the Swift demo#6
Add Objective-C iOS demo app (UIKit) matching the Swift demo#6dustturtle merged 3 commits intomainfrom
Conversation
Co-authored-by: dustturtle <2305214+dustturtle@users.noreply.github.com>
…t file Co-authored-by: dustturtle <2305214+dustturtle@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds a new UIKit-based iOS demo app for the Objective-C SDK under Examples/iOSDemoObjC/, intended to mirror the existing SwiftUI demo (Examples/iOSDemo/) and document it in the repo.
Changes:
- Introduces a new
iOSDemoObjC.xcodeprojand UIKit app (AppDelegate + navigation hub + 4 demo screens). - Adds an Objective-C
SocketManagerwrapper aroundGCDAsyncSocketusingNSNotificationupdates. - Updates
.gitignoreandREADME.mdto include and document the new ObjC iOS demo.
Reviewed changes
Copilot reviewed 20 out of 21 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Documents the new ObjC UIKit demo app and updates demo headings. |
| .gitignore | Adds an exception so Examples/iOSDemoObjC/iOSDemoObjC.xcodeproj is tracked. |
| Examples/iOSDemoObjC/iOSDemoObjC/main.m | Adds app entry point for the new ObjC UIKit demo. |
| Examples/iOSDemoObjC/iOSDemoObjC/AppDelegate.h | Declares app delegate + window for demo app. |
| Examples/iOSDemoObjC/iOSDemoObjC/AppDelegate.m | Sets up window + root navigation controller. |
| Examples/iOSDemoObjC/iOSDemoObjC/MainViewController.h | Declares main navigation hub controller. |
| Examples/iOSDemoObjC/iOSDemoObjC/MainViewController.m | Implements navigation to the 4 feature demo screens. |
| Examples/iOSDemoObjC/iOSDemoObjC/SocketManager.h | Declares ObjC socket wrapper API + update notification. |
| Examples/iOSDemoObjC/iOSDemoObjC/SocketManager.m | Implements socket wrapper + delegate callbacks + notifications. |
| Examples/iOSDemoObjC/iOSDemoObjC/Views/StreamBufferDemoViewController.h | Declares StreamBuffer demo screen. |
| Examples/iOSDemoObjC/iOSDemoObjC/Views/StreamBufferDemoViewController.m | Implements StreamBuffer interactive demo UI. |
| Examples/iOSDemoObjC/iOSDemoObjC/Views/SSEParserDemoViewController.h | Declares SSE parser demo screen. |
| Examples/iOSDemoObjC/iOSDemoObjC/Views/SSEParserDemoViewController.m | Implements SSE parser interactive demo UI. |
| Examples/iOSDemoObjC/iOSDemoObjC/Views/UTF8SafetyDemoViewController.h | Declares UTF-8 safety demo screen. |
| Examples/iOSDemoObjC/iOSDemoObjC/Views/UTF8SafetyDemoViewController.m | Implements UTF-8 boundary safety interactive demo UI. |
| Examples/iOSDemoObjC/iOSDemoObjC/Views/SocketConnectionDemoViewController.h | Declares live socket connection demo screen. |
| Examples/iOSDemoObjC/iOSDemoObjC/Views/SocketConnectionDemoViewController.m | Implements connect/send/receive/TLS/SSE/streaming UI. |
| Examples/iOSDemoObjC/iOSDemoObjC/Assets.xcassets/Contents.json | Adds asset catalog metadata. |
| Examples/iOSDemoObjC/iOSDemoObjC/Assets.xcassets/AppIcon.appiconset/Contents.json | Adds app icon asset metadata. |
| Examples/iOSDemoObjC/iOSDemoObjC/Assets.xcassets/AccentColor.colorset/Contents.json | Adds accent color asset metadata. |
| Examples/iOSDemoObjC/iOSDemoObjC.xcodeproj/project.pbxproj | Adds the new Xcode project wiring in sources/resources/build settings. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - (void)managerDidUpdate { | ||
| UIView *dot = self.navigationItem.rightBarButtonItem.customView; | ||
| dot.backgroundColor = self.manager.isConnected ? UIColor.systemGreenColor : UIColor.systemRedColor; | ||
| [self.tableView reloadData]; | ||
| } |
There was a problem hiding this comment.
managerDidUpdate calls reloadData for every socket update. With streaming text/SSE enabled this can fire very frequently and cause visible UI jank. Consider throttling updates (e.g., coalesce with a timer) and/or reloading only the affected sections/rows instead of the entire table.
| /* Begin PBXFrameworksBuildPhase section */ | ||
| B3000001 /* Frameworks */ = { | ||
| isa = PBXFrameworksBuildPhase; | ||
| buildActionMask = 2147483647; | ||
| files = ( | ||
| ); | ||
| runOnlyForDeploymentPostprocessing = 0; | ||
| }; |
There was a problem hiding this comment.
The target links no additional frameworks (Frameworks build phase is empty), but the included ObjC SDK sources import and call Network.framework APIs (e.g., nw_connection_t). Add Network.framework to “Link Binary With Libraries” (or set OTHER_LDFLAGS to include -framework Network) so the demo app links successfully.
| - (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)error { | ||
| _isConnected = NO; | ||
| if (error) { | ||
| [self appendLog:[NSString stringWithFormat:@"🔴 Disconnected: %@", error.localizedDescription]]; | ||
| } else { | ||
| [self appendLog:@"🔴 Disconnected"]; | ||
| } | ||
| } |
There was a problem hiding this comment.
After a disconnect (especially a remote disconnect), self.socket is left non-nil, which can leave the manager holding a stale socket instance and makes sendData:/readData think a socket exists even though it’s disconnected. Consider setting self.socket = nil (and optionally resetting readTag/received buffers) inside socketDidDisconnect:withError:.
| cell.textLabel.text = @"Port"; | ||
| field.text = self.port; | ||
| field.placeholder = @"Port"; | ||
| field.keyboardType = UIKeyboardTypeNumberPad; |
There was a problem hiding this comment.
The Port field uses UIKeyboardTypeNumberPad, which has no Return/Done key, so textFieldShouldReturn: won’t be invoked and the keyboard can’t be dismissed via the configured returnKeyType. Add an inputAccessoryView (Done toolbar button) or use a keyboard type that provides a Return key.
| field.keyboardType = UIKeyboardTypeNumberPad; | |
| field.keyboardType = UIKeyboardTypeNumbersAndPunctuation; |
Companion UIKit iOS demo for the ObjC SDK, mirroring the existing SwiftUI demo at
Examples/iOSDemo/.New:
Examples/iOSDemoObjC/UITableViewControllernavigation hub (≡ SwiftContentView)GCDAsyncSocketwithNSNotification-based state updates (≡ SwiftObservableObjectSocketManager)StreamBufferDemoViewController— sticky/split packet, delimiter readsSSEParserDemoViewController— single/multi/split SSE events, LLM streaming simUTF8SafetyDemoViewController— multi-byte boundary detectionSocketConnectionDemoViewController— live connection with TLS/SSE/streaming toggles../../ObjC/NWAsyncSocketObjC/) withHEADER_SEARCH_PATHSpointing to theinclude/directoryOther changes
.gitignore— added exception forExamples/iOSDemoObjC/iOSDemoObjC.xcodeprojREADME.md— documented the ObjC iOS demo in both the file structure and demo sectionsUsage
Open
Examples/iOSDemoObjC/iOSDemoObjC.xcodeprojin Xcode → run on simulator or device.💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.