I have play pdf file text-to-speech. I have a converted pdf to string page by page. Add all page string in NSMutableArray(EX:- 150 pages pdf , add first index - first page string ). How to get the first page string is over and speaking finish ?. And speak second page string ? I have searched in Google but I didn't find anything. Any help is appreciated.
You don't have to think about page unit.
You have to think about utterance.
Any amount of text you send to the speakUtterance method,
and AVSpeechSynthesizer finishes speaking,
the following delegate method called.
speechSynthesizer:(AVSpeechSynthesizer *)synthesizer
didFinishSpeechUtterance:(AVSpeechUtterance *)utterance;
So inside the delegate method, you have to call speakUtterance method again.
But in usual case, a few words or sentences(normally one sentence) will be sent to AVSpeechSynthesizer. == call speakUtterance
Then if speaking finishes, inside the delegate method, logic begins to start next sentence or word.
It's all I can tell you.
I have got an API I can’t impact on. API has a lot of methods with delegate callbacks like -getInfo, -apiDidGetInfo: . There are some limitations, you can only call these methods sequentially and delegate callback might not be called after request. Two methods never should be called at once. I want to convert this API to something like -getInfoWithCompletion: and use some kind of queue inside + some type of watchdog timer to finish current stalled task. How would you do that?
I used NSURLConnectionobject and called its method cancel sometimes.
Now I should replace NSURLConnection -> NSURLSession. NSURLSession operates with tasks which have cancel method too.
The problem is -[NSURLConnection cancel] just stop the handling of requests but if I use -[NSURLSessionTask cancel] it produces "cancelling error". So how to properly distinguish if cancel is called manually or if a real error is occurred?
I've found 3 solutions:
subclass task/session class
create a custom property via method swizzling in task/session class
the simplest but not very beautiful way - task has string property taskDescription and documentation says that developers are free to use it as they want.
Compare the error code to NSURLErrorCancelled. This error code is generated only when your code cancels the request.
How to write a completion handler for when the SCNAction ends? Or maybe just get notified when the action ends. Is is any way to know when the action ended? My last resort is to use custom delay(delay: Double, closure:()->()) function with delay set to actions execution time, but that seems rather fragile.
runAction(_:completionHandler) and runAction(_:forKey:completionHandler) accept closures. They're defined on the SCNActionable protocol, not SCNAction, so the documentation is easy to miss.
https://developer.apple.com/reference/scenekit/scnactionable/1524219-runaction
I am making an object that goes to download stuff for all of my view controllers. The object is singleton instance and has a callback method with received data once the download is completed. It also has a delegate property so that it knows which object to call back to after the download is done.
There are multiple controllers that use this shared instance, and my question is how to call back to the correct view controller that requested the download.
My approach is to use delegation, but the problem is that since other view controllers are also its delegate, the download object could call back to every object and this will be hard to track.
I've worked on projects where people have attempted to use multiple delegates and it's basically a bad idea. The delegate pattern is about a 1 to 1 relationship between a class and it's delegate. Whilst it is possible to achieve some level of multiple delegation through switching the delegates in and out, it's more likely to lead to unpredictable behaviour and bugs.
My recommendation would be to change how you are thinking about this. You have two options as I see it:
Switch to an Observer pattern where you can register multiple observers which your main class can interact with. This is useful where your observers all implement the same protocol and where your main class wants to be aware of the observers and interaction with them.
Broadcast NSNotifications to indicate state changes and events. Here is a more decoupled approach because the main class does not need to know who is listening and does not directly interact with them. Other can start and stop being notified at their leisure. It also has the advantage that you do not need to create or implement a separate protocol. Instead you register the classes that need to know about changes with the NSNotificationCenter which in turns handles all the routing of notifications for you.
It actually sounds like the delegate pattern might not be the best approach here.
I would look into NSNotificationCenter instead.
The basic idea is that your singleton doing the net connection posts a notification (with something like postNotificationName:object:userInfo:) , saying that new data is available. Within this notification, you can pass a dictionary object (userInfo) that holds the data you've fetched, or info on what parts of your Model contain updated data.
Then, your other view controllers can register themselves to 'observe' these notifications by calling addObserver:selector:name:object:. Generally speaking, when a vc becomes visible I call addObserver, and removeObserver when it's being hidden or transitioned out.
Good luck!
Delegation doesn't seem like the right solution to this problem. How about requiring the requesting view controller to provide an object (its self) and a selector for you to call as a completion notification? Of course, you'll need a place to store that object and selector until the download completes. Hopefully you have (or could create) an object for this.
i recommend to use one of these ways
observer:
when use data that you want to inform other object are near to primitive ones.for example when you are using 'NSMutableArray' you can not inform the change in one of object by the standard implemented pattern at least you need to implement one for your self that is not reusable that much
Notification
when your interaction with destination object (those need to be inform) is in one-way.it means you don't need any acknowledge or other data back from them.
delegate
when there is one object to inform at each time step.
note:block use for success and fail is not a pattern to broadcast data its about to queue task when you don't know when they are finishing or failing like network operations
EDIT:
how to create notification | multi delegate issues and implementation
While I agree with most of the answers here, if you did actually want to achieve multiple delegates you could potentially declare an array of delegates and send messages to all delegates within that array. If your protocol has optional delegate methods you safely check using responds(to aSelector: Selector!) -> Bool before invoking (being mindful of memory management, as those delegates would be strongly referenced in the array). Again I do agree that multiple delegates is likely a bad architectural idea and using blocks or notification center would suit your needs better.
One approach, which works for me if you only have one other object to forward messages to is to create a forwardingDelegate This does not end up with issues of hard to debug ordering of delegates and it does not unnecessarily create a dependency on the other object. Keep in mind, if you have many objects then this might not be the best approach, it is mainly for one additional object but this could be extended to support an array of objects so long as there is one that receives the SDK and forwards it to the other objects [1]. Note that every method that is needed for the forwarded object needs to pass it along, even if it is not used by the forwarding object.
For example, if I need to forward the messages coming from the mapView delegate:
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
// handle this object here.
if ([self.forwardingDelegate respondsToSelector:#selector(mapView:regionDidChangeAnimated:)])
{
[self.forwardingDelegate mapView:mapView regionDidChangeAnimated:animated];
}
// or handle this object here.
}
[self.forwardingDelegate mapView:mapView regionDidChangeAnimated:animated];
The forwarding property would be declared like this.
#property (nonatomic) id<MKMapViewDelegate> forwardingDelegate;
And the other object would adopt the protocol as if it were receiving the original message.
[1] The array approach for multiple delegates may get tricky because then you don't have as much control over what order the delegates get called, as was mentioned in other posts.