NewFiveFour | Blog | Portfolio


Linux: Use TLP to save three hours of laptop battery

Install Linux Advanced Power Management:

add-apt-repository ppa:linrunner/tlp
apt-get update
apt-get install tlp tlp-rdw
tlp start

That should save your about two or three hours.

Disabling your touch screen is done via xinput. I disabled my touchscreen and touchscreen pen whatever that is.

Issue xinput -list and then xinput disable 100, where 100 is the the ID you found in xinput. That saves very little normally, but may be worth a go.

unix

Swift 3 and iOS: Form data and multipart uploads with URLRequest

If you want to upload an image to a server, an image from the photo gallery or camera for example, you often use a multipart request.

First create a POST Request as normal, with with a boundary string created via a UUID request and the content type as multipart/form-data with the boundary string.

var r  = URLRequest(url: URL(string: "https://prospero.uatproxy.cdlis.co.uk/prospero/DocumentUpload.ajax")!)
r.httpMethod = "POST"
let boundary = "Boundary-\(UUID().uuidString)"
r.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

We must now create the http body. We use the below function, passing in parameters as a dictionary with strings, the boundary string we created, data from the UIImage, a mime-type and the filename for the image.

r.httpBody = createBody(parameters: params,
                        boundary: boundary,
                        data: UIImageJPEGRepresentation(chosenImage, 0.7)!,
                        mimeType: "image/jpg",
                        filename: "hello.jpg")

The createBody method first loops over the parameters dictionary, adding them to the body as a Content-Disposition with the boundary.

Finally, it adds the image as data, with the filename, the mime-type and with the boundary as before.

func createBody(parameters: [String: String],
                boundary: String,
                data: Data,
                mimeType: String,
                filename: String) -> Data {
    let body = NSMutableData()

    let boundaryPrefix = "--\(boundary)\r\n"

    for (key, value) in parameters {
        body.appendString(boundaryPrefix)
        body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
        body.appendString("\(value)\r\n")
    }

    body.appendString(boundaryPrefix)
    body.appendString("Content-Disposition: form-data; name=\"file\"; filename=\"\(filename)\"\r\n")
    body.appendString("Content-Type: \(mimeType)\r\n\r\n")
    body.append(data)
    body.appendString("\r\n")
    body.appendString("--".appending(boundary.appending("--")))

    return body as Data
}

The appendString doesn’t exist on a NSMutableData. It’s a helper extension as defined below:

extension NSMutableData {
    func appendString(_ string: String) {
        let data = string.data(using: String.Encoding.utf8, allowLossyConversion: false)
        append(data!)
    }
}

Now we have the URLRequest we can send it off as usual.

swift ios ios-urlrequest

Android: Style Toolbar/ActionBar and centre text

In recent support library updates, we have the Toolbar to use instead of the standard ActionBar to style via various properties in your style xml files.

You add this manually to your layout XML file.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  xmlns:tools="http://schemas.android.com/tools">
  <android.support.v7.widget.Toolbar
      android:id="@+id/toolbar"
      android:layout_alignParentTop="true"
      android:layout_width="match_parent"
      android:layout_height="?attr/actionBarSize"
      android:background="@color/toolbar_background"
      >
  ...

If you want to centre the title text, for example, you now just add a normal TextView and centre align it.

      <TextView
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:textColor="@color/toolbar_text"
          android:gravity="center"
          tools:text="Some title"
          android:id="@+id/toolbar_text"
          style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"/>

Obviously this is a lot to put at the top of every activity, you can instead place it in a separate layout file and use an include directive:

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <include android:id="@+id/toolbar_layout"
        layout="@layout/toolbar_layout" />
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/toolbar_layout">
...

In order to give this the title of your activity, you add this code in your onStart() method, or anywhere after the layout has been inflated:

TextView toolbarText = (TextView) findViewById(R.id.toolbar_text);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
if(toolbarText!=null && toolbar!=null) {
    toolbarText.setText(getTitle());
    setSupportActionBar(toolbar);
}

This will grab our toolbar, grab the text view which will hold our title, set the text on our text view and set the toolbar as our ActionBar.

Now when options menu etc, it will appear in that toolbar.

android android-toolbar

Swift 3 and iOS: Choose an image with UIImagePickerController

If you want to use an image from your iOS device, you’ll want to use this. First put Privacy - Photo Library Usage Description with a string description into your Info.plist file.

Next define let picker = UIImagePickerController() and in your viewDidLoad() set its delegate as picker.delegate = self.

You can start it using:

  picker.allowsEditing = false
  picker.sourceType = .photoLibrary
  self.present(picker, animated: true, completion: nil)

Since we’ve made our class the delegate, you need to make the class use these protocols: UIImagePickerControllerDelegate, UINavigationControllerDelegate.

And we define two methods, one that dismisses the popup and another that grabs our image:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage
    // use the image
    dismiss(animated: true, completion: nil)
}

func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    dismiss(animated: true, completion: nil)
}

If you want to use the camera instead of the photo album, change your initialisation code to:

picker.allowsEditing = false
picker.sourceType = .camera
picker.cameraCaptureMode = .photo
swift ios

Swift 3 and iOS: Save a file

Let’s say you already have a Data object filled with PDF data, or whatever.

We first get the url for our documents directory (in our user’s home domain). Then we append our filename to that.

Finally we write our data above to this new url atomically, marking it with try since it may throw an exception.

var docURL = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last
docURL = docURL?.appendingPathComponent("sample1.pdf")
try OURDATA.write(to: docURL!, options: .atomicWrite)
swift ios

Page 1 of 75
Next