I have that code
typealias escHandler = ( URLResponse?, Data? ) -> Void
func getRequest(url : URL, _ handler : #escaping escHandler){
let session = URLSession.shared
let task = session.dataTask(with: url){ (data,response,error) in
print("--")
handler(response,data)
}
task.resume()
}
I wanna get output from this call, but, for some reason the program just finish without output.
let x = "someURL"
let url = URL(string: x)!
getRequest(url: url){ response,data in
print("Handling")
}
That's my problem, can anyone help me?
The code is correct but if by any chance you are using a "http" URL and not a "https" url then you have to make the following change to the info.plist file
Add "App Transport Security Settings" -> Add "Allow Arbitrary Loads" and set it to "YES".
Refer the screenshot below
Related
I have an iOS/wOS app that launched last year. Now I want to add complications to it and use the new way of doing complications with WidgetKit. I have everything in place up to the point where I'm supposed to read the data from Health to display it, where it fails with Missing com.apple.developer.healthkit entitlement.
This is the new extension I've added
It's embedded in the WatchKit app NOT in the WatchKit Extension and I've added permission to read health data directly in the info.plist for the extension
I pull the data from the TimelineProvider protocol method
func getTimeline(in context: Context, completion: #escaping (Timeline<Entry>) -> ()) {
let currentDate = Date()
var entries: [WorkoutEntry] = []
ComplicationHealthManager.loadPreviousWorkouts { workout in
let workoutEntry = WorkoutEntry(date: currentDate, workout: workout)
entries.append(workoutEntry)
let timeline = Timeline(entries: entries, policy: .after(currentDate))
completion(timeline)
}
}
with the help of a small manager class
class ComplicationHealthManager: ObservableObject {
static func loadPreviousWorkouts(completion: #escaping (HKWorkout?) -> Void) {
let healthStore: HKHealthStore = HKHealthStore()
let workoutPredicate = HKQuery.predicateForWorkouts(with: .traditionalStrengthTraining)
let compound = NSCompoundPredicate(andPredicateWithSubpredicates:
[workoutPredicate])
let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierEndDate,
ascending: false)
let query = HKSampleQuery(
sampleType: .workoutType(),
predicate: compound,
limit: 0,
sortDescriptors: [sortDescriptor]) { (query, samples, error) in
guard
let samples = samples as? [HKWorkout],
error == nil
else {
completion(nil)
return
}
let calendar = Calendar.current
let todaysSamples = samples.filter{ calendar.isDateInToday($0.endDate) }.last
completion(todaysSamples)
}
healthStore.execute(query)
}
}
The issue is in the closure for the health query where it returns with no workouts but an error stating
Error Domain=com.apple.healthkit Code=4 "Missing com.apple.developer.healthkit entitlement." UserInfo={NSLocalizedDescription=Missing com.apple.developer.healthkit entitlement.}
The problem here is I don't understand where and how to add an entitlement for the complication extension or the WatchKit app, as none of them have the option for health. I have a health entitlements set for the iPhone app and the WatchKit Extension.
I found the problem to be that I had the old implementation of watchkit apps, with both a Watch app and a Watch extension. That was the problem. I went and used the migration from Xcode 14 to merge the Watch App and Extension into a new watch app and everything works now.
Please file a Feedback at feedback.apple.com for this.
You can manually add the HealthKit entitlement to the Code Signing Entitlements file (create a new one if there isn't one already) associated with the target
<key>com.apple.developer.healthkit</key>
<true/>
The documentation for https://docs.rs/reqwest/latest/reqwest/blocking/multipart/struct.Form.html shows this example to create a multipart::Form from a file.
let file = reqwest::blocking::multipart::Form::new().file("key", "/path/to/file")?;
let response = reqwest::blocking::Client::new()
.post("https:://test.com.br/send")
.multipart(file)
.send()
.unwrap();
But the function ".file" is only available on the blocking version of reqwest (reqwest::blocking::multipart::Form).
I've tested the blocking version, and i was able to send a form. But i can't find a way to do this using the async version (reqwest::multipart::Form).
Is there a alternative way to make this call using the async version?
If you want to post just a file using async, please check this answer. If you want to construct a multipart form, try to use reqwest::multipart::Part to construct a body, while wrap your file into a stream.
i m successfully update file with multipart with this code(you could change patch to post)
pub async fn update_form(&self, con: &Collection, id: &str, path: &str) -> String {
let url = [&self.url_struct(con), "/", id].concat();
let file = fs::read(path).unwrap();
let file_part = reqwest::multipart::Part::bytes(file)
.file_name("bg.jpg")
.mime_str("image/jpg")
.unwrap();
let form = reqwest::multipart::Form::new().part("img", file_part);
let client = reqwest::Client::new();
match client
.patch(url)
.headers(construct_headers_form())
.multipart(form)
.send()
.await
{
Ok(res) => res.text().await.unwrap_or("no message".to_string()),
Err(_) => "{\"error\":400}".to_string(),
}
}
Using gRPC bindings from https://github.com/gkkachi/firestore-grpc I was able to puzzle together something that is seemingly working but does not receive any content:
Creating the request:
let req = ListenRequest {
database: format!("projects/{}/databases/(default)", project_id),
labels: HashMap::new(),
target_change: Some(TargetChange::AddTarget(Target {
// "Rust" in hex: https://github.com/googleapis/python-firestore/issues/51
target_id: 0x52757374,
once: false,
target_type: Some(TargetType::Documents(DocumentsTarget {
documents: vec![users_collection],
})),
resume_type: None,
})),
};
Sending it:
let mut req = Request::new(stream::iter(vec![req]));
let metadata = req.metadata_mut();
metadata.insert(
"google-cloud-resource-prefix",
MetadataValue::from_str(&db).unwrap(),
);
println!("sending request");
let res = get_client(&token).await?.listen(req).await?;
let mut res = res.into_inner();
while let Some(msg) = res.next().await {
println!("getting response");
dbg!(msg);
}
(full code in this repo).
The request can be made but the stream does not contain any actual content. The only hint I get from the debug logs is
[2021-10-27T14:54:39Z DEBUG h2::codec::framed_write] send frame=GoAway { error_code: NO_ERROR, last_stream_id: StreamId(0) }
[2021-10-27T14:54:39Z DEBUG h2::proto::connection] Connection::poll; connection error error=GoAway(b"", NO_ERROR, Library)
Any idea what is missing?
The crucial thing I was missing as pointed out in the rust users forum was that the request stream was immediately ending which caused the connection to close. The send frame=GoAway was actually send by the client (facepalm).
To keep the connection open and receive responses we can keep the input stream pending: Request::new(stream::iter(vec![req]).chain(stream::pending())). There will be a better way to set things up and keep control over subsequent input requests but this is enough to fix the example.
I'm working with Beego's convenience methods for parsing request body values and have the following:
Router file:
apiNamespace := beego.NewNamespace("/api")
apiNamespace.Router("/sessions/google/new", &controllers.SessionsController{}, "get:GoogleNewSession")
beego.AddNamespace(apiNamespace)
Controller code:
func (c *SessionsController) URLMapping() {
c.Mapping("GoogleNewSession", c.GoogleNewSession)
}
func (c *SessionsController) GoogleNewSession() {
// Always serve JSON
defer func() {
c.ServeJson()
}()
// This is always blank
log.Printf("'Received %+v'", c.Ctx.Input.RequestBody)
c.Ctx.ResponseWriter.WriteHeader(200)
return
// truncated
}
Front end JS (super-agent):
request
.post('/sessions/google/new')
.use(prefix)
.send({ code: authCode })
.set('Accept', 'application/json')
.end(function(err, res){
console.log("******* request", res.request)
if (res.ok) {
var body = res.body;
console.log('yay got ' + JSON.stringify(res.body));
} else {
console.log("***** err", err);
console.log("***** not ok", res.text);
}
});
When the superagent request fires off, I can see in the logs that the path is getting correctly matched. However, the c.Ctx.Input.RequestBody is always empty.
I have tried using something else to fire the request such as Postman but to no avail. In GET requests I am able to retrieve query params correctly.
Any clues or suggestions to help fix or debug this issue?
You need to configure "copyrequestbody = true" in configuration file "conf/app.conf".
The default is false so the content is not copied to c.Ctx.Input.RequestBody.
The example is shown section "Retrieving data from request body" in the document. (http://beego.me/docs/mvc/controller/params.md)
I m using dispatch-nio library to make several Http request calls. But I cannot find an example how to handle callback responses through nio library.
And also I am unable to handle exceptions thrown by nio.Http call. Could anyone please post an example or an url where we can find some information of it.
So far I achieved:
val http = new nio.Http
withShutdown(http) {
val host = :/("http://example.org") /"api"
val withParams = host <<? Map(
"page" -> "1"
)
val future = http(withParams as_str)
while (!future.isSet) {
println("Waiting for results...")
Thread.sleep(15000)
}
future.apply()
}
}
How to set headers and onComplete? any example please
Thanks in advance.