in converting to swift 2 from 1.2 i'm getting an error, type of expression is ambiguous without more context.
var recordSettings = [
AVFormatIDKey: kAudioFormatLinearPCM,
AVSampleRateKey : 44100.0,
AVNumberOfChannelsKey: 1,
AVLinearPCMBitDepthKey : 32,
AVLinearPCMIsFloatKey : true
I have no idea what the problem is . I've tried casting to [String:AnyObject] but with no luck. any suggestions are appreciated.
The type inferencer is having trouble realizing that kAudioFormatLinearPCM is an alias for UInt32 and that that can be boxed in an NSNumber.
So help it:
var recordSettings:[String:AnyObject] = [
AVFormatIDKey: NSNumber(unsignedInt: kAudioFormatLinearPCM),
AVSampleRateKey : 44100.0,
AVNumberOfChannelsKey: 1,
AVLinearPCMBitDepthKey : 32,
AVLinearPCMIsFloatKey : true]
Related
I want to create a binding of the Plotly.js library to Fable.
I am looking at this js code
import React from 'react';
import Plot from 'react-plotly.js';
class App extends React.Component {
render() {
return (
<Plot
data={[
{
x: [1, 2, 3],
y: [2, 6, 3],
type: 'scatter',
mode: 'lines+points',
marker: {color: 'red'},
},
{type: 'bar', x: [1, 2, 3], y: [2, 5, 3]},
]}
layout={ {width: 320, height: 240, title: 'A Fancy Plot'} }
/>
);
}
}
and my (faulty) attempt of creating a simple test binding looks like this
open Fable.Core
open Fable.Core.JsInterop
open Browser.Types
open Fable.React
// module Props =
type Chart =
|X of int list
|Y of int List
|Type of string
type IProp =
| Data of obj list
let inline plot (props: IProp) : ReactElement =
ofImport "Plot" "react-plotly.js" props []
let myTrace = createObj [
"x" ==> [1,2,3]
"y" ==> [2,6,3]
"type" ==> "scatter"
"mode" ==> "lines"
]
let myData = Data [myTrace]
let testPlot = plot myData
But obviously it does not work. How do I get it to work? Also, what does {[...]} mean? I am new to Javascript, and as far as I know {...} denotes an object which must contain name value pairs, and [...] denotes an array. So {[...]} seems to denote an object with a single nameless member that is an array, but as far as I know, there are no objects with nameless members.
I have been able to reproduce the example you linked. Please note that I don't Plotly and that I went the empiric way and so things can probably be improved :)
I have created the code as I would probably have done it if I had to use it in my production app. So there is a bit more code than in your question because I don't use createObj.
If you don't like the typed DSL you can always simplify it, remove it and use createObj or anonymous record like I did for the marker property :)
You need to install both react-plotly.js plotly.js in your project.
open Fable.Core.JsInterop
open Fable.Core
open Fable.React
// Define props using DUs this helps create a typed version of the React props
// You can then transform a list of props into an object using `keyValueList`
[<RequireQualifiedAccess>]
type LayoutProps =
| Title of string
| Width of int
| Height of int
// GraphType is marked as a `StringEnum` this means
// the value will be replace at compile time with
// their string representation so:
// `Scatter` becomes `"scatter"`
// You can customise the output by using `[<CompiledName("MyCustomName")>]
[<RequireQualifiedAccess; StringEnum>]
type GraphType =
| Scatter
| Bar
[<RequireQualifiedAccess; StringEnum>]
type GraphMode =
| Lines
| Points
| Markers
| Text
| None
[<RequireQualifiedAccess>]
type DataProps =
| X of obj array
| Y of obj array
| Type of GraphType
| Marker of obj
// This is an helpers to generate the `flagList` waited by Plotly, if you don't like it you can just remove
// member and replace it with `| Mode of string` and so you have to pass the string by yourself
static member Mode (modes : GraphMode seq) : DataProps =
let flags =
modes
|> Seq.map unbox<string> // This is safe to do that because GraphMode is a StringEnum
|> String.concat "+"
unbox ("mode", flags)
[<RequireQualifiedAccess>]
type PlotProps =
| Nothing // Should have real props here is there exist more than Data and Layout
// Here notes that we are asking for an `Array` or Data
// Array being the type expected by the JavaScript library
// `DataProps seq` is our way to represents props
static member Data (dataList : (DataProps seq) array) : PlotProps =
let datas =
dataList
|> Array.map (fun v ->
keyValueList CaseRules.LowerFirst v // Transform the list of props into a JavaScript object
)
unbox ("data", datas)
static member Layout (props : LayoutProps seq) : PlotProps =
unbox ("layout", keyValueList CaseRules.LowerFirst props)
// All the example I saw from react-plotly was using this factory function to transform the plotly library into a React component
// Even, the example you shown if you look at the Babel tab in the live example
let createPlotlyComponent (plotly : obj) = import "default" "react-plotly.js/factory"
// Immport the plotly.js library
let plotlyLib : obj = import "default" "plotly.js"
// Apply the factory on the plotly library
let Plot : obj = createPlotlyComponent plotlyLib
// Helper function to instantiate the react components
// This is really low level, in general we use `ofImport` like you did but if I use `ofImport` then I got a React error
let inline renderPlot (plot : obj) (props : PlotProps list) =
ReactBindings.React.createElement(plot, (keyValueList CaseRules.LowerFirst props), [])
let root =
// Here we can render the plot using our Typed DSL
renderPlot
Plot
[
PlotProps.Data
[|
[
DataProps.X [| 1; 2; 3 |]
DataProps.Y [| 2; 6; 3 |]
DataProps.Type GraphType.Scatter
DataProps.Mode
[
GraphMode.Lines
GraphMode.Points
]
DataProps.Marker {| color = "red" |}
]
[
DataProps.Type GraphType.Bar
DataProps.X [| 1; 2; 3 |]
DataProps.Y [| 2; 5; 3 |]
]
|]
PlotProps.Layout
[
LayoutProps.Width 640
LayoutProps.Height 480
LayoutProps.Title "A Fancy Plot"
]
]
I'm a bit late to the party here, but wanted to give you a different option if you're still looking to use plotly.js with Fable.
I've been working on bindings for plotly.js for the past month or so, and it's in a pretty usable state as of now. That being said, I wouldn't say it's production ready.
This is what the example you want to convert would look like written with Feliz.Plotly:
open Feliz
open Feliz.Plotly
let chart () =
Plotly.plot [
plot.traces [
traces.scatter [
scatter.x [ 1; 2; 3 ]
scatter.y [ 2; 6; 3 ]
scatter.mode [
scatter.mode.lines
scatter.mode.markers
]
scatter.marker [
marker.color color.red
]
]
traces.bar [
bar.x [ 1; 2; 3 ]
bar.y [ 2; 5; 3 ]
]
]
plot.layout [
layout.width 320
layout.height 240
layout.title [
title.text "A Fancy Plot"
]
]
]
You can find more information out here.
let nameAttributes = [NSFontAttributeName:nameFont, kCTForegroundColorAttributeName:UIColor.whiteColor().CGColor] as [String:AnyObject]
var nameAttributedString = NSMutableAttributedString(string:name, attributes:nameAttributes)
I have these values which are working on Swift 1.2. But on Swift 2, they don't work.
I receive an error on first line:
'_' is not convertible to 'CFString'
And the problem is kCTForegroundColorAttributeName. Without kCTForegroundColorAttributeName, it would works. But I need it to change the color..
In addition:
kCTForegroundColorAttributeName:UIColor.whiteColor().colorWithAlphaComponent(0.7).CGColor
gives me an error:
'_' is not convertible to 'CGFloat'
In Swift 2, attributes on NSMutableAttributedString has to be [String:AnyObject] while in Swift 1.2 was [NSObject:AnyObject].
Any ideas ?
Why not just use NSForegroundColorAttributeName?
Use this Code
let attrs2 = [NSFontAttributeName : FontWithBook(10),NSForegroundColorAttributeName :UIColor.grayColor()]
var gString = NSMutableAttributedString(string:"(Mandatory)", attributes:attrs2)
I haven't found a solution with data set up quite like mine...
var marketshare = [
{"store": "store1", "share": "5.3%", "q1count": 2, "q2count": 4, "q3count": 0},
{"store": "store2","share": "1.9%", "q1count": 5, "q2count": 10, "q3count": 0},
{"store": "store3", "share": "2.5%", "q1count": 3, "q2count": 6, "q3count": 0}
];
Code so far, returning undefined...
var minDataPoint = d3.min( d3.values(marketshare.q1count) ); //Expecting 2 from store 1
var maxDataPoint = d3.max( d3.values(marketshare.q2count) ); //Expecting 10 from store 2
I'm a little overwhelmed by d3.keys, d3.values, d3.maps, converting to array, etc. Any explanations or nudges would be appreciated.
I think you're looking for something like this instead:
d3.min(marketshare, function(d){ return d.q1count; }) // => 2.
You can pass an accessor function as the second argument to d3.min/d3.max.
Apparently I'm the only one to attempt this, as none of my Google searches turned up anything helpful. Assume I'm initializing an attribute array like this:
let glPFAttributes = [
NSOpenGLPFAAccelerated,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAColorSize, 48,
NSOpenGLPFAAlphaSize, 16,
NSOpenGLPFAMultisample,
NSOpenGLPFASampleBuffers, 1,
NSOpenGLPFASamples, 4,
NSOpenGLPFAMinimumPolicy,
0
]
These things are all regular Ints, I've checked. Now if I do
let glPixelFormat = NSOpenGLPixelFormat(attributes: glPFAttributes)
the compiler gives me this error message:
'Int' is not identical to 'NSOpenGLPixelFormatAttribute'
If I made a mistake somewhere, I'm not seeing it.
NSOpenGLPixelFormatAttribute is typeAlias of UInt32. NSOpenGLPixelFormat intializer takes array of NSOpenGLPixelFormatAttribute so you need to make array and convert all Int to UInt32.Below code will work
let glPFAttributes:[NSOpenGLPixelFormatAttribute] = [
UInt32(NSOpenGLPFAAccelerated),
UInt32(NSOpenGLPFADoubleBuffer),
UInt32(NSOpenGLPFAColorSize), UInt32(48),
UInt32(NSOpenGLPFAAlphaSize), UInt32(16),
UInt32(NSOpenGLPFAMultisample),
UInt32(NSOpenGLPFASampleBuffers), UInt32(1),
UInt32(NSOpenGLPFASamples), UInt32(4),
UInt32(NSOpenGLPFAMinimumPolicy),
UInt32(0)
]
let glPixelFormat = NSOpenGLPixelFormat(attributes: glPFAttributes)
Here is the simplified JSON file, I need to download it from a net service and parse results in a table!
EDIT: I provide now more precise code, cleaned and formatted by online tool:
{
"main": [
{
"id": 0, <--- float value
"type": "type0", <--- STRING value
"valueA": {
"valueA1": 1, <--- float value
"valueA2": 2, <--- float value
"valueA3": 3 <--- float value
},
"valueB": {
"valueB1": 1, <--- float value
"valueB2": 2 <--- float value
},
"valueC": [
{
"valueC1": "string0C1", <--- STRING value
"valueC2": 2, <--- float value
"valueC3": 3, <--- float value
}
]
},
FORMATTED by online tool jsonviewer.stack.hu:
I need to parse it with AFJSONRequestOperation, and I write this code:
NSMutableArray *main = [JSON objectForKey:#"main"];
arrayID = [main valueForKey:#"id"];
arrayType = [main valueForKey:#"type"];
NSMutableArray *arrayValueC = [main valueForKey:#"valueC"];
NSMutableString *stringC1 = [arrayValueC valueForKey:#"valueC1"];
// I CANT USE objectForKey, XCode give an exception -[__NSArrayI objectForKey:]: unrecognized selector sent to instance
NSLog(#"id: %#",arrayID);
NSLog(#"type: %#",arrayType);
NSLog(#"string: %#",stringC1);
When I parse, I get this results from NSLog:
id: (
0,
1,
2,
3,
4,
5,
6,
7,
8,
9
)
type: (
type0,
type1,
type2,
type3,
type4,
type5,
type6,
type7,
type8,
type9
)
string: (
(
"string0C1"
),
(
"string2C1"
),
(
"string2C1"
),
(
"string3C1"
),
(
"string4C1"
),
(
"string5C1"
),
(
"string6C1"
),
(
"string7C1"
),
(
"string8C1"
),
(
"string9C1"
)
)
As u can see its all perfect, I can extrapolate every value of ID (float) and TYPE (string), but I hate the round brackets in every object of the valueC1 string: how can I get the clean valueC1 without brackets and quotation marks? Please if u can provide some code. Thanks!
Don't use valueForKey:. Use objectForKey: instead. This is probably the major problem. But once you use it, you might run into new problem:
The following contains a problem that will manifest itself when arrayValueA is accessed the first time:
NSMutableArray *arrayValueA = [arrayMain objectForKey:#"valueA"];
The element stored at valueA is an object i.e. a dictionary and not an array.
Finally, your simplified JSON is invalid anyway. Several values are missing double quotes, e.g.:
"id": id0
should be:
"id": "id0"
You better shows the real JSON data and the real code.
Update:
You should be able to access the JSON data with the following code:
NSArray *main = [JSON objectForKey:#"main"];
NSDictionary* main0 = [main objectAtIndex:0];
arrayID = [main0 objectForKey:#"id"];
arrayType = [main0 objectForKey:#"type"];
NSArray *arrayValueC = [main objectForKey:#"valueC"];
NSDictionary *elem0 = [arrayValueC objectAtIndex:0];
NSString *stringC1 = [arrayValueC objectForKey:#"valueC1"];
NSLog(#"id: %#",arrayID);
NSLog(#"type: %#",arrayType);
NSLog(#"string: %#",stringC1);