combinecommunity / combinecocoa Goto Github PK
View Code? Open in Web Editor NEWCombine publisher bridges for UIKit
License: MIT License
Combine publisher bridges for UIKit
License: MIT License
Describe the bug
UIPageControl.currentPagePublisher is working as unexpected. It only emit the first value at all. This is debug message:
currentPagePublisher: receive subscription: ((extension in CombineCocoa):Combine.Publishers.ControlProperty<__C.UIPageControl, Swift.Int>.(unknown context at $1043e2a68).Subscription<Combine.Publishers.Print<Combine.AnyPublisher<Swift.Int, Swift.Never>>.(unknown context at $107462a60).Inner<Combine.Publishers.Map<Combine.Publishers.Print<Combine.AnyPublisher<Swift.Int, Swift.Never>>, Swift.Bool>.(unknown context at $10746bbe8).Inner<Combine.Publishers.RemoveDuplicates<Combine.Publishers.Map<Combine.Publishers.Print<Combine.AnyPublisher<Swift.Int, Swift.Never>>, Swift.Bool>>.(unknown context at $1074608c0).Inner<Combine.Subscribers.Sink<Swift.Bool, Swift.Never>>>>, __C.UIPageControl, Swift.Int>)
currentPagePublisher: request unlimited
currentPagePublisher: receive value: (0)
To Reproduce
Steps to reproduce the behavior:
currentPage
of the UIPageControl, the indicator view is updated but currentPagePublisher
emits nothingExpected behavior
currentPagePublisher
should emits current value
Device:
Describe the bug
tableView(_:viewForHeaderInSection:)
delegate method cannot be used when using tableView.didEndScrollingAnimationPublisher
.
To Reproduce
class MyViewController: UIViewController {
@IBOutlet private weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.didEndScrollingAnimationPublisher
.sink { print("didEndScrollingAnimation") }
}
}
extension MyViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
// return my header view
}
}
MyViewController
is configured as a delegate of tableView
in a storyboard.
Expected behavior
tableView(_:viewForHeaderInSection:)
is called
Device:
Additional context
RxCocoa supports this by calling tableView.rx.setDelegate(viewController)
.
button6.tapPublisher.sink { _ in
}.store(in: &store)
Button click not responding
Project does not build. There is a generated modulemap file inside .xcodeproj that references some static directory on freak4pc's mac.
Umbrella directory '/Users/freak4pc/Work/OSS/CombineCocoa/Sources/Runtime/include' not found warning creates 8 errors that indicates; Runtime framework classes are not found.
After fixing the reference inside modulemap file that mentions "umbrella "/Users/freak4pc/Work/OSS/CombineCocoa/Sources/Runtime/include", project builds successfully.
However I can't run carthage command successfully, it resets the path.
Steps to reproduce the behavior:
Expected behavior
Runtime framework headers can be found.
Could you guys please help?
Both classes invoke control.addTarget(self, action: #selector(handleEvent), for: event)
but forget to call control.removeTarget
in cancel
method leaving a reference to self
. Since the target is not retained, it is possible that it is not causing an issue though (it may be weak inside the control) but it would be preferable to be consistent and follow Apple recommendation "To stop the delivery of events, always call the removeTarget(_:action:for:) method."
Installation via
pod 'CombineCocoa'
-> instals old version 0.0.1
instead of 0.1.0
pod 'CombineCocoa', '~> 0.1.0'
-> fails
[!] CocoaPods could not find compatible versions for pod "CombineCocoa": In Podfile: CombineCocoa (~> 0.1.0)
Only way to install version 0.1.0
is
pod 'CombineCocoa', :git => 'https://github.com/CombineCommunity/CombineCocoa.git', :tag => '0.1.0'
Cocoapods version:1.8.4
Describe the bug
To Reproduce
Steps to reproduce the behavior:
Expected behavior
CombineCocoa builds and produces CombineCocoa.framework
What is happening
Following message appears during Carthage process
*** Skipped building CombineCocoa due to the error:
Dependency "CombineCocoa" has no shared framework schemes for any of the platforms: iOS
Device:
UICollctionView did not work as expected. When I use colltionView to listen to both didScollPublish and didSelectedItemPublisher, they will not work at the same time and the first declaration will not work.
Simple case is as follows:
// NotWork
collectionView.didScrollPublisher.sink { [weak self] _ in
OMPrint("didScroll NotWork!" )
}
.store(in: &cancellables)
// Work
collectionView. DidSelectItemPublisher. Sink {indexPath in
OMPrint("didSelectItem Work!" )
}
.store(in: &cancellables)
Have you considered adding a publisher for bar button item taps? Would be neat.
I’m happy to have a look at adding myself, just wanted to raise the issue to track.
Describe the bug
A clear and concise description of what the bug is.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
If applicable, add screenshots to help explain your problem.
Device:
Additional context
Add any other context about the problem here.
Issue created in response to #27
According to Apple Combine Subscriptions have to fulfill the contract between publishers and subscribers with backpressure management. This is discussed in the WWDC presentation https://developer.apple.com/videos/play/wwdc2019/722/
The UIControl Event publisher is missing handling of the subscriber's demand. This is so far simply ignored.
I would like to add the demand management
Describe the bug
I had 2 subscribers subscribed to didSelectItemPublisher
of collection view. One to open another controller, one to call api. But when I tapped on collection view cell, it just emited elements to the latest subscriber, ignored the previous one.
To Reproduce
Subscribe 2 subscribers to didSelectItemPublisher
of collection view and see what happens
Expected behavior
didSelectItemPublisher
emits to all its subscribers
Device:
Describe the bug
Key path value type 'ReferenceWritableKeyPath<UIButton, Void>' cannot be converted to contextual type 'KeyPath< UIButton, Void>'To Reproduce
var tappedSubject = CurrentValueSubject<Void,Never>({}())
var signUPTapped: AnyPublisher<Void, Never> {
tappedSubject.map {_ in
self.showAlert()
}
.eraseToAnyPublisher()
}
viewModel.tappedSubject
.assign(to: \.tapPublisher, on: signUpButton)
i get error when do this
I've added CombineCocoa as an SPM dependency to an app being developed in Xcode 12 that supports iOS 13+.
When I add "import CombineCocoa" to a table view cell, it is highlighted in red and says "Missing required module 'Runtime'"
Trying to add a publisher to UIImagePickerController
using a DelegateProxy
My code:
extension UIImagePickerController {
var didFinishPickingMedia: AnyPublisher<[UIImagePickerController.InfoKey: Any], Never> {
let didPickSelector =
#selector(UIImagePickerControllerDelegate.imagePickerController(_:didFinishPickingMediaWithInfo:))
return delegateProxy
.interceptSelectorPublisher(didPickSelector)
.map { $0[1] as! [UIImagePickerController.InfoKey: Any] }
.eraseToAnyPublisher()
}
var didCancel: AnyPublisher<Void, Never> {
let didCancelSelector = #selector(UIImagePickerControllerDelegate.imagePickerControllerDidCancel(_:))
return delegateProxy
.interceptSelectorPublisher(didCancelSelector)
.map { _ in () }
.eraseToAnyPublisher()
}
private var delegateProxy: UIImagePickerControllerDelegateProxy {
.createDelegateProxy(for: self)
}
}
private class UIImagePickerControllerDelegateProxy: DelegateProxy,
UIImagePickerControllerDelegate,
UINavigationControllerDelegate,
DelegateProxyType {
func setDelegate(to object: UIImagePickerController) {
object.delegate = self
}
}
Works well on devices but crashes when presenting the controller on a simulator with 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
.
Appears the UIScrollView.reachedBottomPublisher
offset is not working as expected.
Currently the threshold
is calculated by using max bracketing on offset of calculating the y to compare using visible height:
let threshold = max(offset, self.contentSize.height - visibleHeight)
However in order for this to work the publisher would have to be setup as:
collectionView
.reachedBottomPublisher(collectionView.contentSize.height - visibleHeight - offset)
.sink {
Which I don't believe is correct given when dynamically inserting content the content size will change.
Describe the bug
When using UIScrollViewDelegateProxy and UICollectionViewDelegateProxy, one is ignored
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
self.collectionView.didSelectItemPublisher.sink { _ in
print("not called")
}
.store(in: &self.cancellableSet)
self.collectionView.didEndDraggingPublisher.sink { _ in
print("called")
}
.store(in: &self.cancellableSet)
Describe the bug
simply referencing the willDisplayCellPublisher
will change the delegate of your collection view. This should only happen After subscription.
var willDisplayCellPublisher: AnyPublisher<(cell: UICollectionViewCell, indexPath: IndexPath), Never> {
let selector = #selector(UICollectionViewDelegate.collectionView(_:willDisplay:forItemAt:))
return delegateProxy.interceptSelectorPublisher(selector)
.map { ($0[1] as! UICollectionViewCell, $0[2] as! IndexPath) }
.eraseToAnyPublisher()
}
I'm trying to add some publishers to UISearchBarDelegate like this:
extension UISearchBar {
var searchBarSearchButtonClicked: AnyPublisher<UISearchBar, Never> {
let selector = #selector(UISearchBarDelegate.searchBarSearchButtonClicked(_:))
return delegateProxy
.interceptSelectorPublisher(selector)
.map { $0[1] as! UISearchBar }
.eraseToAnyPublisher()
}
private var delegateProxy: UISearchBarDelegateProxy {
.createDelegateProxy(for: self)
}
}
private class UISearchBarDelegateProxy: DelegateProxy, UISearchBarDelegate, DelegateProxyType {
func setDelegate(to object: UISearchBar) {
object.delegate = self
}
}
Sadly I am getting two compiler errors:
'interceptSelectorPublisher' is inaccessible due to 'internal' protection level
and
Cannot inherit from non-open class 'DelegateProxy' outside of its defining module
From Apple docs:
Starting in spring 2024, you must include the privacy manifest for any SDK listed below when you submit new apps in App Store Connect that include those SDKs, or when you submit an app update that adds one of the listed SDKs as part of the update. Signatures are also required in these cases where the listed SDKs are used as binary dependencies.
Could you please add a privacy manifest for this library?
if i set a subsriber for UITextfield's textPublisher,
and i changed the UITextfield's content by code like this:
textField.text = "some value"
that subscriber can't receive the output.
so, can i send a signal by myself?
something like this:
textField.textPublisher.send("some Value")
Describe the bug
I get an error while trying to upload a binary to Testflight
The app references non-public selectors in Payload/XXX.app/Frameworks/CombineCocoa.framework/CombineCocoa: handleEvent
To Reproduce
Steps to reproduce the behavior:
Expected behavior
No error when distributing
Device:
Have you considered adding a publisher for gesture recognisers? Would be neat.
I’m happy to have a look at adding myself, just wanted to raise the issue to track.
I have build error for this publishers:
/// Combine wrapper for `scrollViewWillBeginZooming(_:with:)`
var willBeginZoomingPublisher: AnyPublisher<UIView?, Never> {
let selector = #selector(UIScrollViewDelegate.scrollViewWillBeginZooming(_:with:))
return delegateProxy.interceptSelectorPublisher(selector)
.map { $0[1] as! UIView? } // ❌ Cannot downcast from 'Any' to a more optional type 'UIView?'
.eraseToAnyPublisher()
}
/// Combine wrapper for `scrollViewDidEndZooming(_:with:atScale:)`
var didEndZooming: AnyPublisher<(view: UIView?, scale: CGFloat), Never> {
let selector = #selector(UIScrollViewDelegate.scrollViewDidEndZooming(_:with:atScale:))
return delegateProxy.interceptSelectorPublisher(selector)
.map { ($0[1] as! UIView?, $0[2] as! CGFloat) } // ❌ Cannot downcast from 'Any' to a more optional type 'UIView?'
.eraseToAnyPublisher()
}
CombineCocoa 0.4.0
Xcode 12.4
Swift 5.3.2
I have two UITextView's that I am using textPublisher
on, to keep them in sync with each other.
import UIKit
import Combine
import CombineCocoa
class ViewController: UIViewController {
@IBOutlet var textView1: UITextView!
@IBOutlet var textView2: UITextView!
@Published var value: String? = ""
private var subscriptions = Set<AnyCancellable>()
override func viewDidLoad() {
super.viewDidLoad()
$value
.sink {
self.textView1.text = $0
self.textView2.text = $0
}
.store(in: &subscriptions)
textView1.textPublisher
.assign(to: \.value, on: self)
.store(in: &subscriptions)
textView2.textPublisher
.assign(to: \.value, on: self)
.store(in: &subscriptions)
}
}
It all works, until you type an emoji: then the app crashes.
2020-11-06 11:49:04.184903+0100 CombineCocoaTest[7757:188602] requesting caretRectForPosition: while the NSTextStorage has oustanding changes {0, 8}
2020-11-06 11:49:04.185022+0100 CombineCocoaTest[7757:188602] !!! _NSLayoutTreeLineFragmentRectForGlyphAtIndex invalid glyph index 7
2020-11-06 11:49:04.191460+0100 CombineCocoaTest[7757:188602] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[NSLayoutManager _fillLayoutHoleForCharacterRange:desiredNumberOfLines:isSoft:] *** attempted layout while textStorage is editing. It is not valid to cause the layoutManager to do layout while the textStorage is editing (ie the textStorage has been sent a beginEditing message without a matching endEditing.)'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff2043a126 __exceptionPreprocess + 242
1 libobjc.A.dylib 0x00007fff20177f78 objc_exception_throw + 48
2 CoreFoundation 0x00007fff2043a004 -[NSException initWithCoder:] + 0
3 UIFoundation 0x00007fff2398ba17 -[NSLayoutManager(NSPrivate) _fillLayoutHoleForCharacterRange:desiredNumberOfLines:isSoft:] + 587
4 UIFoundation 0x00007fff23993d19 _NSFastFillAllLayoutHolesForGlyphRange + 1594
5 UIFoundation 0x00007fff2399155c -[NSLayoutManager(NSPrivate) _rectArrayForRange:withinSelectionRange:rangeIsCharRange:singleRectOnly:fullLineRectsOnly:inTextContainer:rectCount:rangeWithinContainer:glyphsDrawOutsideLines:rectArray:rectArrayCapacity:] + 750
6 UIFoundation 0x00007fff2399456f -[NSLayoutManager(NSPrivate) _rectArrayForRange:withinSelectionRange:rangeIsCharRange:singleRectOnly:fullLineRectsOnly:inTextContainer:rectCount:rangeWithinContainer:glyphsDrawOutsideLines:] + 69
7 UIFoundation 0x00007fff239e3541 -[NSLayoutManager rectArrayForCharacterRange:withinSelectedCharacterRange:inTextContainer:rectCount:] + 35
8 UIKitCore 0x00007fff24a037e1 -[_UITextContainerView updateInsertionPointStateAndRestartTimer:] + 259
9 UIFoundation 0x00007fff2399920e -[NSLayoutManager(NSPrivate) _invalidateLayoutForExtendedCharacterRange:isSoft:invalidateUsage:] + 2247
10 UIKitCore 0x00007fff249f0121 -[UITextView setAttributedText:] + 1000
11 UIKitCore 0x00007fff249fa518 -[UITextView setText:] + 121
12 CombineCocoaTest 0x000000010435e863 $s16CombineCocoaTest20SearchViewControllerC11viewDidLoadyyFySSSgcfU_ + 387
13 CombineCocoaTest 0x000000010435ea71 $sSSSgIegg_AAIegn_TR + 33
14 Combine 0x00007fff4a6a7566 $s7Combine11SubscribersO4SinkC7receiveyAC6DemandVxF + 54
15 Combine 0x00007fff4a6a7c60 $s7Combine11SubscribersO4SinkCy_xq_GAA10SubscriberA2aGP7receiveyAC6DemandV5InputQzFTW + 16
16 Combine 0x00007fff4a6b185a $s7Combine16PublishedSubjectC7ConduitC5offeryyxF + 458
17 Combine 0x00007fff4a6b2627 $s7Combine16PublishedSubjectC4sendyyxFyAA11ConduitBaseCyxs5NeverOGXEfU_TA + 23
18 Combine 0x00007fff4a6e9df4 $s7Combine11ConduitListO7forEachyyyAA0B4BaseCyxq_GKXEKF + 196
19 Combine 0x00007fff4a6b13c8 $s7Combine16PublishedSubjectC4sendyyxF + 216
20 Combine 0x00007fff4a6d09ed $s7Combine9PublishedV18_enclosingInstance7wrapped7storagexqd___s24ReferenceWritableKeyPathCyqd__xGAHyqd__ACyxGGtcRld__CluisZTf4ngdgd_n + 221
21 Combine 0x00007fff4a6d02cb $s7Combine9PublishedV18_enclosingInstance7wrapped7storagexqd___s24ReferenceWritableKeyPathCyqd__xGAHyqd__ACyxGGtcRld__CluisZ + 27
22 CombineCocoaTest 0x000000010435d8e1 $s16CombineCocoaTest20SearchViewControllerC5valueSSSgvs + 145
23 CombineCocoaTest 0x000000010435d79a $s16CombineCocoaTest20SearchViewControllerC5valueSSSgvpACTk + 138
24 libswiftCore.dylib 0x00007fff2f222913 $ss26NonmutatingWritebackBufferCfD + 67
25 libswiftCore.dylib 0x00007fff2f421470 _swift_release_dealloc + 16
26 Combine 0x00007fff4a712737 $s7Combine11SubscribersO6AssignC7receiveyAC6DemandVq_F + 407
27 Combine 0x00007fff4a712a00 $s7Combine11SubscribersO6AssignCy_xq_GAA10SubscriberA2aGP7receiveyAC6DemandV5InputQzFTW + 16
28 Combine 0x00007fff4a72d7a5 $s7Combine10PublishersO11ConcatenateV5InnerC13suffixReceiveyAA11SubscribersO6DemandV6OutputQzF + 149
29 Combine 0x00007fff4a72d6ff $s7Combine10PublishersO11ConcatenateV5InnerC16SuffixSubscriberV7receiveyAA11SubscribersO6DemandV6OutputQzF + 15
30 Combine 0x00007fff4a72d981 $s7Combine10PublishersO11ConcatenateV5InnerC16SuffixSubscriberVy_xq__qd___GAA0F0A2aKP7receiveyAA11SubscribersO6DemandV5InputQzFTW + 17
31 Combine 0x00007fff4a735ce0 $s7Combine10PublishersO3MapV5Inner33_5A6CD15A64659A6248DAF677D4BB6188LLV7receiveyAA11SubscribersO6DemandV6OutputQzF + 144
32 Combine 0x00007fff4a735ce0 $s7Combine10PublishersO3MapV5Inner33_5A6CD15A64659A6248DAF677D4BB6188LLV7receiveyAA11SubscribersO6DemandV6OutputQzF + 144
33 Combine 0x00007fff4a6a8583 $s7Combine16AnySubscriberBoxC7receiveyAA11SubscribersO6DemandV5InputQzF + 35
34 Combine 0x00007fff4a6a9b32 $s7Combine13AnySubscriberV7receiveyAA11SubscribersO6DemandVxF + 18
35 CombineCocoaTest 0x0000000104376736 $s12CombineCocoa13DelegateProxyC26interceptSelectorPublishery0A003AnyG0VySayypGs5NeverOG10ObjectiveC0F0VFyAE0H10SubscriberVyAhJGcfU_yAHcfU_ + 70
36 CombineCocoaTest 0x000000010436ff6f $sSayypGIegg_AAytIegnr_TR + 15
37 CombineCocoaTest 0x00000001043762b1 $sSayypGIegg_AAytIegnr_TRTA + 17
38 CombineCocoaTest 0x000000010437601f $sSayypGytIegnr_AAIegg_TR + 63
39 CombineCocoaTest 0x0000000104375f78 $s12CombineCocoa13DelegateProxyC19interceptedSelector_9argumentsy10ObjectiveC0F0V_SayypGtF + 536
40 CombineCocoaTest 0x00000001043760e9 $s12CombineCocoa13DelegateProxyC19interceptedSelector_9argumentsy10ObjectiveC0F0V_SayypGtFTo + 105
41 CombineCocoaTest 0x00000001043790f3 -[ObjcDelegateProxy forwardInvocation:] + 115
42 CoreFoundation 0x00007fff2043e3f0 ___forwarding___ + 859
43 CoreFoundation 0x00007fff20440698 _CF_forwarding_prep_0 + 120
44 UIFoundation 0x00007fff23a13e16 -[NSTextStorage processEditing] + 316
45 UIFoundation 0x00007fff23a13a60 -[NSTextStorage endEditing] + 83
46 UIFoundation 0x00007fff23a13af9 -[NSTextStorage coordinateEditing:] + 53
47 UIKitCore 0x00007fff249d2071 -[UITextInputController _insertText:fromKeyboard:] + 395
48 UIKitCore 0x00007fff249d2cc8 -[UITextInputController insertText:] + 333
49 UIKitCore 0x00007fff249f58f5 -[UITextView insertText:] + 62
50 UIKitCore 0x00007fff24450cfe -[UIKeyboardImpl insertText:updateInputSource:] + 254
51 UIKitCore 0x00007fff2444a5c0 -[UIKeyboardImpl _performKeyboardOutput:shouldCheckDelegate:] + 1046
52 UIKitCore 0x00007fff2444a16a -[UIKeyboardImpl performKeyboardOutput:] + 25
53 UIKitCore 0x00007fff244491e7 __55-[UIKeyboardImpl handleKeyboardInput:executionContext:]_block_invoke_2 + 418
54 UIKitCore 0x00007fff2447bc3d -[UIKeyboardTaskEntry execute:] + 147
55 UIKitCore 0x00007fff2447a8d1 -[UIKeyboardTaskQueue continueExecutionOnMainThread] + 310
56 Foundation 0x00007fff2086f973 __NSThreadPerformPerform + 204
57 CoreFoundation 0x00007fff203a8845 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
58 CoreFoundation 0x00007fff203a873d __CFRunLoopDoSource0 + 180
59 CoreFoundation 0x00007fff203a7c1f __CFRunLoopDoSources0 + 248
60 CoreFoundation 0x00007fff203a23f7 __CFRunLoopRun + 878
61 CoreFoundation 0x00007fff203a1b9e CFRunLoopRunSpecific + 567
62 GraphicsServices 0x00007fff2b793db3 GSEventRunModal + 139
63 UIKitCore 0x00007fff2466d40f -[UIApplication _run] + 912
64 UIKitCore 0x00007fff24672320 UIApplicationMain + 101
65 libswiftUIKit.dylib 0x00007fff53c487b2 $s5UIKit17UIApplicationMainys5Int32VAD_SpySpys4Int8VGGSgSSSgAJtF + 98
66 CombineCocoaTest 0x000000010436026a $sSo21UIApplicationDelegateP5UIKitE4mainyyFZ + 122
67 CombineCocoaTest 0x00000001043601de $s16CombineCocoaTest11AppDelegateC5$mainyyFZ + 46
68 CombineCocoaTest 0x00000001043602b9 main + 41
69 libdyld.dylib 0x00007fff20257409 start + 1
70 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[NSLayoutManager _fillLayoutHoleForCharacterRange:desiredNumberOfLines:isSoft:] *** attempted layout while textStorage is editing. It is not valid to cause the layoutManager to do layout while the textStorage is editing (ie the textStorage has been sent a beginEditing message without a matching endEditing.)'
terminating with uncaught exception of type NSException
CoreSimulator 732.17 - Device: iPhone 12 Pro (F1EB105F-0A1A-4AB4-91C9-728A05B22C85) - Runtime: iOS 14.1 (18A8394) - DeviceType: iPhone 12 Pro
(lldb)
Describe the bug
The UICollectionView crashes internally when using the delegate publishers such as didSelectItemPublisher
and using UICollectionViewDiffableDataSource
as dataSource.
To Reproduce
UICollectionViewDiffableDataSource
as dataSource.didSelectItemPublisher
Expected behavior
Shouldn't crash
Device:
Additional context
Crash Log:
2021-08-04 11:21:52.800547+0100 App[6134:8095978] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
*** First throw call stack:
(
0 CoreFoundation 0x0000000113473fba __exceptionPreprocess + 242
1 libobjc.A.dylib 0x0000000112bc1ff5 objc_exception_throw + 48
2 CoreFoundation 0x00000001134f2523 _CFThrowFormattedException + 194
3 CoreFoundation 0x00000001134f0457 -[__NSArrayM insertObject:atIndex:].cold.2 + 0
4 CoreFoundation 0x000000011337114a -[__NSArrayM insertObject:atIndex:] + 1130
5 Runtime 0x000000010f64a5b8 unpackInvocation + 1410
6 Runtime 0x000000010f649fdd -[ObjcDelegateProxy forwardInvocation:] + 45
7 CoreFoundation 0x0000000113478259 ___forwarding___ + 825
8 CoreFoundation 0x000000011347a7a8 _CF_forwarding_prep_0 + 120
9 UIKitCore 0x000000012ddf07cd -[UICollectionView _notifyDidEndDisplayingCellIfNeeded:forIndexPath:] + 194
10 UIKitCore 0x000000012de07b5a -[UICollectionView _reuseCell:notifyDidEndDisplaying:] + 1471
11 UIKit 0x0000000150773878 -[UICollectionViewAccessibility _reuseCell:notifyDidEndDisplaying:] + 77
12 UIKitCore 0x000000012de17202 -[UICollectionView _updateAnimationDidStop:finished:context:] + 1838
13 UIKitCore 0x000000012de169e4 __102-[UICollectionView _updateWithItems:tentativelyForReordering:propertyAnimator:collectionViewAnimator:]_block_invoke.2110 + 77
14 libdispatch.dylib 0x0000000119698578 _dispatch_call_block_and_release + 12
15 libdispatch.dylib 0x000000011969974e _dispatch_client_callout + 8
16 libdispatch.dylib 0x00000001196a7b3f _dispatch_main_queue_callback_4CF + 1152
17 CoreFoundation 0x00000001133e18f8 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
18 CoreFoundation 0x00000001133dc169 __CFRunLoopRun + 2781
19 CoreFoundation 0x00000001133db1a7 CFRunLoopRunSpecific + 567
20 GraphicsServices 0x0000000122ed0d85 GSEventRunModal + 139
21 UIKitCore 0x000000012e7184df -[UIApplication _run] + 912
22 UIKitCore 0x000000012e71d39c UIApplicationMain + 101
23 libswiftUIKit.dylib 0x0000000118266f42 $s5UIKit17UIApplicationMainys5Int32VAD_SpySpys4Int8VGGSgSSSgAJtF + 98
24 App 0x000000010ef3c40a $sSo21UIApplicationDelegateP5UIKitE4mainyyFZ + 122
25 App 0x000000010ef3c37c $s4App11AppDelegateC5$mainyyFZ + 28
26 App 0x000000010ef3c4f9 main + 41
27 libdyld.dylib 0x0000000119727bbd start + 1
)
libc++abi: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
terminating with uncaught exception of type NSException
Since UITextView
doesn't subclass UIControl
I can't just do something like this
public extension UITextView {
/// A publisher emitting any text changes to a this text field.
var textPublisher: AnyPublisher<String?, Never> {
Publishers.ControlProperty(control: self, events: [.allEditingEvents, .valueChanged], keyPath: \.text)
.eraseToAnyPublisher()
}
}
So how would you add such a publisher?
It seems that a delegate proxy can only be used on one item of its kind at a time.
For example in this screen, there are two view controllers, both have a UISearchBar. The one in the main view controller works completely fine, but the one on the half-modal (that has focus) doesn't do anything, none of the new publishers (for example searchBar.textDidChangePublisher
) fire. Until I remove the delegate publishers from the other search bar, and then it works in the modal.
First of all, thanks for all of your hard work. I appreciate the additions to Combine in both the Cocoa and Ext packages. They have helped bridge the gap between RxSwift and Combine.
Describe the bug
To Reproduce
I have an issue with UITextView. If I have multiple subscriptions to the same textView textPublisher
, only the last subscription receives events. I have tested other controls, and they work as expected, so I believe this issue is specific to UITextView. I have a sample project that I could pass along; however, the issue is easy to reproduce.
Steps to reproduce the behavior:
textPublisher
Expected behavior
I expect both subscriptions to receive text input updates
Additional context
Example:
class ViewController: UIViewController {
private var disposables = Set<AnyCancellable>()
@IBOutlet var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
textView.textPublisher
.sink { text in
print("Subscription-1 \(text)")
}
.store(in: &disposables)
textView.textPublisher
.sink { text in
print("Subscription-2 \(text)")
}
.store(in: &disposables)
}
}
produces the following output:
Subscription-1 Optional("")
Subscription-2 Optional("")
Subscription-2 Optional("T")
Subscription-2 Optional("Th")
Subscription-2 Optional("Thi")
Subscription-2 Optional("This")
Subscription-2 Optional("This ")
Subscription-2 Optional("This i")
Subscription-2 Optional("This is")
Subscription-2 Optional("This is ")
Subscription-2 Optional("This is a")
Subscription-2 Optional("This is a ")
Subscription-2 Optional("This is a m")
Subscription-2 Optional("This is a me")
Subscription-2 Optional("This is a mes")
Subscription-2 Optional("This is a mess")
Subscription-2 Optional("This is a messa")
Subscription-2 Optional("This is a messag")
Subscription-2 Optional("This is a message")
Describe the bug
When we try to archive a project which has CombineCocoa as a dependency, the archive fails. The following error is generated.
Instance method 'subscribe(on:options:)' requires that 'DispatchQueue' conform to 'Scheduler'
To Reproduce
Steps to reproduce the behavior:
Expected behavior
The archive should be generated
Actual behavior
Getting the error
Instance method 'subscribe(on:options:)' requires that 'DispatchQueue' conform to 'Scheduler'
In ReactiveCocoa there is an ability to subscribe to object selector's trigger like
navigationController?.reactive
.trigger(for: #selector(UINavigationController.popViewController))
.producer.observe(on: UIScheduler()).startWithValues { ... }
I think this feature is very useful and it would be great if Combine had this ability too 🙏
Describe the bug
I have come across a strange behaviour, where the textPublisher will emit the same value twice, if there is a subscription to it, and at the end of the subscription when the keyboard is dismissed (if it has not been dismissed before the subscription occurred).
To Reproduce
Imagine a save method that starts its chain by subscribing to the textPublisher, sending the value to an API, and on completion popping the view controller that contained the text field. The chain in the save method will be triggered twice, once when the method is invoked, and once when the view controller is popped, as that will cause the text field to dismiss the keyboard and emit an event (not sure which exactly) stating that editing has ended on it. I believe that this is due to the fact that the textPublisher observers both .allEditingEvents and .valueChanged events.
Expected behavior
I would expect the textPublisher to only emit when the actual text has changed, not when editing has ended or anything similar.
Device:
What do you think about working on it together? I've got few ideas. What can I do?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.