Get CallerId (Username) from incoming call Linphone - Swift - swift

I've just found a simple way to get the some CallLogs (CallerID, Username, To, From, Call duration, Date, Status, ...) from the new Linphone library for swift (SDK 5.0).
I just want to share it with you

Referring to Linphone's documentation, and some testings, I found at least 2 simple ways to retrieve the CallLog and read it:
1. Using CoreDelegateStub
CoreDelegateStub( onCallStateChanged: { (core: Core, call: Call, state: Call.State, message: String) in
So, you can use the call attribute to get the CallerID(Username) for example, like that:
call.callLog?.fromAddress?.username
Remember, the callLog object contains a ton of parameters that you can find in the documentation
2. Using Core from Linphone wrapper
var mCore: Core!
self.mCore.callLogs
In that way, you can retrieve all your call logs in an array, so you will need to choose an item and get the attributes from it like I've shown above.
self.mCore.callLogs[0].fromAddress?.username

Related

v2.ODataModel: which API is more preferred? "bindElement" or "read"?

I set the view.setModel(model), get the model for the view, and request for model.read("/entitySet('10000')").
The model is then filled up with /entitySet('10000')/properties.
But it is difficult to assign them to view fields, as now in the view, <Text text="{property}"> doesn't work. It has to be <Text text="{/entitySet('10000')/property}">.
On the other hand, if I set view's context binding to "/entitySet('10000')", then <Text text="{property}"> would start working.
Which one is the preferred method? When to use .read?
I almost never use .read if I want to use the results from an OData call directly in a binding context. The only time I use .read is if I want to manipulate the results before doing anything with them.
Look at this example from the sdk for instance: https://ui5.sap.com/#/entity/sap.ui.table.Table/sample/sap.ui.table.sample.OData
Syntax on this kind of binding is similar to read but with a few differences in events, and a few different types of methods depending on what you want to bind. Binding to a view for instance uses bindElement:
this.getView().bindElement("/entitySet('1000')");
After this, fields on that particular entity can be accessed as <Text text="{property}" />.
Here's an example from one of my current apps with events and some other call parameters:
this.getView().bindElement({
path: `/Orders('${currentOrderNumber}')`,
parameters: {
expand: 'Texts'
},
events: {
dataRequested: _ => this.getView().setBusy(true),
dataReceived: data => {
if (!this.getView().getBindingContext()) {
// navigate to `Not Found` view
}
},
change: _ => this.getView().setBusy(false)
}
});
For a table, it's slightly different, since it depends on the aggregation you wish to bind, such as
oTable.bindRows({
path: "properties"
});
Which is the same as:
<Table rows="{properties}" />
It's always important to be more expressive. Use the API that is specifically designed to do that one task.
Comparing the two variants:
myModel.read(sPath) with text="{/path/property}"
myControl.bindElement(sPath) with text="{property}"
I'd be perplexed about the 1st call whereas in the 2nd call, I'd know exactly what you want to achieve (You want to bind element. Alternatively, bindObject can be also used).
The same applies to the framework. Since you're telling exactly what you want to achieve, the framework can improve its behavior based on your intent. E.g.: in (route)PatternMatched handler when the user navigates to the same page, .bindElement with the same path won't trigger another request since the model already stored the entity from the previous call. It can show the result immediately.
With .read, however, the framework doesn't know what you want to achieve, so it sends the request right away regardless of the application state.
Additionally, the 1st variant is anything but future-proof. It relies on the cached results. It's almost a side-effect that it works at all. The problem is that there is no guarantee that this behavior will continue to work in later versions. Also there won't be read method in V4 ODataModel.
TL;DR
v2.ODataModel#read
Does not create context from the response. Repeating .read("<same path>") always sends a new request.
Less expressive. Encourages app developers to work with a client-side model (e.g. JSONModel).
Application loses context awareness, increasing TCO, less future-proof.
bindElement or bindObject
Creates context from the response and stores it internally so that the same request can return the data immediately.
Clearly expresses the intent; application as well as framework can work with the existing APIs.
More future-proof: v4.ODataModel does not support manual read. Imagine you've built your applications with the v2ODataModel.read-jsonModel.setData approach, and you need to migrate to v4. Have fun. :)
I honestly think that v2.ODataModel#read should have never become a public method. I wouldn't encourage anyone to use .read except of when reading the $count value manually.
If the entity values need to be formatted, there are formatters and binding types out of the box which are also easy to extend.
If the application needs to restructure the response body, usually it's a sign of a poor design of the data model or the service not conforming to the OData spec.
I almost agree with Jorg, but not entirely:
It really depends on what are you trying to achieve. If looking to display data from backend then the easiest way to go is with this.getView().bindElement()
but if you are in need to manipulate data before displaying (like formatting text, displaying images from base64 strings, etc) OR if you would like to create new entity using some of existing data, OR update the existing data - the this.getModel(sName).read() is the way to go - as you can set read entity with all its deep entities to JSONModel in successCallback and manipulate it from the localModel.
If using localModel the dataBinding is pretty much the same in the view - except you have to additionally give model name to take data from. So for example, if in successCallback of your Model.read() you set your data to Model named "localModel":
this.getModel().read(sObjectPath, {
urlParameters: {
$expand: ""
},
success: function (oData) {
// "localModel" is name you gave in onInit function to your new JSONMOdel, when setting it to View e.g. this.getView().setModel(oJSONMOdel, "localModel")
this.getModel("localModel").setData(oData);
}
})
then in XML view you would indicate that
<Text text="{localModel>/mainPropertyName}"/>
// for displaying deep entities as List items or in Table
<List items="{localModel>/deepEntityName}">
<StandardListItem title="{localModel>propertyNamefromDeepEntity}" />
</List>
From my experience working with more complex apps that Read-Only - I always use Model.read().

How to use delta trigger in flink?

I want to use the deltatrigger in apache flink (flink 1.3) but I have some trouble with this code :
.trigger(DeltaTrigger.of(100, new DeltaFunction[uniqStruct] {
override def getDelta(oldFp: uniqStruct, newFp: uniqStruct): Double = newFp.time - oldFp.time
}, TypeInformation[uniqStruct]))
And I have this error:
error: object org.apache.flink.api.common.typeinfo.TypeInformation is not a value [ERROR] }, TypeInformation[uniqStruct]))
I don't understand why DeltaTrigger need TypeSerializer[T]
and I don't know what to do to remove this error.
Thanks a lot everyone.
I would read into this a bit https://ci.apache.org/projects/flink/flink-docs-release-1.2/dev/types_serialization.html sounds like you can create a serializer using typeInfo.createSerializer(config) on your type info. Note what you're passing in currently is a type itself and NOT the type info which is why you're getting the error you are.
You would need to do something more like
val uniqStructTypeInfo: TypeInformation[uniqStruct] = createTypeInformation[uniqStruct]
val uniqStrictTypeSerializer = typeInfo.createSerializer(config)
To quote the page above regarding the config param you need to pass to create serializer
The config parameter is of type ExecutionConfig and holds the
information about the program’s registered custom serializers. Where
ever possibly, try to pass the programs proper ExecutionConfig. You
can usually obtain it from DataStream or DataSet via calling
getExecutionConfig(). Inside functions (like MapFunction), you can get
it by making the function a Rich Function and calling
getRuntimeContext().getExecutionConfig().
DeltaTrigger needs a TypeSerializer because it uses Flink's managed state mechanism to store each element for later comparison with the next one (it just keeps one element, the last one, which is updated as new elements arrive).
You will find an example (in Java) here.
But if all you need is a window that triggers every 100msec, then it'll be easier to just use a TimeWindow, such as
input
.keyBy(<key selector>)
.timeWindow(Time.milliseconds(100)))
.apply(<window function>)
Updated:
To have hour-long windows that trigger every 100msec, you could use sliding windows. However, you would have 10 * 60 * 60 windows, and every event would be placed into each of these 36000 windows. So that's not a great idea.
If you use a GlobalWindow with a DeltaTrigger, then the window will be triggered only when events are more than 100msec apart, which isn't what you've said you want.
I suggest you look at ProcessFunction. It should be straightforward to get what you want that way.

Extbase Hooks - execute code upon record creation

I want to create a standard typo3 extension but when I create a record (or modify it) I want to calculate something (in my case I want to call the Google Map API to get coordinates from a given address).
SO I search for a hook or something. Any idea?
One of my project example, may helps you for hook in backend when record has been changed.
In your extension file ext_localconf.php
// Hook for cancellation
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass'][] = 'EXT:femanager/class.tx_femanager_tcemainprocdm.php:tx_femanager_tcemainprocdm';
hook file class.tx_femanager_tcemainprocdm.php where you can execute
your script
class tx_femanager_tcemainprocdm{
function processDatamap_postProcessFieldArray ($status, $table, $id, &$fieldArray, &$reference){
// $status also called action like delete
// $table - table name of excute backend action
// $id - record UID
// $fieldArray - fields of your table
if($table = 'your_extension_table_name'){
// your script
}
}
}
Maybe this answer is useful to you.
Register your class as a data handling hook in your extension. This one "is called AFTER all commands of the commandmap" were executed. Maybe you need to look for a more appropriate one.
Then in your registered Hook i.e. 'typo3conf/ext/your_ext/Classes/Hooks/AfterCreate.php' do your calculation. Hope this sets you on the right track.
In my special case there was no need to calculate the coordinates when the record got saved. So I just used the listAction in the controller, check if coordinates are there and if not call the Google API (and send an email if the Google API does not give a coordinate back).
In another case where the new record comes from a frontend plugin and I had to do something with this data I used the createAction in the Controller. (I am not sure if the createAction is also called when the record is created from the backend.)

Issue with using polymorphic_path with FactoryGirl build object

I am using factory_girl and rspec2 for my testing. I have an issue with the following code:
let(:book) { build(:book, id: 1) }
book_path(book)
book_path statement is generating /books url instead of /books/1. I can use create, but any suggestions on how to fix this using build strategy?
I am using
rspec-rails (2.11.0)
factory_girl (3.5.0)
Try book.to_param (that's actually what book_path(book) is doing under the hood) and see what it returns. By default to_param returns id, but your book is not saved yet, so it can return nil.

user_work_history with Flex and the ActionScript SDK

I'm working on a sample app for Facebook, using Flash Builder and Flex.
Now, I've got everything up and running - but there's one problem, specifically with the work history part.
When I try to display the user's work history..here's the code for logging in:
protected function login():void
{
FacebookDesktop.login(loginHandler, ["user_birthday", "user_work_history"]);
}
Here, loginHandler's a callback function, that then goes ahead and displays data about the user:
protected function loginHandler(success:Object,fail:Object):void
{
if (success){
currentState = "LoggedIn";
fname.text = success.user.name;
userImg.source=FacebookDesktop.getImageUrl(success.uid,"small");
birthdayLbl.text=success.user.birthday;
workLbl.text=success.user.work;
}
}
Now, the problem occurs with success.user.work - it ends up printing the following:
[object,Object],[object,Object],[object,Object],[object,Object]
Obviously, I'm doing something wrong..but I can't figure out what exactly it is. Would be grateful for some pointers!
Thanks!
Rudi.
The object contained in success.user.work is most likely an array of objects, each item representing a work period, so you'll have to treat it as such. Either use a list and a custom renderer for each item, or create a string by iterating over the array, and appending the fields that you're interested in.
To see what the individual objects contain, either use a breakpoint during debug and inspect them, or check to see if they're documented in the facebook development documentation.